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 的相关文章

  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • STM32CubeMX+FreeRTOS学习笔记(一)

    嵌入式实时操作系统FreeRTOS 基本概述 在嵌入式领域当中 实时操作系统的应用越来越广泛了 目前嵌入式操作系统种类很多 例如 Clinux C OS II C OS III FreeRTOS RT Thread等等 这篇文章所记录的就是
  • FreeRTOS-内核控制函数

    FreeRTOS 内核控制函数 FreeRTOS中有一些内核函数 一般来说这些内核函数在应用层不会使用 但是内核控制函数是理解FreeRTOS中断的基础 接下来我们逐一分析这些内核函数 taskYIELD 该函数的作用是进行任务切换 这是一
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

    摘要 每个任务都有自己的堆栈 堆栈的总大小在创建任务的时候就确定了 此函数用于检查任务从创建好到现在的历史剩余最小值 这个值越小说明任务堆栈溢出的可能性就越大 FreeRTOS 把这个历史剩余最小值叫做 高水位线 此函数相对来说会多耗费一点
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • FreeRTOS,串口中断接收中使用xQueueOverwriteFromISR()函数,程序卡死在configASSERT

    原因 UART的中断优先级设置的太高 高于了configMAX SYSCALL INTERRUPT PRIORITY宏定义的安全中断等级 UART的中断等级小于等于宏定义的优先等级即可
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • 再论FreeRTOS中的configTOTAL_HEAP_SIZE

    关于任务栈和系统栈的基础知识 可以参考之前的随笔 FreeRTOS 任务栈大小确定及其溢出检测 这里再次说明 define configTOTAL HEAP SIZE size t 17 1024 这个宏 官方文档解释 configTOTA
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • 【软件教程】如何让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