- 简述:
- 多任务操作系统核心是对任务的管理,包括:任务创建、挂起、删除、调度和切换等
- 任务的基本概念:
- uC/OS是一个支持多任务的操作系统
- 每个任务独立运行,可共享同一个优先级
- 任务越多,堆栈空间越大,每个任务的堆栈空间各自独立
- 一个系统能运行多少任务,取决于硬件有多少RMA
- 高优先级任务可以打断低优先级任务
- 任务间用IPC实现任务之间的通信
- 删除任务函数可以将某一任务删除
- 任务调度器的基本概念:
- uC/OS中提供的任务调度器是基于优先级的全抢占式
- 优先级数值越大的任务,优先级越低
- (空闲任务)最低优先级= OS_CFG_PRIO_MAX - 1u
- 优先级查找的过程决定了调度时间是否具有确定性
- 查找优先级方法:
- 前导零指定:依拖于硬件
- 位图查表法:C语言模仿前导零指令(空间换时间)
- 相同优先级的调度:时间片轮转(分时调度器),只在当前系统中无更高优先级有效
- 调度原则:
- 一旦任务状态发生改变
- 并且当前运行任务优先级小于优先级队列中任务最高优先级时
- 立刻进行任务切换
- 任务的几种状态
- 任务状态迁移图:
- 就绪:
- 延时:
- 等待:
- 运行:
- 挂起:
- 延时+挂起:
- 等待+挂起:
- 超时等待+挂起:
- 删除:
- 任务状态迁移图:
- 常用任务函数解析:
- 任务挂起函数OS_TaskSuspend();
- 宏定义OS_CFG_TASK_SUSPEND_EN必须使能
- 不能挂起空闲任务
- 任务挂起只是将任务进入挂起态,其内部资源保留,
- 同时不会参与任务的调度,调用恢复函数,整个任务立即从挂起态进入就绪态
- 任务恢复函数OSTaskResume();
- 有挂起就有恢复
- 恢复任务就是让挂起的任务重新进入就绪状态
- 需要使能OS_CFG_TASK_SUSPEND_EN
- 删除任务函数OSTaskDel();
- 需要使能OS_CFG_TASK_DEL_EN
- 删除的任务将从所有就绪、阻塞、挂起和事件列表中删除
- 恢复删除的任务只能重新创建
- 删除的任务不会释放堆栈空间
- 延时函数OSTimeDly();
- 停止当前任务的运行,等待延时一段时间后再运行
- 延时函数OSTimeDlyHMSM();
- 与上述延时功能相同,用于停止当前任务的运行,等待延时一段时间后再运行
- 此函数更加直观,可以精确到延时多少个小时、分、秒、毫秒;
- 需要使能OS_CFG_TIME_DLY_HMSM_EN
- 任务挂起函数OS_TaskSuspend();
- 任务设计要点:
- 任务运行的上、下文环境
- 中断服务函数:中断服务程序最好保持精简短小、快进快出,只做标记事件的发生
- 普通任务:优先级的处理,保证紧急任务的优先级更高
- 空闲任务:不允许出现阻塞情况
- 任务的执行时间
- 任务从开始到结束的时间
- 任务的周期
- 任务的时间,处理时间更短的任务优先级应该设置更高一些
- 任务运行的上、下文环境
- 例程
-
/**************** (C) COPYRIGHT SPT ************* * 文件名 :main.c * 芯片 :STM32F767IGT6 * 开发工具 :MDK V5.25 * HAL版本 :STM32Cube_FW_F7_V1.4.0 * uC/OSIII版本:UCOSIII 3.04 * 作者 :spt * 时间 :2020-04-22 * 联系方式 : * 功能简述 : *************************************************/ #include "includes.h" #include "bsp.h" /* ********************************************************************************************************* * 任务控制块TCB ********************************************************************************************************* */ static OS_TCB AppTaskStartTCB; //起始任务控制块 static OS_TCB AppTaskLedTCB; //led任务控制块 static OS_TCB AppTaskUsartTCB; //串口任务控制块 /* ********************************************************************************************************* * 任务堆栈 ********************************************************************************************************* */ static CPU_STK AppTaskStartStk[APP_TASK_START_STK_SIZE]; //起始任务堆栈大小 static CPU_STK AppTaskLedStk[APP_TASK_LED_STK_SIZE]; //led任务堆栈大小 static CPU_STK AppTaskUsartStk[APP_TASK_USART_STK_SIZE]; //串口任务堆栈大小 /* ********************************************************************************************************* * 函数原型 ********************************************************************************************************* */ static void AppTaskStart(void *p_arg); //起始任务函数 static void AppTaskLed(void *p_arg); //led任务函数 static void AppTaskUsart(void *p_arg); //串口任务函数 /************************************************** * 函数名:main() * 描述 :主函数入口 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ int main(void) { OS_ERR err; CPU_IntDis(); //关闭所有中断 OSInit(&err); //系统初始化 /* 创建起始任务 */ OSTaskCreate((OS_TCB *)&AppTaskStartTCB, //任务控制块地址 (CPU_CHAR *)"App Task Start", //任务名称 (OS_TASK_PTR ) AppTaskStart, //任务函数 (void *) 0, //传递给任务函数(形参p_arg)的实参 (OS_PRIO ) APP_TASK_START_PRIO, //任务的优先级 (CPU_STK *)&AppTaskStartStk[0], //任务堆栈的基地址 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10, //任务堆栈空间剩下1/10时限制其增长 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE, //任务堆栈空间(单位:sizeof(CPU_STK)) (OS_MSG_QTY ) 5u, //任务可接收的最大消息数 (OS_TICK ) 0u, //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10) (void *) 0, //任务扩展(0表不扩展) (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项 (OS_ERR *)&err); OSStart(&err); } /************************************************** * 函数名:static void AppTaskStart (void *p_arg) * 描述 :起始任务 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskStart (void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); /* Initialize the uC/CPU services */ //初始化滴答计数器 cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq /* Determine nbr SysTick increments */ / (CPU_INT32U)OSCfg_TickRate_Hz; OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ //内存管理,堆内存池,内存池表 Mem_Init(); /* Initialize memory managment module */ // Math_Init(); /* Initialize mathematical module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN CPU_IntDisMeasMaxCurReset(); #endif /* 创建led任务 */ OSTaskCreate((OS_TCB *) &AppTaskLedTCB, //任务控制块地址 (CPU_CHAR *) "App Task Led", //任务名称 (OS_TASK_PTR ) AppTaskLed, //任务函数 (void *) 0, //传递给任务函数(形参p_arg)的实参 (OS_PRIO ) APP_TASK_LED_PRIO, //任务的优先级 (CPU_STK *) &AppTaskLedStk[0], //任务堆栈的基地址 (CPU_STK_SIZE) APP_TASK_LED_STK_SIZE / 10, //任务堆栈空间剩下1/10时限制其增长 (CPU_STK_SIZE) APP_TASK_LED_STK_SIZE, //任务堆栈空间(单位:sizeof(CPU_STK)) (OS_MSG_QTY ) 5u, //任务可接收的最大消息数 (OS_TICK ) 0u, //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10) (void *) 0, //任务扩展(0表不扩展) (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项 (OS_ERR *)&err); /* 创建串口任务 */ OSTaskCreate((OS_TCB *) &AppTaskUsartTCB, //任务控制块地址 (CPU_CHAR *) "App Task Usart", //任务名称 (OS_TASK_PTR ) AppTaskUsart, //任务函数 (void *) 0, //传递给任务函数(形参p_arg)的实参 (OS_PRIO ) APP_TASK_USART_PRIO, //任务的优先级 (CPU_STK *) &AppTaskUsartStk[0], //任务堆栈的基地址 (CPU_STK_SIZE) APP_TASK_USART_STK_SIZE / 10, //任务堆栈空间剩下1/10时限制其增长 (CPU_STK_SIZE) APP_TASK_USART_STK_SIZE, //任务堆栈空间(单位:sizeof(CPU_STK)) (OS_MSG_QTY ) 5u, //任务可接收的最大消息数 (OS_TICK ) 0u, //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10) (void *) 0, //任务扩展(0表不扩展) (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项 (OS_ERR *)&err); OSTaskDel(&AppTaskStartTCB, &err); //删除起始任务 } /* ********************************************************************************************************* * 任务函数实现 ********************************************************************************************************* */ /************************************************** * 函数名:static void AppTaskLed(void *p_arg) * 描述 :led应用 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskLed(void *p_arg) { OS_ERR err; OS_REG value; (void)p_arg; for(;;) { value = OSTaskRegGet(0, 0, &err); //获取自身任务寄存器值 if(value < 10) { OSTaskRegSet(0, 0, ++value, &err); //继续累加任务寄存器值 } else { OSTaskRegSet(0, 0, 0, &err); //将任务寄存器值归0 OSTaskResume(&AppTaskUsartTCB, &err); //恢复串口任务 } HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); //PB1置1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); //PB0置1 OSTimeDly ( 500,OS_OPT_TIME_DLY,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); //PB1置0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //PB0置0 OSTimeDly ( 500,OS_OPT_TIME_DLY,&err); } } /************************************************** * 函数名:static void AppTaskUsart(void *p_arg) * 描述 :串口打印 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskUsart(void *p_arg) { OS_ERR err; OS_REG value; (void)p_arg; for(;;) { value = OSTaskRegGet(0, 0, &err); //获取自身任务寄存器值 if(value < 5) { OSTaskRegSet(0, 0, ++value, &err); } else { OSTaskRegSet(0, 0, 0, &err); OSTaskSuspend(0, &err); //0表挂起自身 } printf("灯亮了\r\n"); OSTimeDly ( 500,OS_OPT_TIME_DLY,&err); printf("灯灭了\r\n"); OSTimeDly ( 500,OS_OPT_TIME_DLY,&err); } } /************************ (C) COPYRIGHT SPT END OF FILE***********************/
-
- 下载验证
- 总结
- 任务的迁移状态、常用任务函数、延时函数;
- 参考资料:
- 正点原子《STM32F767 UCOS开发手册》
- 野火《uC/OS-III内核应用与开发》
- 《嵌入式实时操作系统 uC/OS-III原理及应用(第二版)》
- 官方源码
- 硬件平台:
- 正点原子阿波罗F767
- 软件平台:
- MDK5.2.5
- 库版本:
- TM32Cube_FW_F7_V1.4.0
- uC/OS-III版本
- UCOSIII 3.04
【3】uC/OS-III应用开发————>任务管理(STM32F767)
最新推荐文章于 2022-11-07 20:39:33 发布