【FreeRTOS】FreeRTOS 源码学习笔记 (4) 任务创建xTaskCreate + 常用结构体TCB、xLIST

2023-05-16

1. 引言

经过第一节的移植,我们已经拿到了一个可以用的工程。 经过第二三节的基础知识,我们对基本的数据结构,列表、队列这些也有了一个了解。
接下来就可以单步跟踪了,看一下系统是怎么运行的。
使用FreeRTOS,首先要新建一个任务,我们可以单步跟一下它的运行流程,在调试之前,还是要先把最重要的几个结构体整理一下。

(本文初版为2020.4.12,FreeRTOS的代码版本为FreeRTOS Kernel V10.3.1)

2. 重要结构体

2.1 TCB

做FreeRTOS肯定首先要把大名鼎鼎的TCB干掉。
直接上源码先

//task.c 
//line 250

/*
 * Task control block.  A task control block (TCB) is allocated for each task,
 * and stores task state information, including a pointer to the task's context
 * (the task's run time environment, including register values)
 */
typedef struct tskTaskControlBlock 			/* The old naming convention is used to prevent breaking kernel aware debuggers. */
{
	volatile StackType_t	*pxTopOfStack;	/*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */

	#if ( portUSING_MPU_WRAPPERS == 1 )
		xMPU_SETTINGS	xMPUSettings;		/*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
	#endif

	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;			/*< The priority of the task.  0 is the lowest priority. */
	StackType_t			*pxStack;			/*< Points to the start of the stack. */
	char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */

	#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
		StackType_t		*pxEndOfStack;		/*< Points to the highest valid address for the stack. */
	#endif

	#if ( portCRITICAL_NESTING_IN_TCB == 1 )
		UBaseType_t		uxCriticalNesting;	/*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
	#endif

	#if ( configUSE_TRACE_FACILITY == 1 )
		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. */
	#endif

	#if ( configUSE_MUTEXES == 1 )
		UBaseType_t		uxBasePriority;		/*< The priority last assigned to the task - used by the priority inheritance mechanism. */
		UBaseType_t		uxMutexesHeld;
	#endif

	#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;	/*< Stores the amount of time the task has spent in the Running state. */
	#endif

	#if ( configUSE_NEWLIB_REENTRANT == 1 )
		/* Allocate a Newlib reent structure that is specific to this task.
		Note Newlib support has been included by popular demand, but is not
		used by the FreeRTOS maintainers themselves.  FreeRTOS is not
		responsible for resulting newlib operation.  User must be familiar with
		newlib and must provide system-wide implementations of the necessary
		stubs. Be warned that (at the time of writing) the current newlib design
		implements a system-wide malloc() that must be provided with locks.

		See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
		for additional information. */
		struct	_reent xNewLib_reent;
	#endif

	#if( configUSE_TASK_NOTIFICATIONS == 1 )
		volatile uint32_t ulNotifiedValue;
		volatile uint8_t ucNotifyState;
	#endif

	/* See the comments in FreeRTOS.h with the definition of
	tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */
	#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
		uint8_t	ucStaticallyAllocated; 		/*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
	#endif

	#if( INCLUDE_xTaskAbortDelay == 1 )
		uint8_t ucDelayAborted;
	#endif

	#if( configUSE_POSIX_ERRNO == 1 )
		int iTaskErrno;
	#endif

} tskTCB;

/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t;

一些可选功能先跳过,抽出其中几个关键的member说一下。

{
	volatile StackType_t	*pxTopOfStack;	/*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
	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;			/*< The priority of the task.  0 is the lowest priority. */
	StackType_t			*pxStack;			/*< Points to the start of the stack. */
	char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
  • pxStack : 每个任务都有一个栈帧空间,pxStack 指的就是这个空间的起始地址(低地址)。(malloc开出来的地址)
  • pxTopOfStack:栈顶的位置。随着入栈出栈操作,栈顶会一直变。
  • pxEndOfStack:栈空间的结尾,如果栈向上生长,就是栈帧空间最大的地址,如果栈向下,就是栈帧空间最小的地址,也就是pxStack,所以portSTACK_GROWTH > 0时才会有这个member,不然重复。
  • xStateListItem:状态列表,表明当前系统的状态。挂在链表中是方便来找,如果是用一个变量来表明,每次还得遍历一遍来找,效率低,链表方便。
  • xEventListItem:事件列表
  • uxPriority : 优先级。FreeRTOS的优先级是越大越优先。最大值是在头文件里配置的,配置一个合适的值就好,不然太大也浪费。因为每个优先级其实也会申请空间来存列表。

2.2 xList

列表的结构体在 列表 里介绍了。
使用起来基本如下图:

网上找了一张图,侵删。
在这里插入图片描述

有些列表是有序的。要用vListInsert插入,按照value值组成一个升序,在有序列表中,xListEnd.pxNext指向的是头,xListEnd.pxPrevious指向的是尾巴。在真实使用时,要根据顺序来做判断的。
有些链表是无序的。vListInsertEnd插入,只是表示一个集合。无序列表中,具体到FreeRTOS中的轮询列表,它不标记逻辑头尾,因为vListInsertEnd()插入时并不是根据xListEnd,而是pxIndex

3. 任务创建流程

任务创建主要使用xTaskCreate接口来创建,流程十分简介。

  1. 开空间
    任务需要管理 和 运行,任务管理需要TCB控制块,任务运行需要任务堆栈。
    所以xTaskCreate的开头就是为这两部分需求开空间。在具体代码中会根据栈的生长方向来做一个malloc顺序的调整,主要就是为了如果栈溢出,不至于覆盖到TCB结构体。这里也是比较细节的。
    pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );负责给TCB模块开空间。
    pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );负责给堆栈开空间,这个开空间的控制参数usStackDepth 是从函数入参传进来的。
  2. TCB初始化
    接下来,就是对TCB结构体的参数一堆初始化,调用prvInitialiseNewTask接口来进行。这里面主要是对TCB结构体成员进行初始化,包括栈空间地址pxTopOfStack的赋值,任务名pcTaskName的赋值等。
  • pxTopOfStack,对pxTopOfStack赋值是根据栈生长方向来计算。根据栈空间的起始地址(malloc开的低地址)和整个栈的大小,来判断pxTopOfStack在栈空间最低还是最高位置(另外做一下字节对齐)
  • pcTaskName,这里通过对每个字符的赋值来填充pcTaskName,在最后添加’\0’结束符。而没有用strcpy这种,减少对库的依赖。
  • uxPriority,优先级直接用配置值
  • xStateListItem,使用vListInitialiseItem接口初始化状态列表。
  • xEventListItem,使用vListInitialiseItem接口初始化事件列表。
    然后初始化栈,栈第一次是空的,虽然是第一次用,但是要把栈改成一种“从任务切换出来”的样子,这样下次任务切换回来的时候,就不用针对第一次使用这个任务的栈做处理了。
  1. 加入就绪列表
    最后把任务先加入到ready列表中(prvAddNewTaskToReadyList),等待调度。

基本流程图如下
在这里插入图片描述

4. 参考链接

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

【FreeRTOS】FreeRTOS 源码学习笔记 (4) 任务创建xTaskCreate + 常用结构体TCB、xLIST 的相关文章

  • 玩转肺癌目标检测数据集Lung-PET-CT-Dx ——③整理、验证数据,建立Dataset对象

    文章目录 数据整理整理出所有的dcm文件整理出所有的xml标注文件整理数据 舍弃错误的标注文件整理数据 两个标注文件指向同一个目标图片的情况封装函数 xff0c 传入xml文件 xff0c 显示标注效果 整理数据 将PETCT的三通道图像转
  • Java_求 1+11+111+1111+11111+111111+1111111+11111111

    span class token keyword package span cn span class token punctuation span myAlgorithm span class token punctuation span
  • Ubuntu22.04安装CUDA、cudnn详细步骤

    文章目录 安装CUDA安装cudnn下载安装文件安装验证是否安装成功 在Ubuntu系统中 xff0c 使用nvidia smi命令可以看到当前GPU信息 xff0c 在右上角可以看到CUDA Version xff0c 意思是最大支持的C
  • Ubuntu22.04部署Pytorch2.0深度学习环境

    文章目录 安装Anaconda创建新环境安装Pytorch2 0安装VS CodeUbuntu下实时查看GPU状态的方法小实验 xff1a Ubuntu Windows10下GPU训练速度对比 Ubuntu安装完显卡驱动 CUDA和cudn
  • 玩转肺癌目标检测数据集Lung-PET-CT-Dx ——④转换成PASCAL VOC格式数据集

    文章目录 关于PASCAL VOC数据集目录结构 创建VOC数据集的几个相关目录XML文件的形式 读取dcm文件与xml文件的配对关系 创建VOC格式数据集 创建训练 验证集 本文所用代码见文末Github链接 关于PASCAL VOC数据
  • Ubuntu与win10 修改开机启动顺序

    lfg 64 lfg ubuntu cd boot grub 打开grub cfg所在文件夹 lfg 64 lfg ubuntu boot grub sudo chmod a 43 w grub cfg 修改权限为所有可写 sudo pas
  • 小觅双目相机标准彩色版SDK的环境配置

    一 初用MYNTEYE双目相机标准彩色版 xff08 SC xff09 1 小觅相机目前标准版有三款 xff0c 详见 xff1a 小觅双目摄像头标准版系列参数比较 2 彩色工程版有以下7种分辨率可选 xff0c 数据输出格式为YUYV x
  • 小觅双目摄像头标准版系列产品参数比较

  • java for无限循环

    for无限循环的几个情况 判断条件为true 会无限循环 省略了判断条件 会无限循环 判断条件为true 会无限循环 package test010 public class Main nbsp nbsp nbsp public stati
  • 计数器与定时器有何区别

    计数器是当你开始从0开始计数时一直不停的开始记数 除非你让他停下来要不他会不停的记下去 而定时器则是不一样的 是需要你自己先设定一个时间然后开始倒计时 当你的所定时间倒计完以后 他就自动停止下来了 懂了吗 至于用哪个就要看你干什么而定了 8
  • C++基础知识

    1 面向对象的程序设计思想是什么 xff1f 答 xff1a 把数据结构和对数据结构进行操作的方法封装形成一个个的对象 2 什么是类 xff1f 答 xff1a 把一些 具有共性的对象归类后形成一个集合 xff0c 也就是所谓的类 3 对象
  • 【开关电源】降压变换器(BUCK)的断续模式建模

    1 前言 在DCDC变换器中BUCK变换器是最基础的一类降压型变换器 xff0c 它可以将输入电压降低后输出 在连续模式CCM下 xff0c 输出和输入之间的比值是D xff08 D为占空比 xff09 这种开关变换器是一种通过电子开关周期
  • 变量命名规范

    本文转载于https blog csdn net ZCF1002797280 article details 51495229 是我见过的描述最精炼 最好懂的命名文档 xff0c 故收藏转载推荐 1 驼峰命名法 1 1 小驼峰法 除第一个单
  • C++实现websocket服务器握手协议(使用Qt)

    前提 xff1a 笔者在开发server程序时 xff0c 要求websocket与server连接 websocket的机制是在第一次连接时进行握手协议 xff0c 协议通过 xff0c 才可以进行正常的通信 xff0c 否则websoc
  • 00011__ARM和STM32的区别

    https blog csdn net qq 34385566 article details 79668280
  • linux中查看系统资源占用情况的命令

    size 61 large top size 主要参数 d xff1a 指定更新的间隔 xff0c 以秒计算 q xff1a 没有任何延迟的更新 如果使用者有超级用户 xff0c 则top命令将会以最高的优先序执行 c xff1a 显示进程
  • 关于PendSV异常和SVC异常

    这里先说什么是异常 xff0c 什么是中断 xff1f 请下这张图 颜色加深的表项为异常 xff0c 这些属于cm3内核自带的 其中 3 xff0c 2 xff0c 1异常的优先级固定 xff0c 是不可更改的 xff0c 其余的异常中断优
  • FreeRTOS学习4-任务创建和删除

    关于任务创建有3个函数 1 动态创建一个任务 可以自动分配任务堆栈和TCB FreeRTOSConfig h中 xff0c 需要定义 define configSUPPORT DYNAMIC ALLOCATION 1 支持动态内存申请 Ba
  • java里 equals和== 区别

    1 java中equals和 61 61 的区别 值类型是存储在内存中的堆栈 xff08 简称栈 xff09 xff0c 而引用类型的变量在栈中仅仅是存储引用类型变量的地址 xff0c 而其本身则存储在堆中 2 61 61 操作比较的是两个
  • VRPTW建模与求解—基于粒子群算法

    VRPTW建模与求解 基于粒子群算法 1 VRPTW简要描述 VRPTW xff08 Vehicle Routing Problem with Time Windows xff09 是指在经典VRP的前提上 xff0c 给每个客户增添时间窗

随机推荐

  • 伽马分布,指数分布,泊松分布的关系 -转自简书

    原文链接 xff1a https www jianshu com p 6ee90ba47b4a 伽马分布 xff0c 指数分布 xff0c 泊松分布的关系 thinkando 关注 2018 09 25 21 13 字数 714 阅读 29
  • 双轴驱动步进电机云台二自由度单片机控制程序PTU57

    高精度云台由两个电机驱动 xff0c 可控制方位角和高度角 xff0c 具有两自由度的机械电子设备 可用于机器视觉 摄影摄像 监控安防 天文观测 雷达扫描 DIY雕刻机 转盘转台 智能机械手臂 双轴跟踪太阳能定日镜等各类应用高精度云台的场合
  • php使用curl获取需要认证的https请求

    lt php php使用curl获取需要认证的https请求的方法 url 61 34 XXXXXX 34 arr header 61 34 Accept application json 34 arr header 61 34 Autho
  • i-vector本质剖析

    1 i vector的由来 基于因子分析理论 xff0c 句子h的超向量可以描述成 其中为ubm模型的均值超向量 xff0c 即为i vector 2 i vector的计算 2 1 T矩阵的估计 为句子h的观察特征 xff0c 可以对应于
  • C++程序设计基础实验-实验七 多态性

    实验七多态性 一 实验目的 掌握运算符重载的方法 xff1b 掌握使用虚函数的继承实现动态多态性 掌握纯虚函数及抽象类的使用 二 实验内容 设计复数类Complex xff08 请参照教材例题8 1的设计 xff09 xff0c 实现运算符
  • g2o_a_general_framework_for_graph_optimaization

    g2o A General Framework for Graph Optimization NONLINEAR GRAPH OPTIMIZATION USING LEAST SQUARES 机器人和计算机视觉中的许多问题都可以用下列方程的
  • P5644 [PKUWC2018]猎人杀

    P5644 PKUWC2018 猎人杀 题目大意 一开始有 n n n 个猎人 xff0c 第 i i i 个猎人有仇恨度
  • 【Linux基础系列之】platform虚拟总线

    linux当中大多数的设备都是以paltform虚拟总线挂载上去的 xff0c 这里以kernel drivers net dm9000 c为例子分析一下 xff0c platform设备挂在过程 xff1b xff08 1 xff09 d
  • ARMv8-AArch64简述

    ARMv8是ARM版本升级以来最大的一次改变 xff0c ARMv8的架构继承以往ARMv7与之前处理器技术的基础 xff0c 除了现有的16 32bit的Thumb2指令支持外 xff0c 也向前兼容现有的A32 ARM 32bit 指令
  • ARMv8-AArch64寄存器和指令集

    xff08 一 xff09 简述 AArch拥有31个通用寄存器 xff0c 系统运行在64位状态下的时候名字叫Xn xff0c 运行在32位的时候就叫Wn xff1b AArch32与AArch64寄存器对应关系 xff1a xff08
  • ION框架学习(一)

    第一章介绍 xff1a ION的框架和buffer的分配 xff1b 第二章介绍 xff1a 如何使用ION buffer xff1b ION是google在Android4 0 为了解决内存碎片管理而引入的通用内存管理器 用来支持不同的内
  • 高通Camera 驱动调试要点(一)

    本文主要介绍QCOM camera调试的重要参数 xff1b xff08 1 xff09 Lane assign 和lane mask 现在摄像头基本都是mipi接口类型 xff0c 因为前后摄都对应到平台这边不同的mipi接口 xff0c
  • 高通Camera 驱动调试要点(二)

    这篇文章主要介绍数据流这边Camera ISP这块所遇到的问题 xff0c 主要介绍bus overflow和sof freeze xff1b xff08 一 xff09 bus overflow 摄像头传感器时钟通道 即 MIPI DDR
  • c/c++代码性能效率

    一 尽量减少值传递 xff0c 多用引用来传递参数 boolCompare xff08 span class hljs keyword string span s1 span class hljs keyword string span s
  • 6.Docker定制镜像

    当我们从docker镜像仓库中下载的镜像不能满足我们的需求时 xff0c 我们可以通过以下两种方式对镜像进行更改 1 从已经创建的容器中更新镜像 xff0c 并且提交这个镜像 2 使用 Dockerfile 指令来创建一个新的镜像 Dock
  • 全球最大成人网站公布年度榜单!原来lsp最爱看的是这种片……

    前几天 xff0c 那个号称全球最大的成人网站P hub xff0c 发布了 2022年度报告 别惊讶 xff0c 这已经是P某发布年度报告的第9个年头了 正所谓 xff0c 知己知彼百战不殆 不发年度报告 xff0c 怎么总结过去 xff
  • ROS学习篇(三)ROS系统的串口数据读取和解析(组合导航系统)

    一 Ubuntu下的串口助手cutecom 下载 xff1a sudo apt get install cutecom 打开 xff1a sudo cutecom 查看电脑链接的串口信息 xff08 名称 xff09 xff1a dmesg
  • VScode 结合clangd 构建linux源代码阅读环境

    1 背景介绍 上一篇文章 xff1a VScode 结合Global构建linux源代码阅读环境 xff0c 介绍了在VS Code工具中通过remote ssh远程登陆到Linux远程服务器 xff0c 使用Global构建linux源代
  • 信号量 PK 自旋锁

    信号量可能允许有多个持有者 xff0c 而自旋锁在任何时候只能允许一个持有者 xff0c 当然也有信号量叫互斥信号量 xff08 只能有一个持有者 xff09 xff0c 允许有多个持有者的信号量叫 计数信号量 信号量适合于保持时间较长的情
  • 【FreeRTOS】FreeRTOS 源码学习笔记 (4) 任务创建xTaskCreate + 常用结构体TCB、xLIST

    1 引言 经过第一节的移植 xff0c 我们已经拿到了一个可以用的工程 经过第二三节的基础知识 xff0c 我们对基本的数据结构 xff0c 列表 队列这些也有了一个了解 接下来就可以单步跟踪了 xff0c 看一下系统是怎么运行的 使用Fr