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

    文章

    5619

    浏览量

    130406
  • API
    API
    +关注

    关注

    2

    文章

    2474

    浏览量

    67005
  • 函数
    +关注

    关注

    3

    文章

    4421

    浏览量

    67832
  • RTOS
    +关注

    关注

    25

    文章

    869

    浏览量

    123210

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

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

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【瑞萨FPB-RA6E2试用】【瑞萨FPB-RA6E2】RTOS(Real-Time Operating System,实时操作系统)《线程》个人理解及项目实现

    System,实时操作系统)线程含义 在 RTOS(Real-Time Operating System,实时操作系统) 中,线程(Thread) 是任务调度和并发执行的基本单位。不同 RT
    发表于 01-14 11:50

    如何在Zephyr RTOS中实现延时和计时函数

    在实时操作系统(RTOS)中,时间管理是核心功能之一。无论是任务调度、超时控制,还是周期性事件,延时和计时机制都扮演着至关重要的角色。Zephyr RTOS作为一个轻量级、模块化的开源系统,提供
    的头像 发表于 12-26 10:32 6087次阅读
    如何在Zephyr <b class='flag-5'>RTOS</b>中实现延时和计时<b class='flag-5'>函数</b>

    RTOS在嵌入式开发中的作用

    中,不依赖其它任务或调度器。 高峰负载管理 RTOS提供为管理系统高峰活动提供一个有效的方法。更高的优先级分配给执行峰值负载活动的
    发表于 12-26 07:53

    使用RTOS时需要注意的几点内容分享

    是为一个外设指定一个核。所以,在等待事件发生期间,使该核空闲起来是有意义的。 其结果是,优先式、中断驱动的RTOS架构占据业已部署的大部分平台。虽然借助硬件手段(多个寄存器组合、硬件调度、任务切换
    发表于 12-23 06:34

    选择RTOS的要点

    补充Linux,因为它们可提供硬实时级别的QoS。 要指出的很重要一点是:这类补充常常是在原始OS上集成一个RTOS编程环境。与传统台式或服务器OS相比,RTOS通常要小很多。RTOS
    发表于 12-12 08:00

    RTOS Crash 问题全维度分析与解决指南

    →TaskB”),识别死锁(长时间无切换)、优先级反转; 中断时长检测 :在ISR入口/出口记录时间戳(如SysTick值),排查ISR执行超时(超过RTOS调度周期); 压力测试 :模拟极限场景(如
    发表于 12-08 03:56

    FreeRTOS 空闲任务

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

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

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

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

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

    详解hal_entry入口函数

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

    同步任务开发指导

    ,推荐使用TaskPool。 定义并发函数,内部调用同步方法。 创建任务Task,通过execute()接口执行任务,并对任务返回的结果
    发表于 06-19 07:57

    【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 785次阅读
    <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 1605次阅读