资料介绍
1 引言
uC/OS-II是著名的源码公开的实时内核[1],是专为嵌入式应用设计的,可用于各类8位16位和32位单片机或DSP。现在有很多使用者正在或已经将其移植到各种类型的芯片。因为源码公开,uC/OS-II也经常被作为嵌入式实时内核的教材,为专业人员提供了学习实时内核的难得机会。在实际使用中不管基于何种操作系统平台,应用程序经常会等待一些系统资源,如信号量,事件标志,消息等。等待类型共有三种:(1)如果不能马上获取,悬挂等待;(2)不管是否能获取资源,马上返回,不会等待;(3) 如果不能马上获取资源,将进行有限时间的等待,即超时等待。
2 超时等待机制的基本原理
应用程序通过操作系统提供的系统调用接口获取资源时,在系统调用的入口参数里可以指定超时等待的最大时间,通常以毫秒为单位,内核会将其转化为系统的时钟滴嗒数(tick)。一般内核都会执行以下流程:
(1)如果资源能马上获取,系统调用将成功返回。
(2)如果资源不能马上获取,内核将设置一定时器进行计时,把当前任务悬挂在该资源的等待队列上,该任务从就绪表中删除,并进行调度,让出CPU的使用权。
(3)如果在指定的时间内资源变得可以获取了,定时器应马上停止计时,该任务从等待队列里摘下并且重新回到就绪表中等候调度。
(4)如果定时器到时,任务应该从等待队列里摘下并且重新回到就绪表中,系统调用返回超时信息。
内核在每一个tick都会做一系列的工作,包括任务的延迟以及超时等待资源的定时器等相关的检查操作。一般来讲,在指定的时间间隔以外到达的资源和信号被认为是无效的,这也是指定超时时间间隔的原意所在,有些对时间要求苛刻的场合就有这种需求,内核必须处理好这方面的问题。
3 uC/OS-II内核超时等待机制的分析
假设某任务T超时等待信号量资源R,先来分析时钟节拍函数的源代码。
void OSTimeTick(void)
{
OS_TCB *ptcb;
OSTimeTickHook();
ptcb=OSTCBList;
while(ptcb-》OSTCBPrio!=OS_IDLE_PRIO){
OS_ENTER_CRITICAL();
if(ptcb-》OSTCBDly!=0){
if(--ptcb-》OSTCBDly==0){
if(!(ptcb-》OSTCBStat&OS_STAT_SUSPEND)){//(1)
OSRdyGrp|=ptcb-》OSTCBBity; //(2)
OSRdyTbl[ptcb-》OSTCBY]|=ptcb-》OSTCBBitX;//(3)
}else {
ptcb-》OSTCBDly=1;
}
}
}
ptcb=ptcb-》OSTCBNext;
OS_EXIT_CRITICAL();
}
OS_ENTER_CRITICAL();
OSTime++;
OS_EXIT_CRITICAL();
}
语句(1),(2),(3)表明:时钟中断服务程序在每一个时钟中断在需要的情况下对任务的延迟项进行减1操作,如果任务T的定时时间间隔到期(延迟项被减为0),并且任务T没有附加的挂起操作,任务T就会进入就绪表,然而该函数却没有进一步将任务T移出资源R的等待队列,也就是说此时任务T跨了两个状态,这两个状态从本质上讲是矛盾的。虽然任务T此时处于就绪状态,但未必马上就能获得执行权,这取决于任务T的优先级。在任务T没有被调度执行之前的这段时间内,假设资源R到达了,比如一个中断服务程序调用了OSSemPost函数,会是什么情况呢?我们再来分析OSSemPost函数。
void OSSemPost(OS_EVENT *pevent)
{
OS_ENTER_CRITICAL();
if(pevent-》OSEventGrp!=0x00){
OS_EventTaskRdy(pevent,(void*)0,OS_STAT_SEM);//(4)
OS_EXIT_CRITICAL();
OS_Sched();
return(OS_NO_ERR);
}
if(pevent-》OSEventCnt《65535){
pevent-》OSEventCnt++;
OS_EXIT_CRITICAL();
return(OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return(OS_SEM_OVF);
}
}
从语句(4)可以看出,在资源R的等待列表中有等待任务的情况下,等待表中最高优先级的任务将从等待列表中删除,并且进入就绪表。如果等待表中的最高优先级任务就是前面讲的等待超时的任务T,这相当于任务T又一次进入就绪表,不过只有一次从等待表中删除。任务T获取到了资源,只不过是在超时时间以外获取到的。任务T获得执行权以后从调度程序返回将运行函数OSSemPend()语句(6)处的条件代码,此时语句(5)处的条件不成立,任务按获取到资源对待。
void OSSemPend(OS_EVENT *pevent,INT16U timeout,INT8U *err)
{
OS_ENTER_CRITICAL();
if(pevent-》OSEventType!=OS_EVENT_TYPE_SEM){
OS_EXIT_CRITICAL();
*err=OS_ERR_EVENT_TYPE;
}
if(pevent-》OSEventCnt》0){
pevent-》OSEventCnt--;
OS_EXIT_CRITICAL();
*err=OS_NO_ERR;
}else if(OSIntNesting》0){
OS_EXIT_CRITICAL();
*err=OS_ERR_PEND_ISR;
}else{
OSTCBCur-》OSTCBStat|=OS_STAT_SEM;
OSTCBCur-》OSTCBDly=timeout;
OSEventTaskWait(pevent);
OS_EXIT_CRITICAL();
OSSched();
OS_ENTER_CRITICAL();
if(OSTCBCur-》OSTCBStat&OS_STAT_SEM){ //(5)
OSEventTo(pevent);
OS_EXIT_CRITICAL();
*err=OS_TIMEOUT;
}else{ //(6)
OSTCBCur-》OSTCBEventPtr=(OS_EVENT*0);
OS_EXIT_CRITICAL();
*err=OS_NO_ERR;
}
}
}
void OSEventTo(OS_EVENT *pevent)
{
if((pevent-》OSEventTbl[OSTCBCur-》OSTCBY]&=~OSTCBCur-》OSTCBBitX)==0)
{
pevent-》OSEventGrp&=~OSTCBBitY;
}
OSTCBCur-》OSTCBStat=OS_STAT_RDY;
v OSTCBCur-》OSTCBEventPtr=(OS_EVENT*0);}
如果任务T由于超时进入就绪态,到T获得执行权之前,仍没有获取到资源R,将运行语句(5)处的条件代码,由函数OSEventTo()可以看出,此时任务T才被从等待表中删除,最后返回超时状态。
通过分析开放源码的nucleus内核,发现nucleus在超时到期时执行定时器的一个回调函数,此回调函数马上将等待任务从等待链表中删除,将返回状态定性为超时。这样在任务获得执行权前,即使资源到达,该任务也不会得到。这样一来,uC/OS-II内核只要在时钟节拍函数里增加代码将延时期满的任务从相应的资源等待列表中删除即可。这一工作很容易实现,内核任务控制块有指向所等待的信号量,消息等事件控制块的指针,事件控制块里有相应的等待表。对于uC/OS-II新引进的事件标志组[2],任务控制块有指向相应的等待节点的指针,等待节点有指向相应的事件标志组控制块的指针,删除一个等待节点也能实现。
4 结论
uC/OS-II其它资源的等待机制,比如消息以及包括2.5.2版引入的事件标志组的实现都存在上述的超时时间不严格的问题,这是由中断节拍函数OSTimeTick()决定的,该函数只负责将任务移入就绪表,而不处理相应的等待表。
参考文献:
[1]Labrosse Jean J.uc/OS-II-源码公开的实时嵌入式操作系统[M]。北京:中国电力出版社,2001.
[2]Labrosse Jean J. 嵌入式实时操作系统uc/OS-II[M]。北京:北京航空航天大学出版社,2003.
uC/OS-II是著名的源码公开的实时内核[1],是专为嵌入式应用设计的,可用于各类8位16位和32位单片机或DSP。现在有很多使用者正在或已经将其移植到各种类型的芯片。因为源码公开,uC/OS-II也经常被作为嵌入式实时内核的教材,为专业人员提供了学习实时内核的难得机会。在实际使用中不管基于何种操作系统平台,应用程序经常会等待一些系统资源,如信号量,事件标志,消息等。等待类型共有三种:(1)如果不能马上获取,悬挂等待;(2)不管是否能获取资源,马上返回,不会等待;(3) 如果不能马上获取资源,将进行有限时间的等待,即超时等待。
2 超时等待机制的基本原理
应用程序通过操作系统提供的系统调用接口获取资源时,在系统调用的入口参数里可以指定超时等待的最大时间,通常以毫秒为单位,内核会将其转化为系统的时钟滴嗒数(tick)。一般内核都会执行以下流程:
(1)如果资源能马上获取,系统调用将成功返回。
(2)如果资源不能马上获取,内核将设置一定时器进行计时,把当前任务悬挂在该资源的等待队列上,该任务从就绪表中删除,并进行调度,让出CPU的使用权。
(3)如果在指定的时间内资源变得可以获取了,定时器应马上停止计时,该任务从等待队列里摘下并且重新回到就绪表中等候调度。
(4)如果定时器到时,任务应该从等待队列里摘下并且重新回到就绪表中,系统调用返回超时信息。
内核在每一个tick都会做一系列的工作,包括任务的延迟以及超时等待资源的定时器等相关的检查操作。一般来讲,在指定的时间间隔以外到达的资源和信号被认为是无效的,这也是指定超时时间间隔的原意所在,有些对时间要求苛刻的场合就有这种需求,内核必须处理好这方面的问题。
3 uC/OS-II内核超时等待机制的分析
假设某任务T超时等待信号量资源R,先来分析时钟节拍函数的源代码。
void OSTimeTick(void)
{
OS_TCB *ptcb;
OSTimeTickHook();
ptcb=OSTCBList;
while(ptcb-》OSTCBPrio!=OS_IDLE_PRIO){
OS_ENTER_CRITICAL();
if(ptcb-》OSTCBDly!=0){
if(--ptcb-》OSTCBDly==0){
if(!(ptcb-》OSTCBStat&OS_STAT_SUSPEND)){//(1)
OSRdyGrp|=ptcb-》OSTCBBity; //(2)
OSRdyTbl[ptcb-》OSTCBY]|=ptcb-》OSTCBBitX;//(3)
}else {
ptcb-》OSTCBDly=1;
}
}
}
ptcb=ptcb-》OSTCBNext;
OS_EXIT_CRITICAL();
}
OS_ENTER_CRITICAL();
OSTime++;
OS_EXIT_CRITICAL();
}
语句(1),(2),(3)表明:时钟中断服务程序在每一个时钟中断在需要的情况下对任务的延迟项进行减1操作,如果任务T的定时时间间隔到期(延迟项被减为0),并且任务T没有附加的挂起操作,任务T就会进入就绪表,然而该函数却没有进一步将任务T移出资源R的等待队列,也就是说此时任务T跨了两个状态,这两个状态从本质上讲是矛盾的。虽然任务T此时处于就绪状态,但未必马上就能获得执行权,这取决于任务T的优先级。在任务T没有被调度执行之前的这段时间内,假设资源R到达了,比如一个中断服务程序调用了OSSemPost函数,会是什么情况呢?我们再来分析OSSemPost函数。
void OSSemPost(OS_EVENT *pevent)
{
OS_ENTER_CRITICAL();
if(pevent-》OSEventGrp!=0x00){
OS_EventTaskRdy(pevent,(void*)0,OS_STAT_SEM);//(4)
OS_EXIT_CRITICAL();
OS_Sched();
return(OS_NO_ERR);
}
if(pevent-》OSEventCnt《65535){
pevent-》OSEventCnt++;
OS_EXIT_CRITICAL();
return(OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return(OS_SEM_OVF);
}
}
从语句(4)可以看出,在资源R的等待列表中有等待任务的情况下,等待表中最高优先级的任务将从等待列表中删除,并且进入就绪表。如果等待表中的最高优先级任务就是前面讲的等待超时的任务T,这相当于任务T又一次进入就绪表,不过只有一次从等待表中删除。任务T获取到了资源,只不过是在超时时间以外获取到的。任务T获得执行权以后从调度程序返回将运行函数OSSemPend()语句(6)处的条件代码,此时语句(5)处的条件不成立,任务按获取到资源对待。
void OSSemPend(OS_EVENT *pevent,INT16U timeout,INT8U *err)
{
OS_ENTER_CRITICAL();
if(pevent-》OSEventType!=OS_EVENT_TYPE_SEM){
OS_EXIT_CRITICAL();
*err=OS_ERR_EVENT_TYPE;
}
if(pevent-》OSEventCnt》0){
pevent-》OSEventCnt--;
OS_EXIT_CRITICAL();
*err=OS_NO_ERR;
}else if(OSIntNesting》0){
OS_EXIT_CRITICAL();
*err=OS_ERR_PEND_ISR;
}else{
OSTCBCur-》OSTCBStat|=OS_STAT_SEM;
OSTCBCur-》OSTCBDly=timeout;
OSEventTaskWait(pevent);
OS_EXIT_CRITICAL();
OSSched();
OS_ENTER_CRITICAL();
if(OSTCBCur-》OSTCBStat&OS_STAT_SEM){ //(5)
OSEventTo(pevent);
OS_EXIT_CRITICAL();
*err=OS_TIMEOUT;
}else{ //(6)
OSTCBCur-》OSTCBEventPtr=(OS_EVENT*0);
OS_EXIT_CRITICAL();
*err=OS_NO_ERR;
}
}
}
void OSEventTo(OS_EVENT *pevent)
{
if((pevent-》OSEventTbl[OSTCBCur-》OSTCBY]&=~OSTCBCur-》OSTCBBitX)==0)
{
pevent-》OSEventGrp&=~OSTCBBitY;
}
OSTCBCur-》OSTCBStat=OS_STAT_RDY;
v OSTCBCur-》OSTCBEventPtr=(OS_EVENT*0);}
如果任务T由于超时进入就绪态,到T获得执行权之前,仍没有获取到资源R,将运行语句(5)处的条件代码,由函数OSEventTo()可以看出,此时任务T才被从等待表中删除,最后返回超时状态。
通过分析开放源码的nucleus内核,发现nucleus在超时到期时执行定时器的一个回调函数,此回调函数马上将等待任务从等待链表中删除,将返回状态定性为超时。这样在任务获得执行权前,即使资源到达,该任务也不会得到。这样一来,uC/OS-II内核只要在时钟节拍函数里增加代码将延时期满的任务从相应的资源等待列表中删除即可。这一工作很容易实现,内核任务控制块有指向所等待的信号量,消息等事件控制块的指针,事件控制块里有相应的等待表。对于uC/OS-II新引进的事件标志组[2],任务控制块有指向相应的等待节点的指针,等待节点有指向相应的事件标志组控制块的指针,删除一个等待节点也能实现。
4 结论
uC/OS-II其它资源的等待机制,比如消息以及包括2.5.2版引入的事件标志组的实现都存在上述的超时时间不严格的问题,这是由中断节拍函数OSTimeTick()决定的,该函数只负责将任务移入就绪表,而不处理相应的等待表。
参考文献:
[1]Labrosse Jean J.uc/OS-II-源码公开的实时嵌入式操作系统[M]。北京:中国电力出版社,2001.
[2]Labrosse Jean J. 嵌入式实时操作系统uc/OS-II[M]。北京:北京航空航天大学出版社,2003.
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- 基于STM32F103C8T6+uC/OS-II的例程笔记(二) 1次下载
- 【嵌入式系统—实时操作系统】uC/OS-II 及其STM32F103移植 5次下载
- uC/OS-II 应用程序基本结构及重要的API介绍 2次下载
- 嵌入式实时操作系统uC/OS-II内核_英版 0次下载
- uc-os-II入门学习 165次下载
- μC/OS-II 在Nios上的移植 90次下载
- 基于MCF5213和uC/OS-II的低成本Zigbee无线 51次下载
- uc/os-ii在ARM处理器上的移植 65次下载
- μC/OS-II在PC机上移植的设计与实现 14次下载
- 基于uc/os-ii 的嵌入式GUI研究与应用 20次下载
- 基于uC/OS-II的齿轮流量计二次仪表的设计 30次下载
- μC OS-II 在Nios 上的移植1 28次下载
- μC OS-II 在S3C44B0X 处理器上的移植 18次下载
- μC/OS-II 任务调度机制的改进 14次下载
- The uC/OS-II port for Keil C V 57次下载
- 基于μC/OS-II和TMS320LF2407A实现集散式数据采集系统的设计 2003次阅读
- 基于单片机和μC/0S-II内核实现串口通信模块的设计 1529次阅读
- 基于实时嵌入式操作系统mC/OS-II实现GPRS终端系统的设计 2063次阅读
- 基于μC/OS-II操作系统实现在P89V51RD2微控制器上运行 645次阅读
- 基于μC/OS-II操作系统在SPCE061A上的移植优化研研究 673次阅读
- 基于μC/OS-II嵌入式系统开发中低功耗系统的设计 2817次阅读
- 51单片机对μC/OS-II实时操作系统的移植 2228次阅读
- LPC213X通过μC/OS-II的多种移植方案 547次阅读
- 浅论uC/OS-II 在电动车电池管理系统中的应用研究 1168次阅读
- μC/OS-II系统基础嵌入式开发编程教程 4148次阅读
- LPC2119简介 μC/OS-II在LPC2119上的移植 2525次阅读
- 车辆调度系统的整体设计 UC/OS-II的内核调度机理 1022次阅读
- 嵌入式设备设计的内核uc/os-ii api使用手册大全 4044次阅读
- uC/OS-III的特点 1941次阅读
- 用AndesCore N1033A-S处理器实现μC/OS-II的移植 3693次阅读
下载排行
本周
- 1TC358743XBG评估板参考手册
- 1.36 MB | 330次下载 | 免费
- 2开关电源基础知识
- 5.73 MB | 6次下载 | 免费
- 3100W短波放大电路图
- 0.05 MB | 4次下载 | 3 积分
- 4嵌入式linux-聊天程序设计
- 0.60 MB | 3次下载 | 免费
- 5基于FPGA的光纤通信系统的设计与实现
- 0.61 MB | 2次下载 | 免费
- 6基于FPGA的C8051F单片机开发板设计
- 0.70 MB | 2次下载 | 免费
- 751单片机窗帘控制器仿真程序
- 1.93 MB | 2次下载 | 免费
- 8基于51单片机的RGB调色灯程序仿真
- 0.86 MB | 2次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 2555集成电路应用800例(新编版)
- 0.00 MB | 33564次下载 | 免费
- 3接口电路图大全
- 未知 | 30323次下载 | 免费
- 4开关电源设计实例指南
- 未知 | 21548次下载 | 免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB | 15349次下载 | 免费
- 6数字电路基础pdf(下载)
- 未知 | 13750次下载 | 免费
- 7电子制作实例集锦 下载
- 未知 | 8113次下载 | 免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB | 6653次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935054次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537796次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191185次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183278次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138040次下载 | 免费
评论
查看更多