freertos笔记-任务基本构造

news/2024/10/29 22:05:04/

红叶何时落水

每个任务都有他特有的属性,这些属性记录着当前任务的状态
相当于新建一个任务对象 对象类为TCB_t/tskTCB动态创建
 

typedef struct tskTaskControlBlock
{volatile StackType_t    *pxTopOfStack;//指向该任务堆栈的最后一项 pxTopOfStack为堆栈栈顶指针 32位    ListItem_t            xStateListItem;//定义一个链表 项 ,这个项有着必要的信息  状态链表项 用来记录该任务的状态,是挂起还是就绪ListItem_t            xEventListItem;//事件列表项    用于记录自己是否处于延时列表中    UBaseType_t            uxPriority;    //任务优先级 运行过程中要被识别的优先级 可以被优先级继承机制改变        StackType_t            *pxStack;//任务堆栈起始地址 分配的堆栈的起始地址            char                pcTaskName[ configMAX_TASK_NAME_LEN ];//任务名字 没啥用#if ( configUSE_MUTEXES == 1 )UBaseType_t        uxBasePriority;//任务基础优先级,优先级反转的时候用到,就是说他初始化的那个优先级                UBaseType_t        uxMutexesHeld;//任务获取到的互斥信号量个数#endif#if( configUSE_TASK_NOTIFICATIONS == 1 )        volatile uint32_t ulNotifiedValue;//任务通知值        volatile uint8_t ucNotifyState;//任务状态    用于任务通知操作#endif
} tskTCB;
这个是上面含有的链表 项  的定义
struct xLIST_ITEM
{configLIST_VOLATILE TickType_t xItemValue;            /*< 列表项的值,降序排列 */struct xLIST_ITEM * configLIST_VOLATILE pxNext;        /*< 链表连接 */struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;    /*< 双向链表 */void * pvOwner;                                        /*<指向那个任务对象TCB_t 中的变量xStateListItem的pvOwner指向TCB,当任务处于就绪态时,pvContainer指向就绪列表其余状态,同理 */ void * configLIST_VOLATILE pvContainer;                /*<指向列表项所属的列表 */
};typedef struct xLIST_ITEM ListItem_t;    


创建一个新任务

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //任务函数 这里是一个指针常量,表示函数地址const char * const pcName, //任务名 没啥用const uint16_t usStackDepth, //堆栈大小 单位是字而非字节 不包括TCBvoid * const pvParameters, //任务函数的参数,指针类型,建议结构体传参UBaseType_t uxPriority, //优先级TaskHandle_t * const pxCreatedTask )//句柄 其实就是任务堆栈


删除任务
vTaskDelete();//删除任务,并在空闲任务中释放空间(堆栈以及TCB的空间)TCB空间如果是动态创建任务的话,就是自动分配自动回收,如果是静态创建,就需要初始化一下,而且必须是初始化StaticTask_t该结构体,而不是值初始化一个结构体指针

将该任务挂起,只有调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()才会恢复该任务,其他的队列,任务通知,delay都不能将其唤醒
xTaskToSuspend(句柄);句柄为NULL时挂起自己 可以通过函数 xTaskGetHandle()来根据任务名字
xTaskResumeFromISR();//中断中调用这类函数,必须检查一下中断结束后的任务与进入中断时的任务是不是同一个,如果不是,就要进行上下文切换,就是改变PSP的指向

YieldRequired=xTaskResumeFromISR(Task2Task_Handler);//恢复任务 2
if(YieldRequired==pdTRUE)
{/*如果函数 xTaskResumeFromISR()返回值为 pdTRUE,那么说明要恢复的这个任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),所以在退出中断的时候一定要进行上下文切换!*/portYIELD_FROM_ISR(YieldRequired);
}

删除任务
vTaskDelete();
1. 先获取要删除任务的句柄 参数为NULL,就获取调用该任务的句柄 prvGetTCBFromHandle()
    #define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) )
2. 从就绪列表中删除该任务
3. 列表优先级切换

    #define taskRESET_READY_PRIORITY( uxPriority )                                                        \{                                                                                                    \if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 )    \//判断这个优先级列表里的任务还有没有,如果这个优先级的列表里没有了任务,就执行下面的语句{                                                                                                \portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );                            \//重置优先级}                                                                                                \}


4. 检查是否处于延迟列表中,是的话,从延时列表中删掉
5. 如果要删除的任务正在运行,就将其添加到xTasksWaitingTermination列表中,然后由空闲任务释放其空间
   ++uxDeletedTasksWaitingCleanUp;表示有多少个任务要被清理
6. 如果要删除的任务没有在运行 prvDeleteTCB() 释放空间 并--uxCurrentNumberOfTasks;表示当前可运行任务数减一

   prvResetNextTaskUnblockTime();重新计算下一个任务解锁的时间static void prvResetNextTaskUnblockTime( void ){TCB_t *pxTCB;if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ){xNextTaskUnblockTime = portMAX_DELAY;}else{( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );//获取列表中的第一个任务xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) );//延时时间等于任务结构体里的value值,升序排列,value值越大,排的越后面,延时越长}}


7. 如果要删除的任务正在运行,切换上下文


任务挂起
vTaskSuspend() 不能重复挂起,就是说,只要调用恢复API就会被解除悬挂
1. 获取要挂起任务的句柄
2. 就绪,延时列表中移除该任务,并判断当前优先级 它会使xdelay失效,那就意味着接触悬挂,立马加入就绪状态
3. 插入挂起列表 vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
4. prvResetNextTaskUnblockTime();
5. 如果该任务正在运行,切换上下文 portYIELD_WITHIN_API();
6. 如果调度器不工作,那么手动切换当前任务指针 vTaskSwitchContext();

恢复被挂起的任务
 

vTaskResume()
{TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume; if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) {taskENTER_CRITICAL(); {if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) {( void ) uxListRemove( &( pxTCB->xStateListItem ) ); prvAddTaskToReadyList( pxTCB );if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) {taskYIELD_IF_USING_PREEMPTION();}}}taskEXIT_CRITICAL(); }
}


 


http://www.ppmy.cn/news/132985.html

相关文章

win7系统下连网络打印机打印反应很慢解决方法

删除之前网络添加的打印机&#xff0c; 重现安一下方法添加即可&#xff1a; 开始添加打印机了&#xff0c;打开控制面板里的设备和打印机&#xff0c;然后选择添加打印机&#xff1a; 在打开的窗口里选择添加本地打印机&#xff0c;然后点下一步&#xff1a; 在打开的选择打印…

DAY04_JDBC快速入门JDBC API详解SQL防注入数据库连接池JDBC综合练习

目录 1 JDBC1.1 JDBC概念1.2 JDBC本质 1.3 JDBC好处 2 JDBC快速入门2.1 编写代码步骤2.2 具体操作 3 JDBC API详解3.1 DriverManager3.2 Connection3.2.1 获取执行对象3.2.2 事务管理 3.3 Statement3.4 ResultSet3.4.1 ResultSet案例 3.5 PreparedStatement3.5.1 SQL注入3.5.2 …

计算机识别不了佳能打印机,佳能打印机不能打印如何解决 佳能打印机不能打印解决方法【介绍】...

一些企业和学校购买的打印机品牌基本上都是佳能的&#xff0c;由于佳能打印机使用比较频繁&#xff0c;所以经常会出现这样那样的问题。可是佳能打印机不能打印怎么办呢&#xff1f;用户要如何解决这种问题&#xff0c;此时用户要检查一下开关电源是否通电&#xff0c;检查驱动…

佳能LBP2900打印机无法正常打印.用32位驱动安装正常

SourceURL:file:///home/zttz/桌面/32Debian/32成功 下载地址&#xff1a; 佳能&#xff08;中国&#xff09; - 服务与支持 下载解压文件&#xff1a; 1.进入LBP2900文件夹下 /佳能LBP2900/32-bit_Driver/Debian 2.sudo dpkg -i cndrvcups-common_3.21-1_i386.deb 如…

spoolsv.exe 报错,无法打印

spoolsv.exe 报错,无法打印 在使用打印机过程中突然出现spoolsv.exe应用程序错误,内存不能written•••,检查打印驱动,打印机设置选项无法打开。怀疑是病毒所致,升级杀毒软件后安全模式下杀毒后没有发现病毒,重启后还是不行,并且开机时出现打印服务错误。我运行msconfi…

linux下mysql的配置,Linux下Mysql配置()

摘要 腾兴网为您分享:Linux下Mysql配置()&#xff0c;智慧医疗&#xff0c;小太阳&#xff0c;享家&#xff0c;相机美颜等软件知识&#xff0c;以及重庆地税12366&#xff0c;正常的小学上课时间表&#xff0c;移动云信&#xff0c;dnf幸运冒险家&#xff0c;八爪龙演播大师&a…

统信 UOS 连接 Windows 共享打印机

系统是统信 UOS 家庭版。由于 VMWare 虚拟机直接连接打印机&#xff0c;主机会蓝屏&#xff0c;所以这里改为采用连接 Windows 共享的打印机来测试 UOS 的系统打印功能。 在 Windows 配置打印机共享 在 Windows 系统的“启用或关闭 Windows 功能”开启 LPD 功能。点击开始按钮…

ubuntun8.04安装Canon LBP2900打印机

参考链接&#xff1a; http://pleasure.javaeye.com/?page4&show_fulltrue https://help.ubuntu.com/community/HardwareSupportComponentsPrinters/CanonPrinters/Canon_LBP_2900 步骤&#xff1a; 1、下载驱动程序 http://software.canon-europe.com/index.asp &a…