uC/OS创建任务有几个硬性要求
1. 任务必须被创建在多任务开始之前或者是运行的任务中。
2. 任务不能由ISR创建。
3. 任务必须在死循环中,并且不能有返回。
-
- //建立一个新任务
- #if OS_TASK_CREATE_EN > 0 //允许生成OSTaskCreate()函数
- INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
- {
- #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; //保留这个优先级,将就绪态设为1
- OS_EXIT_CRITICAL(); //打开中断
- psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); //初始化任务堆栈
- err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); //获得并初始化任务控制块
- 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
- //建立一个新任务。与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
具体函数的介绍好需要看官方的文档:http://sigpromu.org/brett/elec3730/quickref.html
今天的文章OSTaskCreate 和 OSTaskCreateExt 函数的区别分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/5263.html