ucos II 创建第一个任务之二
来源:互联网 发布:sql注入错误 编辑:程序博客网 时间:2024/06/06 19:39
Ucos II 创建第一个任务之二
下面具体讲解下任务创建的过程
下图就是创建任务函数的实现程序。
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
void *psp;
INT8U err;
if (prio > OS_LOWEST_PRIO) { (1)
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { (2)
OSTCBPrioTbl[prio] = (OS_TCB *)1; (3)
OS_EXIT_CRITICAL(); (4)
psp = (void *)OSTaskStkInit(task, pdata, ptos, 0); (5)
err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); (6)
if (err == OS_NO_ERR) { (7)
OS_ENTER_CRITICAL();
OSTaskCtr++; (8)
OSTaskCreateHook(OSTCBPrioTbl[prio]); (9)
OS_EXIT_CRITICAL();
if (OSRunning) { (10)
OSSched(); (11)
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; (12)
OS_EXIT_CRITICAL();
}
return (err);
} else {
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
}
1.OSTaskCreate()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWSEST_PRIO之间。OS_LOWSEST_PRIO的定义是在os_cfg.h这个文件,定义如下:#define OS_LOWEST_PRIO 12 。这个地方mcu21就有些搞不懂,为什么不是64,而是12?有明白的可以告知mcu21同学。
2.接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用μC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲未使用的,μC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。
3.然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。没错,就是OSTaskStkInit(),系统移植时候,我们辛辛苦苦在OS_CPU_C.C编写了它,原来是跑到这里耀武扬威来了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户必须将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。
4.一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],这也是任务创建的核心,从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB,如果OS_TCB池中有空闲的OS_TCB,它就被初始化。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。
5. 从OSTCBInit()返回后,OSTaskCreate()要检验返回代码[L4.1(7)],如果成功,就增加OSTaskCtr[L4.1(8)],OSTaskCtr用于保存产生的任务数目。如果OSTCBInit()返回失败,就置OSTCBPrioTbl[prio]的入口为0[L4.1(12)]以放弃该任务的优先级。
6.然后,OSTaskCreate()调用OSTaskCreateHook()[L4.1(9)],OSTaskCreateHook()是用户自己定义的函数,用来扩展OSTaskCreate()的功能。这一步骤可有有可无,在mcu21的项目里,移植的时候是没有编写OSTaskCreateHook()的,所以也没有调用这一函数。。
7. 如果OSTaskCreate()函数是在某个任务的执行过程中被调用(即OSRunning置为True[L4.1(10)]),则任务调度函数会被调用[L4.1(11)]来判断是否新建立的任务比原来的任务有更高的优先级。如果新任务的优先级更高,内核会进行一次从旧任务到新任务的任务切换。如果在多任务调度开始之前(即用户还没有调用OSStart()),新任务就已经建立了,则任务调度函数OS_Sched()不会被调用。
经过以上7步,一个任务大致就创建好了。
上面程序中多次使用了这两句程序,非常重要,多次使用。
OS_ENTER_CRITICAL(); //关中断
OS_EXIT_CRITICAL(); //开中断
- ucos II 创建第一个任务之二
- ucos II 创建第一个任务之二
- ucos II 创建第一个任务之一
- ucos II 创建第一个任务之一
- uCOS-ii内核的任务之二
- ucos II任务管理之二:恢复任务
- ucos II 任务间 通信之二:事件控制块
- ucos II 内核学习之二:任务控制块
- ucos II 内核学习之二:任务控制块
- ucos-II之任务优先级
- uCOS-II整理之任务
- Ucos II 移植之二
- uCOS-II内核之任务调度 [转载]
- uCOS-II任务之延时函数
- uCOS-II任务间通信之信号量
- uCOS-II任务间通信之邮箱
- uCOS-II内核之任务控制块
- uCOS-II内核学习之任务调度
- Delphi xe6 andriod 编程入门教程demo随书光盘
- c#将Excel数据导入到数据库的实现代码
- Freemarker页面语法、函数教程
- redis学习笔记01
- Oracle数据库从 9.2.0.1 到 9.2.0.8升级步骤
- ucos II 创建第一个任务之二
- Android入门笔记 - 界面开发 - Notification, NotificationManager
- Android APK反编译详解(附图)
- mysql优化提点建议
- test12
- java 内存泄露的理解与解决
- combotree 取值问题
- 擦亮“电子眼” 守卫家门口的安全
- android多线程signalthreadpthreads编程