本模块介绍SYS/BIOS中的第三种线程:TASK线程。
Task线程被Task模块所管理控制,Task的优先级高于空闲循环(Idle Loop),但是低于硬件中断和软件中断。Task模块基于Task的优先级和当前执行的状态动态地调度和抢占任务。这样确保了处理器始终准备运行最高优先级的线程。Task线程拥有高达32个优先等级。默认为16,最低优先级为0,即空闲循环。
这里值得注意的是,SWI和HWI是不能被阻塞的线程,也就是说一旦它们被运行,就要运行到终点,除非被其他线程抢占,HWI和SWI都使用的是系统的堆栈,而每个TASK有自己的堆栈,可以在TASK线程之间随意的相互切换,例如若在TASK2的运行过程中,TASK1进入ready状态,DSP将会马上转到TASK1运行,稍后如果TASK1被阻塞,DSP再继续TASK2运行,当TASK1所等待的信号就绪后,再转入TASK1中运行,如此反复。
动态创建和删除Task:
Task_Params taskParams;
Task_Handle task0;
Error_Block eb;
Error_init(&eb);
/* Create 1 task with priority 15 */
Task_Params_init(&taskParams);
taskParams.stackSize = 512;
taskParams.priority = 15;
task0 = Task_create((Task_FuncPtr)hiPriTask, &taskParams, &eb);
if (task0 == NULL) {
System_abort("Task create failed");
}
以上代码显示了如何动态创建一个Task,通过调用Task_create()函数,来派生SYS/BIOS任务,其参数包括新任务开始执行的C函数地址, Task_create()返回值为一个任务句柄,可以作为一个变量传递个其他任务函数。
如果传递NULL,而不是指向实际的task_Params结构体指针,会使用默认的参数,eb是一个错误块,可以处理在任务对象创建期间可能产生的错误。
通过使用Task_delete函数来回收任务对象和堆栈使用的存储空间,并释放任务对象的堆栈。但是该函数不能释放被任务所拥有的Semaphore或其他资源。
静态创建Task:
使用Task_create()可以静态创建任务,但是不能使用Task_delete来删除静态创建的任务,
Task线程模块会自动创建Task_idle任务线程并且给予最低的优先级。当没有更高优先级的HWI,SWI,TASK运行时,会执行Task_idle。如果想让Task线程初始不被激活,可以设置起优先级为-1。只有当优先级上上升时才会被激活。
每个任务对象总是处于以下四个可能的执行状态之一:
- Task_Mode_RUNNING:任务线程正在系统中执行
- Task_Mode_READY:任务已经准备好用于编排执行,是否执行取决于处理器
- Task_Mode_BLOCKED:任务线程不能被执行,直到特定的时间在系统中发生
- Task_Mode_TERMINATED:任务线程被终止了且没有再执行
- Task_Mode_INACTIVE:任务有一个-1的优先级,并且处于准备好的状态,可以在运行时调用Task_setPri()来设置优先级或者创建任务来改变优先级
Task线程的最大优先级为Task_numPriorities-1 (default=15; maximum=31).如果达到最大优先级,那么该线程就不能被其他任务线程抢占,最高优先级的Task线程仍然可以调用Semaphore_pend(), Task_sleep()或者其他低优先级任务线程执行阻塞调用.Task线程可以在运行时通过Task_setPr()来改变优先级.