0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

strongerHuang 来源:Mculover666 作者:mculover666 2021-11-05 14:20 次阅读

1. 说明

在工作过程中,我发现在实际使用RTOS完成项目时,理解这些知识仅能达到会用RTOS的水平,要想用好RTOS,还需要了解一些比较细节的机制,否则容易掉坑进去,花大量时间定位问题。

本文结合TencentOS-Tiny实时操作系统给大家讲述一下相关内容。

2. 任务的通常写法

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

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

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

while(1){
//1.waitsomekernelobject...
//eg.tos_sem_pend,tos_mutex_pend,tos_event_pend.

//2.waitsuccess,handle!
}
}

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

② 定时执行

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

while(1){
//1.dosomething...

//2.sleep!
//eg.tos_task_delay,tos_sleep_ms.
}
}

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

3. 一次性任务

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

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

//dosomething...

//exit?
}

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

4. 寻找答案

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

6cdb8e6e-3dfd-11ec-82a9-dac502259ad0.png

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

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

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

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

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

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

6d302d48-3dfd-11ec-82a9-dac502259ad0.png

从代码里可以看到,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__voidtask_exit(void)
{
tos_task_destroy(K_NULL);
}

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

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

6. 总结

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

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

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

编辑:jq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    5025

    浏览量

    117707
  • API
    API
    +关注

    关注

    2

    文章

    1380

    浏览量

    60984
  • 函数
    +关注

    关注

    3

    文章

    3864

    浏览量

    61307
  • RTOS
    +关注

    关注

    20

    文章

    775

    浏览量

    118781

原文标题:RTOS 任务入口函数执行完之后去哪里了?

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    RTOS内功修炼记(一)— 任务到底应该怎么写?

    本篇文章讲述了任务的三大元素:任务控制块、任务栈、任务入口函数,并讲述了编写
    的头像 发表于 12-01 16:36 341次阅读
    <b class='flag-5'>RTOS</b>内功修炼记(一)— <b class='flag-5'>任务</b>到底应该怎么写?

    reset_primary函数执行流程

    从核 , 待所有CPU核都启动完成之后 ,OP-TEE会触发安全监控模式调用(smc), 通知系统OP-TEE启动已完成并将CPU的状态切换回到正常世界状态 ,该函数执行流程如图所示。 reset
    的头像 发表于 11-02 18:06 292次阅读
    reset_primary<b class='flag-5'>函数</b>的<b class='flag-5'>执行</b>流程

    RTOS相比裸机有什么优点?RTOS相比裸机更方便吗?

    理实时任务。在本文中,我们将探讨使用RTOS而不是裸金属系统的优点,以及它是否更方便。 RTOS相对于裸机系统的优势 1.多任务处理 RTOS
    的头像 发表于 10-29 16:33 1000次阅读

    移植uC/OSIII之后,多任务并发执行,每个任务都只执行了一次,就不执行

    多个任务按照优先级执行一次后就停止,具体什么原因呢,各位大佬帮帮忙
    发表于 10-08 21:48

    51单片机多任务执行例子

    51单片机多任务同时执行。RTX51 tiny是一种实时操作系统(RTOS),可以用它来建立多个任务函数)同时
    发表于 08-04 15:59 0次下载

    51单片机多任务同时执行

    51单片机多任务同时执行。RTX51 Tiny是一种实时操作系统(RTOS),可以用它来建立多个任务函数)同时
    发表于 08-03 16:58

    FreeRTOS任务通知通用发送函数

    发送任务通知 任务通知通用发送函数 任务任务通知发送函数:xTaskNotify()、xTas
    的头像 发表于 07-30 11:43 502次阅读
    FreeRTOS<b class='flag-5'>任务</b>通知通用发送<b class='flag-5'>函数</b>

    空闲任务钩子函数详解

    空闲任务钩子函数详解 1、钩子函数 FreeRTOS中有多个钩子函数,钩子函数类似回调函数,当某
    的头像 发表于 07-30 10:57 609次阅读
    空闲<b class='flag-5'>任务</b>钩子<b class='flag-5'>函数</b>详解

    FreeRTOS中其他任务API函数

    1、函数 uxTaskPriorityGet() 此函数用来获取指定任务的优先级,要使用此函数的话宏 INCLUDE_uxTaskPriorityGet 应 该定义为 1。 2、
    的头像 发表于 07-06 16:54 668次阅读

    RTOS任务间通信为什么不用全局变量?

    RTOS任务间通信为什么不用全局变量?原因在于使用全局变量存在诸多弊端。
    发表于 07-05 09:06 421次阅读

    main函数不一定就是程序入口

    我们都知道,main函数是C程序的入口,那这个入口能不能修改?
    发表于 06-15 17:09 319次阅读

    RTOS中的任务是线程?进程?还是协程?

    今天为大家讲解讲解OS中的线程、进程和协程的这几个概念,同时一起看看RTOS中的任务到底属于哪一种。
    的头像 发表于 06-04 17:19 1226次阅读
    <b class='flag-5'>RTOS</b>中的<b class='flag-5'>任务</b>是线程?进程?还是协程?

    Verilog任务函数的区别

    函数一样,任务(task)可以用来描述共同的代码段,并在模块内任意位置被调用,让代码更加的直观易读。
    的头像 发表于 06-01 16:38 1015次阅读
    Verilog<b class='flag-5'>任务</b>与<b class='flag-5'>函数</b>的区别

    CMSIS RTOS任务管理

    RTOS
    橙群微电子
    发布于 :2023年05月29日 10:06:26

    嵌入式RTOS任务栈 和 系统栈

    简介明了带你了解嵌入式RTOS任务栈 和 系统栈
    的头像 发表于 05-16 09:57 2050次阅读
    嵌入式<b class='flag-5'>RTOS</b>的 <b class='flag-5'>任务</b>栈 和 系统栈