本文学习与程序编写基于 正点原子的 STM32F1 UCOS开发手册
编写熟悉一下 UCOSIII系统的 时间片轮转调度
文章提供测试代码讲解、完整工程下载、测试效果图
目录
解决上文的卡系统问题:
使能时间片轮转调度:
任务初始化定义更改:
文件结构提要:
任务函数文件:
任务块头文件 #include "Task_config.h" :
目前各个文件任务:
#include "main.h"
#include "ComTask.h"
#include "MessageTask.h"
#include "CalculateTask.h"
下载测试效果:
测试工程下载:
解决上文的卡系统问题:
上文讲到在MessageTask任务中使用打印函数会卡系统:
任务栈太小,导致卡系统,将原先的 128 改为 256 就解决了:
使能时间片轮转调度:
先确认 OS_CFG_SCHED_ROUND_ROBIN_EN 定义为 1
查看 OSCfg_TickRate_Hz 定义多大,这是系统时钟节拍频率:
本工程直接在Comtask启动时获取并打印一次:
然后调用函数初始化时间片轮转:
任务初始化定义更改:
这里先更改一下任务初始化的一些定义:
这步更改是设置每个任务的时间片:
修改这俩任务优先级相同:
文件结构提要:
这里赘述一些文件结构,本文不详细解释,在往前的文章有更详细介绍:
STM32F407ZGT6-UCOSIII笔记3:任务挂起与恢复实验-CSDN博客
任务函数文件:
工程包含一个TASK组,里面含有各个任务的实际函数体:
#include "ComTask.h"包含串口相关任务操作
#include "MessageTask.h" 包含信号灯状态等 对外释放信号安排的 相关操作
#include "CalculateTask.h" 包含数据计算任务
任务块头文件 #include "Task_config.h" :
这是为了方便 任意其他任务 对 任意任务进行 删除 挂起 恢复 等操作而编写的,
因为每个任务都写在自己的任务文件中,对任务块名称引用需要有专门文件来提供通道
不这么编写就没法有这个实现......
目前各个文件任务:
#include "main.h"
创建开始任务初始化每个基本任务:
#include "main.h" void start_task(void *p_arg);//开始任务函数 int main(void) { OS_ERR err; CPU_SR_ALLOC(); Init_ALL(); OSInit(&err); //初始化UCOSIII OS_CRITICAL_ENTER();//进入临界区 //创建开始任务 OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块 (CPU_CHAR * )"start task", //任务名字 (OS_TASK_PTR )start_task, //任务函数 (void * )0, //传递给任务函数的参数 (OS_PRIO )START_TASK_PRIO, //任务优先级 (CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位 (CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小 (OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 (OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度, (void * )0, //用户补充的存储区 (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项 (OS_ERR * )&err); //存放该函数错误时的返回值 OS_CRITICAL_EXIT(); //退出临界区 OSStart(&err); //开启UCOSIII while(1); } //开始任务函数 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 //创建ComTask任务 OSTaskCreate((OS_TCB * )&COMTASKTaskTCB, (CPU_CHAR * )"com task", (OS_TASK_PTR )comTask, (void * )0, (OS_PRIO )COMTASK_TASK_PRIO, (CPU_STK * )&COMTASK_TASK_STK[0], (CPU_STK_SIZE)COMTASK_STK_SIZE/10, (CPU_STK_SIZE)COMTASK_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )2, //之前为0 //2个时间片 2*5ms (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建MessageTask任务 OSTaskCreate((OS_TCB * )&MessageTaskTaskTCB, (CPU_CHAR * )"Message task", (OS_TASK_PTR )MessageTask, (void * )0, (OS_PRIO )MessageTask_TASK_PRIO, (CPU_STK * )&MessageTask_TASK_STK[0], (CPU_STK_SIZE)MessageTask_STK_SIZE/10, (CPU_STK_SIZE)MessageTask_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )2, //之前为0 //2个时间片 2*5ms (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建CalculateTask任务 OSTaskCreate((OS_TCB * )&CalculateTaskTaskTCB, (CPU_CHAR * )"Calculate task", (OS_TASK_PTR )CalculateTask, (void * )0, (OS_PRIO )CalculateTask_TASK_PRIO, (CPU_STK * )&CalculateTask_TASK_STK[0], (CPU_STK_SIZE)CalculateTask_STK_SIZE/10, (CPU_STK_SIZE)CalculateTask_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区 }
#include "ComTask.h"
#include "ComTask.h" /* ComTask 删除CalculateTask ComTask 打印自己运行次数 打印俩次 ComTask 后等待800ms */ void comTask(void * p_arg) { OS_ERR err; int i=0,OSTime_tickRate,j; p_arg = p_arg; OSTime_tickRate=OSCfg_TickRate_Hz; //获取系统节拍频率,(该宏定义在 OS_CFG_APP.H) UsartPrintf(USART1, "OSCfg_TickRate_Hz = %d Hz \r\n",OSTime_tickRate); //打印系统节拍频率 OSTaskDel((OS_TCB*)&CalculateTaskTaskTCB,&err); //删除CalculateTask UsartPrintf(USART1, "ComTask delete CalculateTask !\r\n"); //打印删除 CalculateTask 提示 while (DEF_TRUE) { i++; UsartPrintf(USART1, "ComTask Print%d\r\n",i); for(j=0;j<2;j++) { UsartPrintf(USART1, "ComTask \r\n"); } OSTimeDlyHMSM(0,0,0,800,OS_OPT_TIME_HMSM_STRICT,&err); //延时800ms } }
#include "MessageTask.h"
#include "MessageTask.h" /* MessageTask 打印自己运行次数 打印俩次 MessageTask 后等待800ms */ void MessageTask (void * p_arg) { OS_ERR err; int i=0,j; p_arg = p_arg; while (DEF_TRUE) { i++; UsartPrintf(USART1, "MessageTask Print%d\r\n",i); //之前这里会卡系统,因为任务栈太小 MessageTask_STK_SIZE 128,现改为256 for(j=0;j<2;j++) { UsartPrintf(USART1, "MessageTask \r\n"); } OSTimeDlyHMSM(0,0,0,800,OS_OPT_TIME_HMSM_STRICT,&err); //延时800ms } }
#include "CalculateTask.h"
本文CalculateTask一开始就被ComTask删了就不贴了
下载测试效果:
俩个同优先级 任务能够正常进行运行打印:
测试工程下载:
https://download.csdn.net/download/qq_64257614/90139426