[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…

计算机中的字典顺序

计算机中的字典顺序 字典顺序&#xff08;Lexicographical Order&#xff09;是一种按照字母表顺序排列的顺序。在计算机科学中&#xff0c;字典顺序通常用于对字符串、字符序列或其他数据进行排序或比较。 字典顺序的原理是从左到右逐个比较字符的 ASCII 值或 Unicode 编码&am…

第一次接触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] …

注解详解系列 - @Primary:优先选择的Bean

注解简介 在今天的注解详解系列中&#xff0c;我们将探讨Primary注解。Primary是Spring框架中的一个重要注解&#xff0c;用于在有多个候选Bean时指定首选的Bean。通过Primary注解&#xff0c;可以明确地告诉Spring容器在注入依赖时选择哪个Bean。 注解定义 Primary注解用于指…

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

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

uniapp的picker组件:解决多个uv-picker时,每个picker高亮的内容显示不是已选择项的问题

先看看是不是你想要的&#xff1a; 解决前&#xff1a; uv-picker解决高亮和已选择项不同的问题 解决后&#xff1a; 解决后的uv-picker高亮及选择项 背景&#xff1a; 此项目是使用vue3uniapp开发的h5项目&#xff0c;项目的某个页面有两个或多个下拉选项&#xff0c;选择的第…

37.自定义协议

自定义协议要素 1.魔数:用来第一时间判定是否是无效数据包。 2.版本号:主持协议升级。 3.序列化算法:消息正文到底采用那种序列化方式,可以由此扩展,例如:json,protobuf(google的序列化算法,基于二进制,虽然可读性不好,但是字节数占用更少),hessian(基于二进制)…

【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: 使…

samba服务器配置(非常详细)

1、安装Samba软件包 sudo apt-get install samba samba-common 2、修改Samba配置文件,配置共享信息 2.1、打开配置文件: sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak//为了防止配置错误,可以先进行备份 sudo vim /etc/samba/smb.conf //对配置文件进行修改 …

服务器监控:运维行业的核心保障与第三方监控软件的选择

随着信息技术的飞速发展&#xff0c;企业IT架构日益复杂&#xff0c;服务器作为整个IT系统的核心&#xff0c;其稳定性和性能对业务的连续性至关重要。在运维行业中&#xff0c;服务器监控作为保障服务器稳定运行的关键环节&#xff0c;已经受到了越来越多企业的重视。本文将探…

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

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