freertos 源码分析四 任务创建的简单分析
任务创建xTaskCreate
为TCB和TCB栈分配空间, 初始化,加入就绪任务链表
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )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 ){ TCB_t * pxNewTCB;BaseType_t xReturn;#if ( portSTACK_GROWTH > 0 ){pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ){memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); if( pxNewTCB->pxStack == NULL ){vPortFree( pxNewTCB );pxNewTCB = NULL;}}}#else{StackType_t * pxStack;pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );if( pxStack != NULL ){pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ){memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) );pxNewTCB->pxStack = pxStack;}else{vPortFreeStack( pxStack );}}else{pxNewTCB = NULL;}}#endifif( pxNewTCB != NULL ){#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ){pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;}#endifprvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );prvAddNewTaskToReadyList( pxNewTCB );xReturn = pdPASS;}else{xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;}return xReturn;}
#endif
TCB初始化
设置栈顶栈底,任务名,优先级,初始化及填充状态消息表项。
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,const char * const pcName,const uint32_t ulStackDepth, void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask,TCB_t * pxNewTCB,const MemoryRegion_t * const xRegions )
{StackType_t * pxTopOfStack;UBaseType_t x;#if ( portSTACK_GROWTH < 0 ){pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] );pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );#if ( configRECORD_STACK_HIGH_ADDRESS == 1 ){pxNewTCB->pxEndOfStack = pxTopOfStack;}#endif}#else{pxTopOfStack = pxNewTCB->pxStack;configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 );}#endifif( pcName != NULL ){for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ){pxNewTCB->pcTaskName[ x ] = pcName[ x ];if( pcName[ x ] == ( char ) 0x00 ){break;}}pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';}configASSERT( uxPriority < configMAX_PRIORITIES );if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) {uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;}pxNewTCB->uxPriority = uxPriority;#if ( configUSE_MUTEXES == 1 ){pxNewTCB->uxBasePriority = uxPriority;}#endifvListInitialiseItem( &( pxNewTCB->xStateListItem ) );vListInitialiseItem( &( pxNewTCB->xEventListItem ) );listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority );listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );if( pxCreatedTask != NULL ){*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;}}
加入就绪态链表 禁中断 任务数加一,设为当前,开中断
static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
{taskENTER_CRITICAL(); {uxCurrentNumberOfTasks++;if( pxCurrentTCB == NULL ){pxCurrentTCB = pxNewTCB;if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ){prvInitialiseTaskLists();}}else{if( xSchedulerRunning == pdFALSE ){if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ){pxCurrentTCB = pxNewTCB;}}}uxTaskNumber++;prvAddTaskToReadyList( pxNewTCB );}taskEXIT_CRITICAL();if( xSchedulerRunning != pdFALSE ){if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ){taskYIELD_IF_USING_PREEMPTION();}}
}
若是uxCurrentNumberOfTasks 为1,即第一个任务,初始化各链表
static void prvInitialiseTaskLists( void )
{UBaseType_t uxPriority;for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ){vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );}vListInitialise( &xDelayedTaskList1 );vListInitialise( &xDelayedTaskList2 );vListInitialise( &xPendingReadyList );#if ( INCLUDE_vTaskDelete == 1 ){vListInitialise( &xTasksWaitingTermination );}#endif#if ( INCLUDE_vTaskSuspend == 1 ){vListInitialise( &xSuspendedTaskList );}#endifpxDelayedTaskList = &xDelayedTaskList1;pxOverflowDelayedTaskList = &xDelayedTaskList2;
}
prvAddTaskToReadyList宏定义
#define prvAddTaskToReadyList( pxTCB ) \traceMOVED_TASK_TO_READY_STATE( pxTCB ); \taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
记录最高优先级
#define taskRECORD_READY_PRIORITY( uxPriority ) \
{ \if( ( uxPriority ) > uxTopReadyPriority ) \{ \uxTopReadyPriority = ( uxPriority ); \} \
}
listINSERT_END 加入链表
taskYIELD_IF_USING_PREEMPTION 定义
#if ( configUSE_PREEMPTION == 0 )#define taskYIELD_IF_USING_PREEMPTION()
#else#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
#endif#ifndef portYIELD_WITHIN_API#define portYIELD_WITHIN_API portYIELD
#endif
stm32对应portYIELD 定义 适配不同定义不同
#define portYIELD()|| | | | __asm volatile ( "SWI 0" )
相关文章:
freertos 源码分析四 任务创建的简单分析
任务创建xTaskCreate 为TCB和TCB栈分配空间, 初始化,加入就绪任务链表 #if ( configSUPPORT_DYNAMIC_ALLOCATION 1 )BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void *…...
二叉树的锯齿形遍历,力扣
目录 题目: 我们直接看题解吧: 快速理解解题思路小建议: 解题方法: 相似题目对比分析: 解题分析: 解题思路: 补充说明: 思路优化: 代码实现(层序遍历倒序): 题…...
避免Arrays.asList陷阱:优雅处理结构性修改的方法
临近年终,项目交付排期比较紧张,导致很多时候,Code Review 往往是走马观花,没有严格执行。最近,一个实习生就产生了一个十分低级的代码BUG。笔者感觉这个问题,对于实习生,尤其是刚入职的 应届 J…...
微信小程序(三十六)事件传参
注释很详细,直接上代码 上一篇 新增内容: 1.传参步骤 2.传参接收解构步骤 源码: index.wxml <button type"primary" bind:tap"onclick" mark:index"{{0}}" mark:remb"{{1}}" class"But&quo…...
编译原理与技术(三)——语法分析(二)自顶向下-递归下降
一、语法分析的两种方法 自顶向下(Top-down): 针对输入串,从文法的开始符号出发,尝试根据产生式规则推导(derive)出该输入串。 从根部开始构造语法树。 自底向上(Bottom-up&#…...
okhttp 的 拦截器
拦截器有很多作用,实现就是责任链模式,细节,等我有时间补上。 后面有时间更新一下。 OkHttp最核心的工作是在 getResponseWithInterceptorChain() 中进行,在进入这个方法分析之前,我们先来了 解什么是责任链模式&…...
Android:多线程下载网络图片
3.12 网络图片操作 1、通过URL请求获取网络图片 示例: 创建t_picture.xml,页面layout布局文件,一个Button按钮和一个ImageView容器显示图片。 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.a…...
跟着GPT学设计模式之原型模式
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(或者叫拷贝)的方式来创建新对象&a…...
博客|基于Springboot的个人博客系统设计与实现(源码+数据库+文档)
个人博客系统目录 目录 基于Springboot的个人博客系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 (1)用户管理 (2)文章分类管理 (3)公告信息管理 (4&#…...
【gcc】webrtc发送侧计算 丢包率
大神的分析 : 提到: 每当收到cc-feedback或者收到RR-report的时候就能统计出丢包率,在cc-controller中就会调用SendSideBandwidthEstimation::UpdatePacketsLost()去更新丢包率,同时进行码率预估 G:\CDN\rtcCli\m98\src\modules\congestion_controller\goog_cc\send_side_b…...
elementui上传文件不允许重名
需求: 用户可以多文件上传 ,在上传到服务器之前需要检查服务器中有无重名的文件,如果有会返回重名文件的名称数组,这些文件需要一个一个的向用户确认是否要覆盖重传。确认完毕后再上传到服务器。 检查文件重名: //上传…...
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Video媒体组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Video媒体组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Video媒体组件 用于播放视频文件并控制其播放状态的组件。 子组件 无 接口…...
Linux操作系统运维-Docker的基础知识梳理总结
Linux操作系统运维-Docker的基础知识梳理总结 docker用来解决不同开发人员软件调试时环境不统一的问题,保证了程序调试时运行环境的一致性。docker的设计理念便是一处镜像,处处运行,即通过产生用户软件,运行环境及其运行配置的统一…...
PMP考试成绩如何查询?
PMP考试成绩已经陆续出来了,出成绩时间大概一周左右,没收到的别着急,先把如何查询成绩路径弄清楚。 【如何查询成绩】 1、输入网址(PMI官网,不知道网址的私戳),点击 Log In 如果忘记 PMI 的账…...
【Scala】 2. 函数
2. 函数 scala运算符、if … else …两部分和C语言类型,这里不再赘述,这里从for循环开始讲讲scala和c/c的不同之处。 2.1 for循环 scala中主要包含to和until两个关键字,下面分别看看两者的用法,看例子就行了。 (1) to的用法 …...
14.0 Zookeeper环球锁实现原理
全局锁是控制全局系统之间同步访问共享资源的一种方式。 下面介绍zookeeper如何实现全民锁,讲解他锁和共享锁两类全民锁。 排他锁 排他锁(Exclusive Locks),又被称为写锁或独占锁,如果事务T1对数据对象O1加上排他锁…...
课时16:本地变量_普通变量
2.2.2 普通变量 学习目标 这一节,我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 变量分类 所谓的本地变量就是:在当前系统的某个环境下才能生效的变量,作用范围小。本地变量按照变量值的生成方式包含两种:普通…...
阿里云服务器centos_7_9_x64位,3台,搭建k8s集群
目录 1.环境信息 2.搭建过程 2.1 安装Docker源 2.2 安装Docker 2.3 安装kubeadm,kubelet和kubectl 2.4 部署Kubernetes Master(node1) 2.5 安装Pod网络插件(CNI) 2.6 加入Kubernetes Node 2.7 测试kubernetes集群 3.部署 Dashboard…...
代码随想录第二十八天
第七章 回溯算法part04 ● 93.复原IP地址 ● 78.子集 ● 90.子集II 详细布置 93.复原IP地址 本期本来是很有难度的,不过 大家做完 分割回文串 之后,本题就容易很多了 题目链接/文章讲解:https://programmercarl.com/0093.%E5…...
【python】绘制爱心图案
以下是一个简单的Python代码示例,它使用turtle模块绘制一个代表爱和情人节的心形图案。 首先,请确保计算机上安装了Python和turtle模块。然后,将以下代码保存到一个.py文件中,运行它就可以看到爱心图案的绘制过程。 import turt…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
