ucos-ii 利用指针数组动态创建任务
ucos-ii下的任务创建
ucos-ii 是一个应用比较广泛的嵌入式实时系统,内核可剥夺,运行时按照任务优先级进行内核抢占,从而保证了多任务的高实时性。并且可应用于许多嵌入式芯片中,比如51单片机,ARM,以及飞思卡尔Power 架构的MPC系列芯片等等。
大家都知道 OSTaskCreate (void (*task)(void *p_arg),
void *p_arg,
OS_STK *ptos,
INT8U prio) 函数可用于创建任务,其中ptos指针指向为该任务申请的任务堆栈的栈顶,该堆栈用于在任务调度时保存CPU寄存器的当前值以及该任务中的局部变量。 在ucos中为任务申请堆栈其实就是创建一个数组,ptos代表该数组第一个元素地址或者最后一个元素地址。所以在给ptos赋值时,需要了解当前所用芯片的堆栈增长方式,即向上增长还是向下增长。若为向上增长方式,则应指向数组的第一个元素地址,相反,应指向数组的最后一个元素地址。 task指向该任务执行的函数地址,p_arg为task函数的参数。prio为该任务的优先级。对于优先级,越小代表优先级越高。以Power架构芯片举例(部分代码),堆栈增长方式为向下增长(即大端模式):
#define StkSize 512;
OS_STK TestStk[StkSize];
int main()
{
OSInit();
OSTaskCreate(
Test,
0,
&TestStk[StkSize-1]
5
);
OSTimeSet(0);
OSStart();
return 1;
}
void Test(void *prg)
{
int i;
while(1)
{
i++;
OSTimeDlyHMSM(0u, 0u, 1u, 0u);
}
}
对于该任务函数,必须是一个死循环,同时,必须要有必要的延时,否则优先级低的任务将无法得到执行。
以上简单的说明了任务的创建,但是在很多应用中任务的数量以及任务堆栈的都不是预先知道的,或者有时根据在Flash中读取到的配置数据来灵活的实现多任务的创建。下面说明如何实现动态多任务的创建。
如何实现多任务以及任务堆栈的创建
如果要根据Flash中配置的数据,实现多任务创建,任务可以用for循环创建,但是任务堆栈呢?我们不能提前按照预期的最大任务数量去申请堆栈,因为这样是对内存的浪费。试想一下,如果我们开发的是一个通用性较强的,可配置参数的嵌入式设备,如果每一个对象都按照预想的最大数量去创建,对于嵌入式设备的内存很难满足要求。
为此,我们可以采用指针数组的方式,我们只定义一个OS_STK类型的指针数组:
OS_STK * TaskStk[12];
然后为其分配内存,假设初始运行时从Flash中读到的任务数量为Num,并且假设Num<12:
int i;
for(i=0;i<Num;i++)
{
if(Num==12)
break;
TaskStk[i]=malloc(StkSize*sizeof(OS_STK));
OSTaskCreate(
Test,
0,
TaskStk[i]+StkSize-1,
i+1;
);
}
因为TaskStk数组存储的是任务堆栈数组的第一个元素地址,所以在在传递栈顶地址时,需要
TaskStk[i]+StkSize-1;
总结
关于在ucos-ii动态创建任务及堆栈已经完成,其用到的主要技术就是C/C++数组指针以及动态变长数组。