本文面向初次触摸uC/OS-II的程序员,为他们介绍一下这个体系的一些根本特征和编程上的留意事项,并介绍几个值得了解的API。本文作者现已成功的将uC/OS-II移植到几种不同CPU之上。包含EPSON S1C33和Sunplus unSP?等,积累了丰厚的阅历,现在愿意和朋友们共享这些阅历。期望本文的材料关于期望运用这个体系来开发的朋友有所协助,作者愿意与您共享任何您成功的高兴。
This passage is written for the basic programmers who are first developed with the uC/OS-II real time OS。I will talk about the basic structure of this system。And I will discuss how to use some of the useful API。I will also discuss the imp of the mutilty-tasking in uC/OS-II。
(一) uC/OS-II 简介
uC/OS-II是一种依据优先级的可抢先的硬实时内核。自从92年发布以来,在世界各地都取得了广泛的运用,它是一种专门为嵌入式设备设计的内核,现在现已被移植到40多种不同结构的CPU上,运转在从8位到64位的各种体系之上。特别值得一提的是,该体系自从2.51版别之后,就经过了美国FAA认证,能够运转在比如航天器等对安全要求极为严苛的体系之上。鉴于uC/OS-II能够免费取得代码,关于嵌入式RTOS而言,挑选uC/OS无疑是最经济的挑选。
(二) uC/OS-II 运用程序根本结构
运用uC/OS-II,天然要为它开发运用程序,下面论说依据uC/OS-II的运用程序的根本结构以及留意事项。
每一个uC/OS-II运用至少要有一个使命。而每一个使命有必要被写成无限循环的方式。以下是引荐的结构:
void task ( void* pdata )
{
INT8U err;
InitTimer(); // 可选
For( ;; )
{
// 你的运用程序代码
…….
……..
OSTimeDly(1); // 可选
}
}
以上便是根本结构,至于为什么要写成无限循环的方式呢?那是由于体系会为每一个使命保存一个仓库空间,由体系在使命切换的时分换康复上下文,并履行一条reti 指令回来。假如答应使命履行到最终一个花括号(那一般都意味着一条ret指令)的话,很可能会损坏体系仓库空间从而使运用程序的履行不确定。换句话说,便是“跑飞”了。所以,每一个使命有必要被写成无限循环的方式。程序员一定要信任,自己的使命是会抛弃CPU运用权的,而不管是体系强制(经过ISR)仍是自动抛弃(经过调用OS API)。
现在来议论上面程序中的InitTimer()函数,这个函数应该由体系供给,程序员有义务在优先级最高的使命内调用它并且不能在for循环内调用。留意,这个函数是和所运用的CPU相关的,每种体系都有自己的Timer初始化程序。在uC/OS-II的协助手册内,作者特别着重绝对不能在OSInit()或许OSStart()内调用Timer初始化程序,那会损坏体系的可移植性一起带来功能上的丢失。所以,一个折中的方法便是象上面这样,在优先级最高的程序内调用,这样能够确保当OSStart()调用体系内部函数OSStartHighRdy()开端多使命后,首要履行的便是Timer初始化程序。或许专门开一个优先级最高的使命,只做一件工作,那便是履行Timer初始化,之后经过调用OSTaskSuspend()将自己挂起来,永久不再履行。不过这样会糟蹋一个TCB空间。关于那些RAM吃紧的体系来说,仍是不用为好。
2006-7-23 21:55 lanso
(三) 一些重要的uC/OS-II API介绍
任何一个操作体系都会供给很多的API供程序员运用,uC/OS-II也不破例。由于uC/OS-II面向的是嵌入式开发,并不要求大而全,所以内核供给的API也就大多和多使命休戚相关。首要的有以下几类:
1)使命类
2)音讯类
3)同步类
4)时刻类
5)临界区与事情类
我个人认为关于初级程序员而言,使命类和时刻类是有必要要首要把握的两种类型的API。下面我就来介绍比较重要的:
1) OSTaskCreate函数
这个函数应该至少再main函数内调用一次,在OSInit函数调用之后调用。效果便是创立一个使命。现在有四个参数,别离是使命的进口地址,使命的参数,使命仓库的首地址和使命的优先级。调用本函数后,体系会首要从TCB闲暇列表内请求一个空的TCB指针,然后将会依据用户给出参数初始化使命仓库,并在内部的使命安排妥当表内符号该使命为安排妥当状况。最终回来,这样一个使命就创立成功了。
2) OSTaskSuspend函数
这个函数很简单,一看姓名就该理解它的效果,它能够将指定的使命挂起。假如挂起的是当前使命的话,那么还会引发体系履行使命切换先导函数OSShed来进行一次使命切换。这个函数只需一个参数,那便是指定使命的优先级。那为什么是优先级呢?事实上在体系内部,优先级除了表明一个使命履行的先后次第外,还起着别离每一个使命的效果,换句话说,优先级也便是使命的ID。所以uC/OS-II不答应呈现相同优先级的使命。
3) OSTaskResume函数
这个函数和上面的函数正好相反,它用于将指定的现已挂起的函数康复成安排妥当状况。假如康复使命的优先级高于当前使命,那么还为引发一次使命切换。其参数相似OSTaskSuspend函数,为指定使命的优先级。需求特别阐明是,本函数并不要求和OSTaskSuspend函数成对运用。
4) OS_ENTER_CRITICAL宏
很多人都认为它是个函数,其实不然,仔细分析一下OS_CPU.H文件,它和下面立刻要谈到的OS_EXIT_CRITICAL都是宏。他们都是触及特定CPU的完成。一般都被替换为一条或许几条嵌入式汇编代码。由于体系期望向上层程序员躲藏内部完成,故而一般都声称履行此条指令后体系进入临界区。其实,它便是关个中止罢了。这样,只需使命不自动抛弃CPU运用权,其他使命就没有占用CPU的机会了,相对这个使命而言,它便是独占了。所以说进入临界区了。这个宏能少用仍是少用,由于它会损坏体系的一些服务,特别是时刻服务。并使体系对外界呼应功能下降。
5) OS_EXIT_CRITICAL宏
这个是和上面介绍的宏配套运用另一个宏,它在体系手册里的阐明是退出临界区。其实它便是重新开中止。需求留意的是,它有必要和上面的宏成对呈现,否则会带来意想不到的结果。最坏的情况下,体系会溃散。咱们引荐程序员们尽量少运用这两个宏调用,由于他们确实会损坏体系的多使命功能。