OSTaskCreate()

本文详细介绍了RTOS环境下使用OSTaskCreateExt()函数创建任务的过程。包括参数解析、任务堆栈初始化、任务控制块定义等关键步骤,并阐述了如何确保任务正确建立。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//建立一个新任务。与OSTaskCreate()不同的是,OSTaskCreateExt()允许用户设置更多的细节  
//内容。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立,但中断处理  
//程序中不能建立新任务。一个任务必须为无限循环结构,且不能有返回点。  
#if OS_TASK_CREATE_EXT_EN > 0                //允许生成OSTaskCreateExt()函数  
INT8U  OSTaskCreateExt (void   (*task)(void *pd),   //建立扩展任务(任务代码指针)  
                        void    *pdata,             //传递参数指针  
                        OS_STK  *ptos,              //分配任务堆栈栈顶指针  
                        INT8U    prio,              //分配任务优先级  
                        INT16U   id,                //(未来的)优先级标识(与优先级相同)  
                        OS_STK  *pbos,              //分配任务堆栈栈底指针  
                        INT32U   stk_size,          //指定堆栈的容量(检验用)  
                        void    *pext,              //指向用户附加的数据域的指针  
                        INT16U   opt)               //建立任务设定选项  
{  
#if OS_CRITICAL_METHOD == 3                  //中断函数被设定为模式3  
    OS_CPU_SR  cpu_sr;  
#endif  
    OS_STK    *psp;                         //初始化任务堆栈指针变量,返回新的栈顶指针  
    INT8U      err;                         //定义(获得定义初始化任务控制块)是否成功  
  
  
#if OS_ARG_CHK_EN > 0        //所有参数必须在指定的参数内  
    if (prio > OS_LOWEST_PRIO) {             //检查任务优先级是否合法  
        return (OS_PRIO_INVALID);            //参数指定的优先级大于OS_LOWEST_PRIO  
    }  
#endif  
    OS_ENTER_CRITICAL();        //关闭中断  
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0  
        OSTCBPrioTbl[prio] = (OS_TCB *)1;    //保留这个优先级,将就绪态设为0  
                                               
        OS_EXIT_CRITICAL();     //打开中断  
  
        //以下两为1堆栈才能清0  
        if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   //检验任务堆栈,CHK=1  
            ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   //任务建立时是否清0,CLR=1  
            #if OS_STK_GROWTH == 1          //堆栈生长方向  
            (void)memset(pbos, 0, stk_size * sizeof(OS_STK));       //从下向上递增  
            #else  
            (void)memset(ptos, 0, stk_size * sizeof(OS_STK));       //从下向下递减  
            #endif  
        }  
  
        psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt);      //初始化任务堆栈  
        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);     //获得并初始化任务控制块  
        if (err == OS_NO_ERR) { //任务控制初始化成功  
            OS_ENTER_CRITICAL();        //关闭中断  
            OSTaskCtr++;                //任务计数器加1  
            OS_EXIT_CRITICAL();         //打开中断  
            if (OSRunning == TRUE) {              //检查是否有(某个)任务在运行  
                OS_Sched();                       //任务调度,最高任务优先级运行  
            }  
        } else {        //否则,任务初始化失败  
            OS_ENTER_CRITICAL();        //关闭中断  
            OSTCBPrioTbl[prio] = (OS_TCB *)0;                 //放弃任务,设此任务就绪态为0  
            OS_EXIT_CRITICAL();         //打开中断  
        }  
        return (err);       //返回(获得并定义初始化任务控制块是否成功)  
    }  
    OS_EXIT_CRITICAL();     //打开中断  
    return (OS_PRIO_EXIST);     //具有该优先级的任务已经存在  
}  
#endif  

#include "includes.h" #include "stm32f10x_gpio.h" #include "xxGpio.h" //任务优先级 #define START_TASK_PRIO 3 //任务堆栈大小 #define START_STK_SIZE 128 //任务控制块 OS_TCB StartTaskTCB; //任务堆栈 CPU_STK START_TASK_STK[START_STK_SIZE]; //任务函数 void start_task(void *p_arg); #define LED0_PIN GPIO_Pin_1 // #define LED0_PORT GPIOA /* GPIOB */ #define LED0_ON() GPIO_SetLow(LED0_PORT, LED0_PIN); //0 #define LED0_OFF() GPIO_SetHigh(LED0_PORT, LED0_PIN); //0 #define LED1_PIN GPIO_Pin_2 // #define LED1_PORT GPIOA /* GPIOB */ #define LED1_ON() GPIO_SetLow(LED1_PORT, LED1_PIN); //0 #define LED1_OFF() GPIO_SetHigh(LED1_PORT, LED1_PIN); //0 #define LED2_PIN GPIO_Pin_3 // #define LED2_PORT GPIOA /* GPIOB */ #define LED2_ON() GPIO_SetLow(LED2_PORT, LED2_PIN); //0 #define LED2_OFF() GPIO_SetHigh(LED2_PORT, LED2_PIN); //0 GpioCfg_ts LED0_Cfg = { LED0_PORT, LED0_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED1_Cfg = { LED1_PORT, LED1_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED2_Cfg = { LED2_PORT, LED2_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; void LEDT_Init(void) { GPIO_Config( &LED0_Cfg ); GPIO_Config( &LED1_Cfg ); GPIO_Config( &LED2_Cfg ); } OS_Q DATA_Msg; //定义一个消息队列,用于发送数据 //主函数 int main(void) { OS_ERR err; CPU_SR_ALLOC(); LEDT_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 OSInit(&err); /* Init uC/OS-III. */ //创建开始任务 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); //存放该函数错误时的返 OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ } /****************************************************************************************** * * 实验(一) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(0) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_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); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_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); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } //task1任务函数 volatile uint32_t i; uint8_t LedStates = 1; void task1_task(void *p_arg) { OS_ERR err; uint8_t count = 10; while(1) { // 任务1正常运行时LED0闪烁 for(uint8_t count = 0; count < 5; count++) { LED0_ON(); for(i = 0; i < 200000; i++); // 简单延时 LED0_OFF(); for(i = 0; i < 200000; i++); // 简单延时 } // 挂起任务2(LED1将停止闪烁) OSTaskSuspend(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); // 延时2秒 // 唤醒任务2(LED1恢复闪烁) OSTaskResume(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_DLY, &err); // 延时3秒 // 删除任务2 OSTaskDel(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err); // 延时1秒 // 删除任务1自身 OSTaskDel((OS_TCB*)0, &err); } } //task2任务函数 void task2_task(void *p_arg) { volatile uint32_t i; while(1) { // LED1持续闪烁 LED1_ON(); for(i = 0; i < 200000; i++); // 简单延时 LED1_OFF(); for(i = 0; i < 200000; i++); // 简单延时 // 让出CPU时间 OSTimeDly(1, OS_OPT_TIME_DLY, NULL); } } #endif /****************************************************************************************** * * 实验(二) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(0) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //任务优先级 #define TASK3_TASK_PRIO 4 //任务堆栈大小 #define TASK3_STK_SIZE 128 //任务控制块 OS_TCB Task3_TaskTCB; //任务堆栈 CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE]; void task3_task(void *p_arg); // 信号量定义 OS_SEM SharedResourceSem; // 共享资源信号量 OS_SEM SyncSem; // 同步信号量 //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_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); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_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); //创建TASK3任务 OSTaskCreate((OS_TCB * )&Task3_TaskTCB, (CPU_CHAR * )"Task3 task", (OS_TASK_PTR )task3_task, (void * )0, (OS_PRIO )TASK3_TASK_PRIO, (CPU_STK * )&TASK3_TASK_STK[0], (CPU_STK_SIZE)TASK3_STK_SIZE/10, (CPU_STK_SIZE)TASK3_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); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } // 低优先级任务函数 void task1_task(void *p_arg) { OS_ERR err; while(1) { // 获取共享资源信号量(第一次信号量接收) OSSemPend(&SharedResourceSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 模拟处理共享资源(长时间操作) OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); // 延时2秒 // 发送同步信号量(第一次信号量发送) OSSemPost(&SyncSem, OS_OPT_POST_1, &err); // 释放共享资源信号量 OSSemPost(&SharedResourceSem, OS_OPT_POST_1, &err); OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_DLY, &err); // 延时5秒 } } // 中优先级任务函数 void task2_task(void *p_arg) { OS_ERR err; while(1) { // 执行不需要共享资源的操作 // 这个任务会抢占低优先级任务 OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err); // 延时1秒 } } // 高优先级任务函数 void task3_task(void *p_arg) { OS_ERR err; while(1) { // 等待同步信号量(第二次信号量接收) OSSemPend(&SyncSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 获取共享资源信号量(第二次信号量接收) OSSemPend(&SharedResourceSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 执行关键操作 // 这里应该快速完成... // 发送同步信号量(第二次信号量发送) OSSemPost(&SyncSem, OS_OPT_POST_1, &err); // 释放共享资源信号量 OSSemPost(&SharedResourceSem, OS_OPT_POST_1, &err); OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_DLY, &err); // 延时5秒 } } #endif /****************************************************************************************** * * 实验(二) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(1) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //任务优先级 #define TASK3_TASK_PRIO 4 //任务堆栈大小 #define TASK3_STK_SIZE 128 //任务控制块 OS_TCB Task3_TaskTCB; //任务堆栈 CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE]; void task3_task(void *p_arg); // 信号量定义 OS_SEM SharedResourceSem; // 共享资源信号量 OS_SEM SyncSem; // 同步信号量 //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_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); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_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); //创建TASK3任务 OSTaskCreate((OS_TCB * )&Task3_TaskTCB, (CPU_CHAR * )"Task3 task", (OS_TASK_PTR )task3_task, (void * )0, (OS_PRIO )TASK3_TASK_PRIO, (CPU_STK * )&TASK3_TASK_STK[0], (CPU_STK_SIZE)TASK3_STK_SIZE/10, (CPU_STK_SIZE)TASK3_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); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } #endif   帮我生成一个UCOSⅢ消息实验代码 任务要求:设计一个消息发送、接收例程,必须包含消息发送和接收,且接收消息后必须对消息长度和数据进行处理。共三个任务。
最新发布
06-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值