运用uC/OS-II,天然要为它开发运用程序,下面论说根据uC/OS-II的运用程序的根本结构以及留意事项。
kernel供给给用户一些功用函数,使得用户的体系树立愈加便利,可是kernel内部不会处理用户的作业,关于整个体系的详细运用作业还得需求用户自己去考虑,怎么利用好这些功用服务函数就成为一个比较重要的问题.
1. main函数的结构
void main (void)
{
初始化体系的硬件;
OSInit();
使命的树立,音讯机制的树立;
OSStart();
}
这儿需求的是在OSStart()履行之前不得发动中止,硬件体系还不能作业.有必要先让软件体系进入作业状况后才行.
2 .使命的结构
每一个uC/OS-II运用至少要有一个使命。而每一个使命有必要被写成无限循环的方式。以下是引荐的结构:
void task ( void* pdata )
{
INT8U err;
InitTimer(); // 可选
For( ;; )
{
// 你的运用程序代码
…….
……..
OSTimeDly(1); // 可选
}
}
以上便是根本结构,在使命发动函数履行完后,体系会切换到最高优先级的使命去履行,此刻,能够将体系硬件部分的发动放在该使命的最前边,仅仅是发动时履行一次,主要是发动体系的节拍中止,或许一些有必要在多使命体系调度后才干初始化的部分,使体系的真实开端作业,到达软件硬件的根本同步.
至于为什么要写成无限循环的方式?那是由于体系会为每一个使命保存一个仓库空间,由体系在使命切换的时分换康复上下文,并履行一条reti 指令回来。假如答应使命履行到最后一个花括号(那一般都意味着一条ret指令)的话,很可能会损坏体系仓库空间从而使运用程序的履行不确定。换句话说,便是“跑飞”了。所以,每一个使命有必要被写成无限循环的方式。
现在来议论上面程序中的InitTimer()函数,这个函数应该由体系供给,程序员有义务在优先级最高的使命内调用它并且不能在for循环内调用。留意,这个函数是和所运用的CPU相关的,每种体系都有自己的Timer初始化程序。
在uC/OS-II的协助手册内,作者特别着重绝对不能在OSInit()或许OSStart()内调用Timer初始化程序,那会损坏体系的可移植性一起带来性能上的丢失。所以,一个折中的方法便是象上面这样,在优先级最高的程序内调用,这样可确保当OSStart()调用体系内部函数OSStartHighRdy()开端多使命后,首要履行的便是Timer初始化程序。或许专门开一个优先级最高的使命,只做一件工作,那便是履行Timer初始化,之后经过调用OSTaskSuspend()将自己挂起来,永久不再履行。不过这样会糟蹋一个TCB空间。关于那些RAM吃紧的体系来说,仍是不用为好。