FreeRTOS之TCB

2023-05-16

FreeRTOSMini实现了最小任务调度。现在分开介绍进程调度重要部分。进程调度的基础首先是定义任务调度的数据结构,来保存任务堆栈结构和任务状态所在状态列表,然后就是任务的优先级唯一号等。

最小Mini内核参照“FreeRTOSMini”篇,包含源码下载地址。

TCB重要信息有:
1.栈顶指针(pxTopOfStack并且告诉编译器不要优化,随时会变化),和芯片位数一致的整形指针指向任务栈顶。任务让出CPU时候要把寄存器R0-R15、程序计数器、程序状态寄存器等CPU执行上下文压到任务栈。任务被执行时候要通过TCB的栈顶指针从任务栈出栈恢复之前保存的上下文信息再接着执行。

2.状态列表项(xStateListItem),通过该列表项所属列表的指针快速调整状态列表项所在状态,即TCB所在状态。调度时候该列表项在就绪列表,当前运行项,等待列表不停切换。

3.任务优先级(uxPriority),任务调度按优先级实行抢占事调度,优先级也决定任务状态列表项所进的相应优先级列表。

4.其他的就不是那么重要了,像任务唯一号等等都是些辅助方面的。

为什么栈顶指针变量要放TCB结构体第一位(第二位就不行吗?)。这里就涉及到C语言结构体的实现了。
1.什么是结构体?
2.结构体内存本质是什么?

下面是我对结构体的理解:
结构体就是按结构把一些属性打包。这些属性占用的内存空间要求固定,如果是字符数组,长度是固定的。或者char*指针,指针大小是固定的,指针指向的东西长度可以不固定。结构体更像是面向简化开发写代码的东西。代码只要某个结构体对象->属性来操作指定属性。对编译器来说都是把属性缓存地址的偏移量。结构在内存的表现就是一个固定长度的内存占用。从第一个属性下来依次按类型从结构体开始位置指针偏移。

比如下面结构体成员内存就如下图:

//测试
struct Test
{
	char * A;
	int B;
	char C[10];
	int D;
} 

在这里插入图片描述

所以为什么要把存栈顶地址的变量放到结构体第一个属性。因为第一个数组的起始地址等于结构体地址。这样可以方便汇编代码通过当前运行TCB结构体快速得到栈顶指针方便操作。类似下图代码,因为是汇编代码,不好操作结构体的->属性。如果不放在第一个那么这些代码都得按位置偏移找到栈顶指针内存位置了。

在这里插入图片描述

TCB结构体如下(task control block):

//任务控制块结构体TCB,创建任务成功后返回该结构体
typedef struct tskTaskControlBlock
{
	//告诉编译器该变量值可能随时发生变化,且这种变化并不是代码引起的。
	//指向放置在任务堆栈上的最后一项的位置。 这必须是 TCB 结构的第一个成员
	volatile StackType_t* pxTopOfStack;

	//表示任务状态,不同的状态会挂接在不同的状态链表下
	//一共有四种状态分别是运行状态(Running State),就绪状态(Ready State),
	//阻塞状态(Blocked State),挂起状态(Suspended State)
	//运行状态:正在执行的任务。
	//就绪状态:等待获得执行权的任务。
	//阻塞状态:直到某些条件达成才会重新进入就绪态等待获得执行权,否则不会执行的任务。
	//挂起状态:除非被主动恢复,否则永远不会执行。
  //这四种链表分别对应着pxCurrentTCB,pxReadyTasksLists,pxDelayedTaskList,xSuspendedTaskList这四个变量。
	//除运行状态外,任务处于其它状态时,都是通过将任务TCB中的xStateListItem挂到相应的链表下来表示的
	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. */
//任务优先级,0是最低的,越大优先级越高
	UBaseType_t uxPriority;                     /*< The priority of the task.  0 is the lowest priority. */
  //指向堆栈起始位置(低地址),这只是单纯的一个分配空间的地址,可以用来检测堆栈是否溢出
	StackType_t* pxStack;                      /*< Points to the start of the stack. */
		//任务名称
	char pcTaskName[16];
	//记录临界段的嵌套层数
	UBaseType_t uxCriticalNesting;
	//跟踪调试用的变量
	UBaseType_t uxTCBNumber;  /*< Stores a number that increments each time a TCB is created.  It allows debuggers to determine when a task has been deleted and then recreated. */
	UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
	//任务优先级被临时提高时,保存任务原本的优先级
	UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
	UBaseType_t uxMutexesHeld;

	//用来标记这个任务的栈是不是静态分配的
	uint8_t ucStaticallyAllocated;
	//延时是否被打断
	uint8_t ucDelayAborted;
	//错误标识
	int iTaskErrno;
} tskTCB;

//老别名
typedef tskTCB TCB_t;
//定义tcb别名
typedef struct tskTaskControlBlock* TaskHandle_t;

通过这篇理解TCB数据结构栈顶指针为什么放第一位。和理解C语言结构体内存布局。从编译器的角度结构体就是固定长度的内存占用块。编译器把属性操作翻译为相对结构体地址偏移的地址操作。地址的偏移就按结构体的属性从上到下按每个类型的占用空间计算。就算是C的结构体,起始也可以直接按地址偏移操作内存地址的值。整个C各种类型和指针、取址都建立在CPU位数的地址上。指针即地址,变量只是一个内存地址的别名。如FreeRTOS的当前运行任务块pxCurrentTCB变量就是一个内存地址别名。这个地址指向的内存存TCB结构体的首地址。换了当前运行任务就把该内存值改新要执行TCB结构体首地址。
在这里插入图片描述

OS原来如此美妙,这就是通过TCB悟出来的点,分享给大家

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS之TCB 的相关文章

  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • FreeRTOS临界区

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • FreeRTOS记录(九、一个裸机工程转FreeRTOS的实例)

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • freertos————互斥锁

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • FreeRTOS轻量级同步--任务通知

    1 简介 在FreeRTOS的配置参数中的configUSE TASK NOTIFICATIONS宏打开 一般RTOS会默认打开 如图1所示 图1 notify宏开关 RTOS在创建任务时 会创建一个32位的通知值ulNotifiedVal
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站

随机推荐

  • 【软件教程】如何让vscode连接ssh时记住密码

    准备软件 客户机安装vscode xff08 vscode官网https code visualstudio com xff09 客户机和服务器配置ssh xff0c 确保能够连接 VSCode ssh记住密码教程 一 在Client客户机
  • 车辆检测--DAVE: A Unified Framework for Fast Vehicle Detection and Annotation

    DAVE A Unified Framework for Fast Vehicle Detection and Annotation ECCV2016 本文使用深度学习进行车辆检测和属性学习 提出的系统为 Detection and Ann
  • 对抗学习用于目标检测--A-Fast-RCNN: Hard Positive Generation via Adversary for Object Detection

    A Fast RCNN Hard Positive Generation via Adversary for Object Detection CVPR 2017 Caffe code https github com xiaolonw a
  • 人脸识别--SphereFace: Deep Hypersphere Embedding for Face Recognition

    SphereFace Deep Hypersphere Embedding for Face Recognition CVPR2017 https github com wy1iu sphereface pytorch https gith
  • 运动相机检测无人机-- Detecting Flying Objects using a Single Moving Camera

    Detecting Flying Objects using a Single Moving Camera PAMI 2017 http cvlab epfl ch research unmanned detection https dri
  • [转载]Python SMTP发送邮件-smtplib模块

    在进入正题之前 xff0c 我们需要对一些基本内容有所了解 xff1a 常用的电子邮件协议有SMTP POP3 IMAP4 xff0c 它们都隶属于TCP IP协议簇 xff0c 默认状态下 xff0c 分别通过TCP端口25 110和14
  • c语言和c++有什么区别

    差不多是win98跟winXP的关系 C 43 43 是在C的基础上增加了新的理论 xff0c 玩出了新的花样 所以叫C加加 C是一个结构化语言 xff0c 它的重点在于算法和数据结构 C程序的设计首要考虑的是如何通过一个过程 xff0c
  • 梳理LVM逻辑卷管理,

    在Linux操作系统会时不时碰到卷有关的操作 xff0c 以下也是罗列了相关操作内容 xff0c 仅供参考 创建PV VG LV的方法 将各物理磁盘或分区的系统类型设为Linux LVM xff0c 其system ID为8e xff0c
  • 使用sqlyog连接 Mysql 出现1251错误

    使用sqlyog连接 Mysql 出现1251错误 简述 xff1a 1251 client does not support authentication protocol requested by server consider upg
  • 准备给ubuntu18.04安装杀毒软件

    如题 xff0c 电脑最近总出现些奇奇怪怪的小问题 xff0c 还是得装个杀毒软件 xff0c 看是不是中病毒了 输入sudo apt get install clamtk 安装完成后 xff0c 输入clamtk 即可 xff0e 卸载方
  • 使用Nginx代理地址

    DotNetCore在Linux发布时候 xff0c 由于不止一个产品组发布网站 xff0c 不像以前大家都用IIS的80发布网站 那么就存在大家抢80端口的情况 xff0c 为了让大家不比加上端口为此用Nginx代理URL实现网站地址代理
  • CentOS安装Cache数据库

    适用CentOS7 6 CentOS8上安装Intersystem公司的Cache数据库 xff0c 资料基本是空白 xff0c 分享一下 首先安装解压软件unzip和libicu xff0c 最小化安装的缺 xff0c 全安装的不缺 yu
  • Cache数据库之ECP搭建

    Cache作为非关系数据库 xff0c 其强大毋庸置疑 首先其Globle结构 xff0c 直接暴露的表Globel数据 xff0c 以及提供的M语言操作Globle达到的最优查询速度 ECP xff08 企业缓存协议 xff09 更是提供
  • Sebia电泳绘图

    Sebia这仪器真是个奇葩的存在 自己仪器有图不存文件 xff0c LIS要的话还得自己按数据绘制 还有蛋白电泳 固定电泳 画不画参考线等不同要求 xff08 奇葩的很 xff09 按理这种事不属于lis范围 xff0c 无奈国内lis太卷
  • nginx代理与负载均衡

    随着谷歌浏览器不断的改变https调用websocket和非https资源的策略 xff0c 从谷歌大概70以后不允许https调用非https资源和ws的websocket 后面实现了wss解决谷歌这一策略的影响 随着谷歌到90后版本限制
  • FreeRTOS学习第一篇

    之前在STM32Nano开发板开发是基于裸机开发 xff0c 即自己在main方法写死循环 死循环轮流执行各个任务逻辑的方法 这样做直接简单 xff0c 但是不同任务有不同优先级 xff0c 对CPU响应要求不同 逻辑容易某个任务卡住了 x
  • FreeRTOS之heap4

    操作系统离不开内存管理 FreeRTOS提供了5种内存管理方法 实现在portable MemMang里heap1到heap5 每种管理方案策略不同 我采用的是比较有代表性的heap4管理方案 该模式定义了ucHeap全局数组充当堆内存池
  • FreeRTOSMini

    最近在研究实时操作系统FreeRTOS FreeRTOS作为开源的RTOS xff0c 源码规模不大 xff0c 可以供操作系统学习 xff0c 加上我的STM32 Nano开发板正好可以学习OS 借着五一放假宅家里学习 实现的FreeRT
  • 双master节点+keepalived方式部署K8s 1.18.20

    相关部署方式也挺多 xff0c 自己采用双master节点 43 单node节点方式 xff0c 并且采用keepalived部署1 18 20版本 xff0c 中间也出现过相关小问题 xff0c 但都一一处理 xff0c 记录以给需要的同
  • FreeRTOS之TCB

    FreeRTOSMini实现了最小任务调度 现在分开介绍进程调度重要部分 进程调度的基础首先是定义任务调度的数据结构 xff0c 来保存任务堆栈结构和任务状态所在状态列表 xff0c 然后就是任务的优先级唯一号等 最小Mini内核参照 Fr