[FreeRTOS 内部实现] 创建任务 xTaskCreate函数解析

文章目录

    • 创建任务 xTaskCreate函数原型
      • 栈深度 usStackDepth 大小如何确定
      • 任务堆空间分配
    • 任务控制块 TCB


创建任务 xTaskCreate函数原型

BaseType_t xTaskCreate(    TaskFunction_t pxTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask )

根据前面的文章可知,要创建一个任务需要 4个要素:运行函数,函数参数,栈,任务优先级。
在RTOS系统中创建任务函数 xTaskCreate,传入参数解析:

  • TaskFunction_t pxTaskCode :运行函数
  • const char * const pcName :函数名字
  • const configSTACK_DEPTH_TYPE usStackDepth :栈大小
  • void * const pvParameters :运行函数的参数
  • UBaseType_t uxPriority : 函数优先级
  • TaskHandle_t * const pxCreatedTask :任务控制块TCB 输出参数

栈深度 usStackDepth 大小如何确定

通过简单的示例来看下,普通的函数会产生多少栈大小,如何计算?
在这里插入图片描述
(1)PUSH {r4-r5,lr}: 将寄存器r4, r5和链接寄存器(lr)压入栈中。这是为了保存这些寄存器的值,以便函数调用结束后可以恢复它们。
(2)SUB sp,sp,#0x194: 从栈指针sp减去0x194(404),为局部变量分配栈空间。
(3)MOV r5, r1: 将r1寄存器的值移动到r5寄存器。这通常是将输入参数的一个值保存到另一个寄存器中。
(4)MOV r4, r0: 将r0寄存器的值移动到r4寄存器。同样,这可能是保存另一个输入参数。
(5)MOV r1, #0x18C: 将立即数0x18C(404)移动到r1寄存器。
(6)ADD r0, sp, #0x04: 将栈指针sp加上4,然后将结果移动到r0寄存器。
(7)BL.W 0x0800020C __aeabi_memclr4: BL.W是ARM的分支链接指令,用于远距离跳转,并在链接寄存器中保存返回地址。
(8)LDR r0, [pc, #24]: 从程序计数器pc地址加上24的位置加载数据到r0寄存器。
(9)LDR r0, [r0, #0x00]: 从r0寄存器指向的地址加载数据到r0。
(10)STR r0, [sp, #0x00]: 将r0寄存器的值存储到栈指针sp地址偏移0的位置。
(11)LDR r0, [r4, #0x00]: 从r4寄存器指向的地址加载数据到r0。
(12)STR r0, [sp, #0x190]: 将r0寄存器的值存储到栈指针sp地址偏移0x190的位置。
(13)LDR r0, [r5, #0x00]: 从r5寄存器指向的地址加载数据到r0。
(14)LDR r1, [sp, #0x190]: 从栈指针sp地址偏移0x190的位置加载数据到r1。
(15)ADD r0, r0, r1: 将r0和r1寄存器的值相加,结果存储在r0。
(16)STR r0, [sp, #0x190]: 将r0寄存器的值再次存储到栈指针sp地址偏移0x190的位置。
(17)STR r0, [r4, #0x00]: 将r0寄存器的值存储到r4寄存器指向的地址。
(18)ADD sp, sp, #0x194: 将栈指针sp加上0x194,释放之前分配的栈空间。
(19)POP {r4-r5,pc}: 从栈中弹出之前保存的r4, r5和pc值,恢复它们,并返回到调用这个函数的代码处。
在这里插入图片描述
栈大小可以根据任务中使用的临时变量估算出需要多大的栈空间,当然函数传入的栈大小要比估算的大些,以免超出越界访问。(一般为估算大小的两倍)

任务堆空间分配

在这里插入图片描述
#define configTOTAL_HEAP_SIZE ((size_t)3072)
RTOS系统中的栈是ucHeap数据,大小为3072字节
每创建一个任务都会在ucHeap堆空间申请出自己的堆空间。


任务控制块 TCB

作用:在栈中为每个任务分配一个任务控制块(TCB)。存储任务状态信息,包括指向任务上下文的指针(任务的运行时环境,包括寄存器值)。完成创建任务后,会将任务的TCB赋给 pxCreatedTask 参数

*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;

结构体TCB

typedef struct tskTaskControlBlock
{volatile StackType_t    *pxTopOfStack;    /* 指向任务堆栈中最后一项的位置。这必须是TCB结构体的第一个成员。*/ListItem_t            xStateListItem;    /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ListItem_t            xEventListItem;        /*< Used to reference a task from an event list. */UBaseType_t            uxPriority;            /* 任务优先级。  0 是优先级最低的。 */StackType_t            *pxStack;            /* 栈的最开始指针 */char            pcTaskName[ configMAX_TASK_NAME_LEN ];/* 任务名称 */ } tskTCB;

由于任务会在栈中会以TCB结构体的形式描述,因此 xTaskCreate函数传入的参数都应该在这个结构中体现。

const char * const pcName :函数名字char pcTaskName[ configMAX_TASK_NAME_LEN ];
UBaseType_t uxPriority : 函数优先级UBaseType_t uxPriority;
const configSTACK_DEPTH_TYPE usStackDepthvolatile :栈深度StackType_t *pxTopOfStack
StackType_t *pxStack;

发现在TCB结构体中没有最重要的运行函数以及参数,而在TCB结构体中存在两个链表。
任务在创建的时候,会将PC指向函数名字,R0寄存器存的参数。在任务切换的时候,要将全部环境保存下来,当下次获得CPU使用权的时候,恢复现场运行任务。因此任务栈中保存一套任务环境。
在这里插入图片描述

StackType_t *pxStack;pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );
if( pxNewTCB != NULL )
{/* Store the stack location in the TCB. */pxNewTCB->pxStack = pxStack;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM专题三:Java代码如何运行

通过前面的第一篇文章&#xff0c;对JVM整体脉络有了一个大概了解。第二篇文章我们通过对高级语言低级语言不同特性的探讨引出了Java的编译过程。有了前面的铺垫&#xff0c;咱们今天正式进入Java到底是如何运行起来的探讨。 目前大部分公司都是使用maven作为包管理工具&#x…

lvgl_micropython development for esp32

​​​​​​上一篇博客已经编译源码生成了ESP32C3的固件lvgl_micropy_ESP32_GENERIC_C3-4.bin&#xff0c;这篇博客开发一个界面。 一、开发环境 1、安装开发工具 Windows安装Thonny工具&#xff0c;官网链接&#xff1a;Thonny, Python IDE for beginners。 参考博客:用M…

游戏开发丨基于Tkinter的五子棋小游戏

文章目录 写在前面Tkinter五子棋系列文章写在后面 写在前面 本期内容&#xff1a;基于tkinter的五子棋小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700190 实验环境 python3.11及以上pycharmtkinter Tkinter Tkinter是Python的一个标准…

文件创建与查看

touch touch命令用于创建一个新的文件。 语法&#xff1a;touch Linux路径 其中路径可以是相对路径、绝对路径或者特殊路径符都可以。 改图展示了通过 touch test.txt 命令创建了一个 test.txt文件&#xff0c;其中深色的代表文件夹&#xff0c;白色的代表文件。 使用 ls -lh…

第一次接触Swing

学习java版的HslCommunication发现使用的是Swing&#xff0c;所以了解了一下~ 了解&#xff1a; Swing是Java的标准库&#xff08;Java Foundation Classes, JFC&#xff09;的一部分&#xff0c;用于构建桌面应用程序的图形用户界面&#xff08;GUI&#xff09;。它是Java AWT…

[每周一更]-(第102期):认识相机格式Exif

文章目录 EXIF数据包含的信息读取EXIF数据的工具和库EXIF数据读取示例&#xff08;Go语言&#xff09;想法参考 相机拍摄的照片&#xff0c;在照片展示行无水印信息&#xff0c;但是照片属性中会包含比较丰富的信息&#xff0c;相机品牌、型号、镜头信息等&#xff0c;这些我们…

基于SpringBoot+Vue大学毕业设计管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…

SpringBoot-通过注解@Vuale从全局配置文件中获取数据

除了通过注解ConfigurationProperties让JavaBean的所有属性和全局配置文件中配置项建立关联关系外&#xff0c;我们spring提供了一个Value注解&#xff0c;获取全局配置文件中的某个配置项的数据 接下来&#xff0c;我们重点说一下两个注解的的区别&#xff1a; Configuration…

深入理解数据仓库建模——数据湖、数仓一体化

引言 在当今数据驱动的时代&#xff0c;数据仓库和数据湖的结合已经成为企业数据管理的关键。本文将深入探讨数据湖与数据仓库一体化的概念、优势以及实现方法&#xff0c;并结合实际案例&#xff0c;为大家展示如何有效地实现这一目标。 数据湖与数据仓库的区别 数据湖和数…

Docker(五)-本地镜像发布到阿里云

1.镜像发布流程图 2.登录阿里云&#xff0c;进入容器镜像服务&#xff08;ACR&#xff09; 3.进入个人实例 3.个人实例中创建命名空间 4.创建镜像仓库 5.本地镜像推送至阿里云 docker login --username你的阿里云账号 registry.cn-hangzhou.aliyuncs.comdocker tag [ImageId] …

CTF-蓝帽杯 2022 初赛Misc计算机取证题目详解

使用工具&#xff1a;Volatility、Passware Kit、Arsenal Image Mounter、DiskGenius 题目文件如下&#xff1a; 首先要知道这些文件是什么&#xff1a; dmp后缀指Dump文件&#xff0c;是windows系统中的错误转储文件。包含计算机程序运行时的内存信息的文件。通常操作系统或…

【Git】win本地 git bash:Connect reset by 20.205.243.166 port22报错问题解决

win10 git bash 控制台 reset 22端口拒绝连接问题&#xff1a; Connection reset by 20.205.243.166 port 221、22端口 无法连接 ssh -T gitgithub.com2、尝试用443端口 仍然无法连接 ssh -T -P 443 gitgithub.com3、重写 git clone 地址 url&#xff0c;全局添加 https 前缀…

每日一题——Python代码实现力扣1. 两数之和(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 菜鸡写法 代码分析 时间复杂度分析 空间复杂度分析 改进建议 我要更强 方法1: 使…

自然语言处理领域的明星项目推荐:Hugging Face Transformers

在当今人工智能与大数据飞速发展的时代&#xff0c;自然语言处理&#xff08;NLP&#xff09;已成为推动科技进步的重要力量。而在NLP领域&#xff0c;Hugging Face Transformers无疑是一个备受瞩目的开源项目。本文将从项目介绍、代码解释以及技术特点等角度&#xff0c;为您深…

气膜建筑:持久耐用的建筑选择—轻空间

随着科技的发展&#xff0c;气膜建筑以其快速施工、节能环保和灵活多用的特点&#xff0c;正在各个领域获得越来越多的应用。然而&#xff0c;许多人对气膜建筑的耐用程度仍存有疑虑。本文将从气膜建筑的材料、结构设计和维护等方面&#xff0c;深入探讨气膜建筑的耐用性&#…

EndNote 21 for Mac v21.3 文献管理软件安装

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行安装EndNote212、升级 三、运行1、打开软件&#xff0c;测试 安装完成&#xff01;&#xff01;&#xff01;四、注意事项 效果 一、下载软件 下载软件 链接&#xff1a;http://www.macfxb.cn 二、开始安装 1、双击…

无霍尔BLDC驱动

目前主要的无霍尔控制方案是基于反电势检测信 息判断换相点,本文研究反电势在 PWM - OFF 点的检 测方案确定换相点。 1. 反电动势检测方案 BLDC 的模型做等效,将线圈阻抗看成是一个 线性电阻和一个储能电感的等效,其等效电路图如图 1所示。 电机三相绕组输出端电压的电压…

Typora + Hexo 图片路径问题(Typedown)

文章目录 1. 冲突来源2. 解决思路3. 实现1. typora图片路径2. hexo脚本 1. 冲突来源 Hexo上对于图片在md中的引用&#xff0c;使用了post_asset_folder: true配置&#xff0c;来更好的管理图片。 当一篇名为xxx.md的文章引用1.png图片时&#xff0c;默认让1.png保持在xxx文件夹…

热电阻温度计的测量电路

热电阻温度计的测量电路&#xff0c;为达到高精度测量&#xff0c;通常会采用电桥测量原理&#xff0c;并结合适当的热电阻类型和连接方式。 惠斯通电桥是用于测量一组电阻式元件阻值变化的电路。该电路具有两个并联电阻支路&#xff0c;充当激励电压 VEXCITATION 的分压器。每…

帕金森综合征的预防方法

帕金森综合征是一种慢性神经退行性疾病&#xff0c;目前尚无法彻底治愈。然而&#xff0c;通过采取一些预防措施&#xff0c;可以降低患病风险或延缓病情发展。以下是一些基于最新研究和医学建议的预防方法&#xff1a; 健康饮食&#xff1a;保持低盐、低脂饮食&#xff0c;多吃…