每一个μC/OS-Ⅱ应用至少要有一个任务。 每一个任务必须被写成无限循环的形式。 以下是一个推荐的结构:
系统会为每一个任务保留一个堆栈空间,由于系统在任务切换时要恢复上下文并执行一条reti 指令返回,如果允许任务执行到最后一个花括号,很可能会破坏系统堆栈空间,从而使应用程序的执行带有不确定性。 换句话说,程序“跑飞”了。 因此,每一个任务必须被写成无限循环的形式。 无论是系统强制(通过ISR)还是主动放弃(通过调用OS API),开发者都要使自己的任务能够放弃对CPU 的使用权。
现在来讨论InitTimer()函数,这个函数应该由系统提供,开发者需要在优先级最高的任务内调用它而且不能在for 循环内调用。 注意,这个函数是与所使用的CPU 相关的,每种系统都有自己的Timer 初始化程序。 在μC/OS-Ⅱ的帮助手册内,作者强调绝对不能在OSInit()或者OSStart()内调用Timer 初始化程序,那样会破坏系统的可移植性,同时也会带来性能上的损失。 因此,一个折中的办法就是像上面一样,在优先级最高的任务内调用,这样可以保证当OSStart()调用系统内部函数OSStartHighRdy()开始多任务后,首先执行的就是Timer 初始化程序。 或者专门执行一个优先级最高的任务,只做一件事情,那就是执行Timer 初始化,之后通过调用OSTaskSuspend()将自己挂起来,永远不再执行。 不过,这样会浪费一个TCB 空间,对于那些RAM 内存空间有限的系统来说,应该尽量不用。(www.xing528.com)
μC/OS-Ⅱ是多任务内核,函数可能会被多个任务调用,因此,还需考虑函数的可重入性。由于每个任务有各自的堆栈,而任务的局部变量是放在当前的任务堆栈中的,所以,要保证函数代码的可重入性,只要不使用全局变量即可。
利用μC/OS-Ⅱ的消息队列可以实现消息驱动程序。 在编写任务代码时,先完成任务初始化,然后在消息循环过程中,在某个消息上等待,当其他任务或者中断服务程序返回消息后,根据消息的内容调用相应的函数模块,函数调用后重新回到消息循环,继续等待消息。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。