新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 浅析μC/OS-ⅡAPI的设计思想及实现机制

浅析μC/OS-ⅡAPI的设计思想及实现机制

作者:时间:2012-08-24来源:网络收藏

3.5查询一个信号量的当前状态, OSSemQuery()

INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)

在应用程序中,用户随时可以调用函数OSSemQuery()来查询一个信号量的当前状态。该函数有两个参数:一个是指向信号量对应事件控制块的指针pevent。该指针是在生产信号量时,由OSSemCreate()函数返回的;另一个是指向用于记录信号量信息的数据结构OS_SEM_DATA(见uCOS_II.H)的指针pdata。因此,调用该函数前,用户必须先定义该结构变量,用于存储信号量的有关信息。在这里,之所以使用一个新的数据结构的原因在于,调用函数应该只关心那些和特定信号量有关的信息,而不是象OS_EVENT数据结构包含的很全面的信息。该数据结构只包含信号量计数值.OSCnt和等待任务列表.OSEventTbl[]、.OSEventGrp,而OS_EVENT中还包含了另外的两个域.OSEventType和.OSEventPtr。

4. 时间类的设计思路和

μⅡ(其它内核也一样)要求用户提供定时中断来延时与超时控制等功能。这个定时中断叫做时钟节拍,它应该每秒发生10至100次。时钟节拍的实际频率是由用户的应用程序决定的。时钟节拍的频率越高,系统的负荷就越重。

下面主要讲述五个与时钟节拍有关的函数。

4.1 任务延时函数,OSTimeDly()

void OSTimeDly (INT16U ticks)

这应该程序员们调用最多的一个函数了,这个函数完成功能很简单,就是先挂起当起当前任务,然后进行任务切换,在指定的时间到来之后,将当前任务恢复为就绪状态,但是并不一定运行,如果恢复后是优先级最高就绪任务的话,那么运行之。简单点说,就是可以任务延时一定时间后再次执行它,或者说,暂时放弃CPU的使用权。一个任务可以不显式的调用这些可以导致放弃CPU使用权的,但那样多任务性能会大大降低,因为此时仅仅依靠时钟在进行任务切换。一个好的任务应该在完成一些操作主动放弃使用权。

4.2 按时分秒延时函数 OSTimeDlyHMSM()

INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U milli)

OSTimeDly()虽然是一个非常有用的函数,但用户的应用程序需要知道延时时间对应的时钟节拍的数目。增加了OSTimeDlyHMSM()函数后,用户就可以按小时(H)、分(M)、秒(S)和毫秒(m)来定义时间了,这样会显得更自然些。与OSTimeDly()一样,调用OSTimeDlyHMSM()函数也会使μⅡ进行一次任务调度,并且执行下一个优先级最高的就绪态任务。任务调用OSTimeDlyHMSM()后,一旦规定的时间期满或者有其它的任务通过调用OSTimeDlyResume()取消了延时,它就会马上处于就绪态。同样,只有当该任务在所有就绪态任务中具有最高的优先级时,它才会立即运行。

4.3 让处在延时期的任务结束延时,OSTimeDlyResume()

INT8U OSTimeDlyResume (INT8U prio)

μⅡ允许用户结束延时正处于延时期的任务。延时的任务可以不等待延时期满,而是通过其它任务取消延时来使自己处于就绪态。这可以通过调用OSTimeDlyResume()和指定要恢复的任务的优先级来完成。实际上,OSTimeDlyResume()也可以唤醒正在等待事件的任务,虽然这一点并没有提到过。在这种情况下,等待事件发生的任务会考虑是否终止等待事件。

4.4 系统时间,OSTimeGet()和OSTimeSet()

INT32U OSTimeGet (void)

void OSTimeSet (INT32U ticks)

用户可以通过调用OSTimeGet()来获得该计数器的当前值。也可以通过调用OSTimeSet()来改变该计数器的值。注意,在访问OSTime的时候中断是关掉的。这是因为在大多数8位处理器上增加和拷贝一个32位的数都需要数条指令,这些指令一般都需要一次执行完毕,而不能被中断等因素打断。

5. 临界区类API的设计思路和

和其它内核一样,μC/OS-Ⅱ为了处理临界段代码需要关中断,处理完毕后再开中断。这使得μC/OS-Ⅱ能够避免同时有其它任务或中断服务进入临界段代码。

μC/OS-Ⅱ定义两个宏(macros)来关中断和开中断,以便避开不同C编译器厂商选择不同的方法来处理关中断和开中断。μC/OS-Ⅱ中的这两个宏调用分别是:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。因为这两个宏的定义取决于所用的微处理器,故在文件OS_CPU.H中可以找到相应宏定义。每种微处理器都有自己的OS_CPU.H文件。

5.1 OS_ENTER_CRITICAL宏

很多人都以为它是个函数,其实不然,仔细分析一下OS_CPU.H文件,它和下面马上要谈到的OS_EXIT_CRITICAL都是宏。他们都是涉及特定CPU的实现。一般都被替换为一条或者几条嵌入式汇编代码。由于系统希望向上层程序员隐藏内部实现,故而一般都宣称执行此条指令后系统进入临界区。其实,它就是关个中断而已。这样,只要任务不主动放弃CPU使用权,别的任务就没有占用CPU的机会了,相对这个任务而言,它就是独占了。所以说进入临界区了。这个宏能少用还是少用,因为它会破坏系统的一些服务,尤其是时间服务。并使系统对外界响应性能降低。

5.2 OS_EXIT_CRITICAL宏

这个是和上面介绍的宏配套使用另一个宏,它在系统手册里的说明是退出临界区。其实它就是重新开中断。需要注意的是,它必须和上面的宏成对出现,否则会带来意想不到的后果。最坏的情况下,系统会崩溃。我们推荐程序员们尽量少使用这两个宏调用,因为他们的确会破坏系统的多任务性能。

6. 结束语

通过对μC/OS-II中这几类API的简单分析,我们可以看出μC/OS-II作为一个多任务、抢占式嵌入式操作系统,其API都是为多任务及其多任务之间的调度和通信的实现来设计的。μC/OS-II提供的API简洁而灵活,使用户在设计实际应用时能够很方便的利用系统提供的各种调用,充分发挥μC/OS-II实时、高效的优点。


上一页 1 2 3 下一页

评论


相关推荐

技术专区

关闭