当前位置: 首页 > news >正文

FreeRTOS——TCB任务控制块、任务句柄、任务栈详解

任务控制块结构体

任务控制块是 FreeRTOS 中用于描述和管理任务的数据结构,包含了任务的状态、优先级、堆栈等信息。

TCB_t的全称为Task Control Block,也就是任务控制块,这个结构体包含了一个任务所有的信息,它的定义以及相关变量的解释如下:

typedef struct tskTaskControlBlock             {// 这里栈顶指针必须位于TCB第一项是为了便于上下文切换操作,详见xPortPendSVHandler中任务切换的操作。volatile StackType_t    *pxTopOfStack;    // MPU相关暂时不讨论#if ( portUSING_MPU_WRAPPERS == 1 )xMPU_SETTINGS    xMPUSettings;        #endif// 表示任务状态,不同的状态会挂接在不同的状态链表下ListItem_t            xStateListItem;    // 事件链表项,会挂接到不同事件链表下ListItem_t            xEventListItem;        // 任务优先级,数值越大优先级越高UBaseType_t            uxPriority;            // 指向堆栈起始位置,这只是单纯的一个分配空间的地址,可以用来检测堆栈是否溢出StackType_t            *pxStack;            // 任务名char                pcTaskName[ configMAX_TASK_NAME_LEN ];// 指向栈尾,可以用来检测堆栈是否溢出#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )StackType_t        *pxEndOfStack;        #endif// 记录临界段的嵌套层数#if ( portCRITICAL_NESTING_IN_TCB == 1 )UBaseType_t        uxCriticalNesting;    #endif// 跟踪调试用的变量#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t        uxTCBNumber;        UBaseType_t        uxTaskNumber;        #endif// 任务优先级被临时提高时,保存任务原本的优先级#if ( configUSE_MUTEXES == 1 )UBaseType_t        uxBasePriority;        UBaseType_t        uxMutexesHeld;#endif// 任务的一个标签值,可以由用户自定义它的意义,例如可以传入一个函数指针可以用来做Hook    函数调用#if ( configUSE_APPLICATION_TASK_TAG == 1 )TaskHookFunction_t pxTaskTag;#endif// 任务的线程本地存储指针,可以理解为这个任务私有的存储空间#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )void            *pvThreadLocalStoragePointers[     configNUM_THREAD_LOCAL_STORAGE_POINTERS ];#endif// 运行时间变量#if( configGENERATE_RUN_TIME_STATS == 1 )uint32_t        ulRunTimeCounter;    #endif// 支持NEWLIB的一个变量#if ( configUSE_NEWLIB_REENTRANT == 1 )struct    _reent xNewLib_reent;#endif// 任务通知功能需要用到的变量#if( configUSE_TASK_NOTIFICATIONS == 1 )// 任务通知的值 volatile uint32_t ulNotifiedValue;// 任务通知的状态volatile uint8_t ucNotifyState;#endif// 用来标记这个任务的栈是不是静态分配的#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) uint8_t    ucStaticallyAllocated;         #endif// 延时是否被打断#if( INCLUDE_xTaskAbortDelay == 1 )uint8_t ucDelayAborted;#endif// 错误标识#if( configUSE_POSIX_ERRNO == 1 )int iTaskErrno;#endif} tskTCB;typedef tskTCB TCB_t;

栈顶指针必须为TCB结构体的第一项,原因是栈顶指针与我们的任务上下文保存、任务切换和任务恢复等操作息息相关。 

每个任务都有自己的任务控制块,类似身份证。

TCB结构体中portSTACK_GROWTH>0表示栈是向上生长,<0表示栈是向下生长,我们STM32的栈是高地址往低地址存储,是向下生长的;而堆是低地址往高地址生长,是向上生长的。

 

任务句柄

        任务句柄(Task Handle)是在 FreeRTOS 中用于标识和引用任务的数据类型。每个创建的任务都会分配一个唯一的任务句柄,通过该句柄可以对任务进行操作和管理。

任务句柄是一个指向任务控制块(Task Control Block,TCB)的指针

        使用任务句柄,可以通过 FreeRTOS 提供的 API 函数对任务进行操作,例如挂起(suspend)、恢复(resume)、删除(delete)任务,或者查询任务的状态等。另外,任务句柄还可以用于任务通信和同步的机制,例如向任务发送信号量或消息。

        在创建任务时,通过调用 FreeRTOS 提供的任务创建函数(例如 xTaskCreate())可以获取到相应任务的句柄。你可以将该句柄保存在一个变量中,以便后续对该任务进行操作或引用。

任务句柄提供了一种有效的方式来管理和操作 FreeRTOS 中的任务。通过使用任务句柄,可以方便地对任务进行控制和监视。

任务栈

图解

任务创建 static void prvInitialiseNewTask(…)
这个函数用于创建新的任务,其中的 “prv” 表示该函数是一个私有函数,只用于内部处理和初始化新任务的操作。对于外部使用者来说,应该使用公开的 API 函数来创建和管理任务,而不是直接调用 “prvInitialiseNewTask”。
这个函数被 TaskHandle_t xTaskCreateStatic() 函数调用
函数源代码如下:

static void prvInitialiseNewTask( 	TaskFunction_t pxTaskCode,              /* 任务入口 */const char * const pcName,              /* 任务名称,字符串形式 */const uint32_t ulStackDepth,            /* 任务栈大小,单位为字 */void * const pvParameters,              /* 任务形参 */TaskHandle_t * const pxCreatedTask,     /* 任务句柄 */TCB_t *pxNewTCB )                       /* 任务控制块指针 */{StackType_t *pxTopOfStack; //栈顶UBaseType_t x;	/* 获取栈顶地址 */pxTopOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 );//pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );/* 向下做8字节对齐 */pxTopOfStack = ( StackType_t * ) ( ( ( uint32_t ) pxTopOfStack ) & ( ~( ( uint32_t ) 0x0007 ) ) );	/* 将任务的名字存储在TCB中 */for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ){pxNewTCB->pcTaskName[ x ] = pcName[ x ];if( pcName[ x ] == 0x00 ){break;}}/* 任务名字的长度不能超过configMAX_TASK_NAME_LEN */pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';/* 初始化TCB中的xStateListItem节点 */vListInitialiseItem( &( pxNewTCB->xStateListItem ) );/* 设置xStateListItem节点的拥有者 */listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );/* 初始化任务栈 */pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );   /* 让任务句柄指向任务控制块 */if( ( void * ) pxCreatedTask != NULL ){		*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;}
}

初始化任务栈 StackType_t *pxPortInitialiseStack(…)

详细存储见下图:

初始化任务栈的作用是保存当前上下文的任务信息,以供我们后续任务切换所使用。

总结:

任务控制块是存储任务信息的载体,每个任务都有对应自己的任务控制块,我们在创建完任务之后,生成了任务对应的任务控制块,我们所定义的对应任务句柄在任务创建完成之后,就会指向我们的任务控制块,相当于我们可以通过任务句柄,间接去控制和管理我们的任务,而任务栈则是一些寄存器的载体,任务栈通过栈顶地址的加减,去存储一些寄存器信息,进而去设置任务的模式以及一些任务切换时所需要的信息,例如将任务栈中的PC寄存器存储了该任务的函数指针,在进行任务切换时,就可以调出PC寄存器存储的信息,进而找到相应的任务函数去执行,任务栈也为该任务预留了一些寄存器的空间,方便后面的使用。

相关文章:

FreeRTOS——TCB任务控制块、任务句柄、任务栈详解

任务控制块结构体 任务控制块是 FreeRTOS 中用于描述和管理任务的数据结构&#xff0c;包含了任务的状态、优先级、堆栈等信息。 TCB_t的全称为Task Control Block&#xff0c;也就是任务控制块&#xff0c;这个结构体包含了一个任务所有的信息&#xff0c;它的定义以及相关变…...

【STM32单片机_(HAL库)】4-5-2【定时器TIM】【感应开关盖垃圾桶项目】HC-SR04超声波模块实验

1.硬件 STM32单片机最小系统HC-SR04超声波模块 2.软件 hcsr04驱动文件添加main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "uart1.h" #include "hcsr04.h"int main(void) {HAL_Init(); …...

安全网络架构

网络安全解决方案是指通过一系列技术和措施来保护网络系统和数据的安全。它涉及多个方面&#xff0c;包括网络设备的防护、数据的加密和备份、安全策略的制定和执行等。以下是一些常见的网络安全解决方案&#xff1a; 防火墙&#xff1a;防火墙是一种硬件或软件设备&#xff0c…...

【万字长文】Word2Vec计算详解(二)Skip-gram模型

【万字长文】Word2Vec计算详解&#xff08;二&#xff09;Skip-gram模型 写在前面 本篇介绍Word2Vec中的第二个模型Skip-gram模型 【万字长文】Word2Vec计算详解&#xff08;一&#xff09;CBOW模型 markdown行 9000 【万字长文】Word2Vec计算详解&#xff08;二&#xff09;S…...

随机掉落的项目足迹:解决TypeError: Cannot read properties of undefined (reading ‘push‘)报错

问题引入 下面是request.js中请求拦截器相关的代码 但是运行时却出现了报错 问题解决 useRouter() 是 Vue Router 提供的组合式 API&#xff0c;它只能在 Vue 组件的 setup() 函数中有效。如果在其他地方&#xff08;例如 Axios 的拦截器中&#xff09;调用它&#xff0c;可…...

ChatTTS 本地安装和测试

Ubuntu 22服务器&#xff0c;3.9/3.10都可以&#xff0c;但是 3.11不可以 sudo apt install python3.10 apt install python3.10 python3.10-dev #ubuntu 22 安装python3.10对应的pip3.10 # 下载 get-pip.py curl -sS https://bootstrap.pypa.io/get-pip.py -o get-pip.py # 使…...

[Leetcode] 560 Subarray Sum Equals K

题意&#xff1a;给定一个数组求连续的子数组的和为k的有几个 Input: nums [1,1,1], k 2 Output: 2 https://leetcode.com/problems/subarray-sum-equals-k/description/ 首先思考1.因为是subarray sum前缀和很容易想到&#xff0c;那问题就转化成preSum[i] preSum[j] - k…...

TCL Android面试题大全及参考答案

能谈谈Jetpack组件吗? Jetpack 是一套用于 Android 开发的工具和组件库,它可以帮助开发者更高效地构建高质量的 Android 应用。 一、主要组件分类 架构组件: ViewModel:负责存储和管理与界面相关的数据,当屏幕旋转或配置发生变化时,ViewModel 可以帮助保存数据,避免数据…...

JVM错误:OutOfMemoryError: GC overhead limit exceeded

OutOfMemoryError: GC overhead limit exceeded 在Window服务器上跑一个项目&#xff0c;无意中出现服务访问不了&#xff0c;查看日志文档&#xff0c;第一次遇到了这个异常信息。 1. 错误含义 OutOfMemoryError: GC overhead limit exceeded 是 JVM 中的一种错误&#xff…...

Unity网络开发 - C#开源网络通信库PESocket的使用

概述 在现代多人在线游戏中&#xff0c;稳定且高效的网络通信是确保游戏体验的关键。本文将探讨如何利用C#开源网络通信库PESocket来构建一个简单的Unity客户端与.NET控制台服务器之间的实时消息传递系统。通过本例&#xff0c;读者不仅能够了解PESocket的基本用法&#xff0c…...

【完-网络安全】Shell与脚本

文章目录 1.CLI与GUI2.终端和Shell2.1 Shell 壳层2.2 终端2.3 终端和Shell区别3.标准流 4.PowerShell4.1 管理员与非管理员4.2 指令4.3 重定向4.4 管道 5.环境变量5.1 影响范围5.2环境变量的作用5.3 常见的环境变量 6.脚本 1.CLI与GUI CLI命令行界面(CLl,Command Line Interfa…...

磁盘标签和分区标签

在Windows中&#xff0c;我们为分区命名&#xff0c;那个名字就是「分区标签」。所以说“分区标签”是给分区的一个名字。 「磁盘标签」其实是我们经常说的「分区表」&#xff0c;比如MBR、GPT等等。而「分区标签」&#xff0c;虽然叫做“分区”标签&#xff0c;但它则是文件系…...

关于摩托车一键启动无钥匙进入、智能科技创新

摩托车一键启动无钥匙进入功能 一、工作原理 摩托车的一键启动无钥匙进入功能采用了世界最先进的RFID无线射频技术和最先进的车辆身份编码识别系统&#xff0c;率先应用小型化、小功率射频天线的开发方案&#xff0c;并成功融合了遥控系统和无钥匙系统&#xff0c;沿用了传统…...

怎么找矩阵系统,怎么源码搭建,源头技术开发需要哪些支持

一、引言 在进行矩阵系统源码搭建时&#xff0c;选择合适的工具至关重要。正确的工具选择不仅可以提高开发效率&#xff0c;还能确保系统的稳定性、可扩展性和性能。本文将探讨在矩阵系统源码搭建过程中如何选择合适的工具。 二、前端开发工具选择 前端框架 React&#xff1a;由…...

云原生化 - 工具镜像(简约版)

在微服务和云原生环境中&#xff0c;容器化的目标之一是尽可能保持镜像小型化以提高启动速度和减少安全风险。然而&#xff0c;在实际操作中&#xff0c;有时候需要临时引入一些工具来进行调试、监控或问题排查。Kubernetes提供了临时容器&#xff08;ephemeral containers&…...

uni-app如何搭建项目(一步一步教程)

来来来&#xff0c;看这里 uni-app新建项目教程uni-app项目结构 首先我们要有一个HBuilder这个软件&#xff0c;然后我们来搭建uni-app项目 uni-app新建项目教程 首先我们打开这个HBuilder软件&#xff0c;好我们就出现这个界面&#xff0c;我们点击新建项目   然后我们选择…...

javascript中原型链(__proto__)与原型(prototype)

JavaScript中原型链(proto)与原型(prototype) 在JavaScript中&#xff0c;理解原型链&#xff08;__proto__&#xff09;和原型&#xff08;prototype&#xff09;对于深入掌握面向对象编程至关重要。本文将通过示例代码&#xff0c;详细解析__proto__和prototype之间的关系&a…...

基于多种机器学习的酒店客户流失预测模型的研究与实现

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍实现过程 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 项目背景&#xff1a; 在当今竞争激烈的酒店行业中&#xff0c;预测和防止客户流…...

Unity实现自定义图集(三)

以下内容是根据Unity 2020.1.0f1版本进行编写的   1、实现编辑器模式下进游戏前Pack全部自定义图集 同Unity的图集一样,Unity的编辑器模式会在进游戏前把全部的SpriteAtlas都打一次图集,如图: 我们也实现这样的效果。 首先需要获取全部的图集路径。因为目前使用的是以.…...

【测开面试真题】

针对地图导航设计测试用例 文章目录 1. selenium 定位元素的方式有几种&#xff1f;2. 自动化测试能够取代人工测试吗&#xff1f;3. 什么是回归测试&#xff1f; 1. selenium 定位元素的方式有几种&#xff1f; &#x1f427;①通过CSS选择器定位&#xff1b;&#x1f427;②…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...