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

    关注

    31

    文章

    5588

    浏览量

    129043
  • API
    API
    +关注

    关注

    2

    文章

    2146

    浏览量

    66205
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66819
  • RTOS
    +关注

    关注

    25

    文章

    862

    浏览量

    122580

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    FreeRTOS 空闲任务

    几乎所有的小型 RTOS 中都会有一个空闲任务,空闲任务属于系统任务,是必须要执行的,用户程序不能将其关闭。不光小型系统中有空闲
    发表于 12-04 07:35

    RTOS 必学概念:任务、信号量、队列一次搞懂

    如果你刚接触RTOS(实时操作系统),很可能会有这样的困惑:“RTOS和裸机程序到底有什么区别?”“任务是线程吗?为什么要分任务?”“信号量和互斥锁有什么区别,不都是同步手段吗?”“队
    的头像 发表于 11-17 10:53 174次阅读
    <b class='flag-5'>RTOS</b> 必学概念:<b class='flag-5'>任务</b>、信号量、队列一次搞懂

    Task任务:LuatOS实现“任务级并发”的核心引擎

    Task任务通过其强大的并发处理能力,使LuatOS能够在单线程环境中模拟多线程执行,通过协程的挂起与恢复机制,实现任务级的并行操作,显著提升系统效能。 sys核心库是LuatOS运行框架库,也是
    的头像 发表于 08-28 13:49 332次阅读
    Task<b class='flag-5'>任务</b>:LuatOS实现“<b class='flag-5'>任务</b>级并发”的核心引擎

    揭秘LuatOS Task:多任务管理的“智能中枢”

    ,也是LuatOS应用程序运行的核心大脑——所有LuatOS应用项目都会使用到sys核心库。    sys核心库提供四大类功能: Task任务 Message消息 Timer定时器 Run调度器 本文将
    的头像 发表于 08-28 13:48 391次阅读
    <b class='flag-5'>揭秘</b>LuatOS Task:多<b class='flag-5'>任务</b>管理的“智能中枢”

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数main
    的头像 发表于 07-25 15:34 1659次阅读

    【RA4L1-SENSOR】05 按键实现RTOS任务切换

    与计数功能的切换,为之后的多任务切换做个铺垫。 2. 软件部分 将上次的实验工程复制一份,重命名为05_Button_Switch_Task 2.1 绑定按键IO &&
    发表于 06-16 22:38

    揭秘LuatOS:实时操作系统RTOS核心库的关键技术剖析!

    电机控制、传感器采集等实时数据处理场景。 在LuatOS开发中, 用于实时操作系统(RTOS)相关功能的核心库 ——提供定时器管理、系统控制、内存监控、路径配置等底层操作接口,为物联网设备提供可靠的实时系统基础支撑。   本文以A
    的头像 发表于 05-21 16:02 510次阅读
    <b class='flag-5'>揭秘</b>LuatOS:实时操作系统<b class='flag-5'>RTOS</b>核心库的关键技术剖析!

    如何在Eclipse ThreadX RTOS中集成SystemView

    可以基于Systemview记录ThreadX操作系统事件并执行分析。我们基于SEGGER Embedded Studio开发环境描述如何在Eclipse ThreadX RTOS中集成SystemView。
    的头像 发表于 05-06 17:11 1169次阅读

    详解RTOS中的Hook函数

    Hook函数RTOS中的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 821次阅读

    stm32cubemax为什么下载之后无法运行?

    我本来想上传代码的,完全完全无法理解为什么下载之后无法运行
    发表于 03-12 06:06

    RTOS中的本地存储指针使用

    本地存储指针是RTOS中的一个重要特性,增强了任务管理和数据处理能力。在RTOS上下文中,本地存储是指存储在本地的特定任务或对象的数据。通常与任务
    的头像 发表于 02-28 16:33 1165次阅读
    <b class='flag-5'>RTOS</b>中的本地存储指针使用

    谷歌AI智能体执行复杂任务能力大幅提升

    自然语言描述任务,随后由AI智能体代替用户执行并最终完成任务,极大地提升工作效率和便捷性。 为了推进这一技术的实现,谷歌正在积极开发两个相关项目。其中备受瞩目的是名为“Mariner”的浏览器扩展程序。通过该程序,AI智能体能够
    的头像 发表于 02-17 14:39 984次阅读

    ADS1282发送SYNC命令之后无法发送RDATAC命令怎么处理?

    ADS1282发送SYNC命令之后无法发送RDATAC命令
    发表于 02-08 08:32

    使用任务通知提高RTOS应用的效率

    在实时嵌入式系统中,性能和资源效率是决定设计成败的关键因素。传统的实时操作系统(RTOS)提供了如队列、信号量和事件组机制,实现任务之间的同步和通信。FreeRTOS/SAFERTOS还提供一种方法可以使这些过程更快、更轻量化,即任务
    的头像 发表于 12-27 14:54 1066次阅读

    【RA-Eco-RA4E2-64PIN-V1.0开发板试用】MDK+点灯+流水灯

    的led引脚为P207\\\\P113P207引脚配置输出高P113也是这样当使用 RTOS 时,程序从 main 函数开始进行线程调度; 当没有使用 RTOS 时,C语言程序的入口
    发表于 12-15 15:59