良许Linux教程网 干货合集 RTOS 任务入口函数执行完之后去哪里了?

RTOS 任务入口函数执行完之后去哪里了?

1. 说明

在我的工作经验中,我发现只是会使用实时操作系统(RTOS)还不足以真正掌握它的运用。要想充分利用RTOS,还需要了解一些比较细节的机制,否则可能会遇到一些问题,并花费大量的时间来定位和解决。

为了帮助大家更好地理解RTOS,本文将结合TencentOS-Tiny实时操作系统,向大家介绍相关的知识。

2. 任务的通常写法

遵循“不使用就让出”的原则,任务通常有两种写法。

「阻塞等待」某个事件处理,等待到之后处理:

void task1_entry(void *arg)
{
 // init...

 while (1) {
  // 1. wait some kernel object...
  // eg. tos_sem_pend, tos_mutex_pend, tos_event_pend.
   
  //  2. wait success, handle!
 }
}

这种写法中,在没有事件发生的时候,任务会因为等待某个内核对象而被挂起,让出CPU不参与调度。

② 定时执行

void task1_entry(void *arg)
{
 // init...

 while (1) {
  // 1. do some thing...
  
  //  2. sleep!
  // eg. tos_task_delay, tos_sleep_ms.
 }
}

这种写法中,任务在干完活之后,会主动进入睡眠状态,让出CPU不参与调度。

3. 一次性任务

上面两种写法的共性是都有主循环,不需要考虑任务入口函数退出的情况,但在一些场景中任务只需要执行一次即可:

void task1_entry(void *arg)
{
 // init...

 // do some thing...

 // exit?
}

「这个时候就要思考一个问题:任务入口函数执行完毕之后去了哪里?」

4. 寻找答案

首先,「任务入口函数本质上是一个函数」,跳转函数的指令是BL,CPU在执行该指令跳转到某个函数执行时,会将当前PC地址作为函数返回地址、加载到LR寄存器中、保证函数执行完可以返回到这儿继续执行,再将函数地址加载到PC寄存器、程序接着执行就到了函数中。image-20231115222203763

那么,任务入口函数没有被别的函数主动调用,是如何被拉起来执行的呢?

任务切换分为两步:保存上文、切换下文。切换下文就是指将保存在任务栈中的CPU寄存器组的值、加载到CPU中。

「所以,当任务栈中初始保存的CPU寄存器组的值中、PC寄存器值为该任务的任务入口函数地址时,切换下文加载之后,由于PC指向任务入口函数,所以CPU接着运行就到了任务入口函数中,也就是该任务在运行。」

同样的道理,「任务栈中初始保存的CPU寄存器组的值中、LR寄存器的值决定了、任务入口函数退出时候返回到哪里。」

由于不同CPU架构的CPU寄存器组不同,所以初始化任务栈的代码与架构强相关,在arch目录下都有不同架构对应的实现。

这里我们以ARM Cortex-M4为例(Arm-v7m)看看代码如何实现:

image-20231115222209427
image-20231115222209427

从代码里可以看到,TencentOS-Tiny默认退出函数为exit参数指定的值,接下来我们看看退出函数~

5. 任务退出函数

在创建任务的API tos_task_create 中,初始化任务栈的过程中会指定退出函数为 task_exit

task->sp = cpu_task_stk_init((void *)entry, arg, (void *)task_exit, stk_base, stk_size);

task_exit 函数主要完成销毁自身的工作,具体实现如下:

__STATIC__ void task_exit(void)
{
    tos_task_destroy(K_NULL);
}

该销毁函数传入的参数为NULL表示销毁自身,如果是静态任务则按以下步骤销毁(动态任务销毁值得用一篇文章去讲述):

  • 将任务从就绪列表移除
  • 将任务从等待列表移除
  • 将任务从统计列表移除
  • 任务状态置为K_TASK_STATE_DELETED

6. 总结

本文讲述了任务的两种常规写法,以及任务函数执行完毕之后去了哪里?

当任务函数执行完毕退出时,会执行到哪里由任务栈初始化时LR寄存器的值决定,RTOS内核都会提供一个默认退出函数,TencentOS-Tiny提供的任务退出函数中,会自动销毁任务自身。

所以在编写一次性任务时,就不需要主动调用销毁API销毁自身啦~

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部