第3章 μCOS-II的中断和时钟
- 格式:ppt
- 大小:1.01 MB
- 文档页数:27
u c o s i i中文书邵贝贝集团标准化工作小组 [Q8QX9QT-X8QQB8Q8-NQ8QJ8-M8QMN]第5章时间管理在节时钟节拍中曾提到,μC/OS-Ⅱ(其它内核也一样)要求用户提供定时中断来实现延时与超时控制等功能。
这个定时中断叫做时钟节拍,它应该每秒发生10至100次。
时钟节拍的实际频率是由用户的应用程序决定的。
时钟节拍的频率越高,系统的负荷就越重。
节讨论了时钟的中断服务子程序和节时钟节函数OSTimeTick——该函数用于通知μC/OS-Ⅱ发生了时钟节拍中断。
本章主要讲述五个与时钟节拍有关的系统服务:OSTimeDly()OSTimeDlyHMSM()OSTimeDlyResume()OSTimeGet()OSTimeSet()本章所提到的函数可以在文件中找到。
5.0任务延时函数,OSTimeDly()μC/OS-Ⅱ提供了这样一个系统服务:申请该服务的任务可以延时一段时间,这段时间的长短是用时钟节拍的数目来确定的。
实现这个系统服务的函数叫做OSTimeDly()。
调用该函数会使μC/OS-Ⅱ进行一次任务调度,并且执行下一个优先级最高的就绪态任务。
任务调用OSTimeDly()后,一旦规定的时间期满或者有其它的任务通过调用OSTimeDlyResume()取消了延时,它就会马上进入就绪状态。
注意,只有当该任务在所有就绪任务中具有最高的优先级时,它才会立即运行。
程序清单所示的是任务延时函数OSTimeDly()的代码。
用户的应用程序是通过提供延时的时钟节拍数——一个1 到65535之间的数,来调用该函数的。
如果用户指定0值[(1)],则表明用户不想延时任务,函数会立即返回到调用者。
非0值会使得任务延时函数OSTimeDly()将当前任务从就绪表中移除[(2)]。
接着,这个延时节拍数会被保存在当前任务的OS_TCB中[(3)],并且通过OSTimeTick()每隔一个时钟节拍就减少一个延时节拍数。
第3章内核结构 (1)3.0 临界段(Critical Sections) (1)3.1 任务 (1)3.2 任务状态 (3)3.3 任务控制块(Task Control Blocks, OS_TCBs) (4)3.4 就绪表(Ready List) (7)3.5 任务调度(Task Scheduling) (10)3.6 给调度器上锁和开锁(Locking and UnLocking the Scheduler) (11)3.7 空闲任务(Idle Task) (12)3.8 统计任务 (13)3.9 µC/OS中的中断处理 (16)3.10 时钟节拍 (20)3.11 µC/OS-Ⅱ初始化 (23)3.12 µC/OS-Ⅱ的启动 (24)3.13 获取当前μC/OS-Ⅱ的版本号 (27)3.14 OSEvent???()函数 (28)I第3章内核结构本章给出μC/OS-Ⅱ的主要结构概貌。
读者将学习以下一些内容;μC/OS-Ⅱ是怎样处理临界段代码的;什么是任务,怎样把用户的任务交给μC/OS-Ⅱ;任务是怎样调度的;应用程序CPU的利用率是多少,μC/OS-Ⅱ是怎样知道的;怎样写中断服务子程序;什么是时钟节拍,μC/OS-Ⅱ是怎样处理时钟节拍的;μC/OS-Ⅱ是怎样初始化的,以及怎样启动多任务;本章还描述以下函数,这些服务于应用程序:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),OSInit(),OSStart(),OSIntEnter()和OSIntExit(),OSSchedLock()和OSSchedUnlock(), 以及OSVersion().(Critical Sections)s)s)3.0临界段临界段(Critical Section(Critical Section和其它内核一样,μC/OS-Ⅱ为了处理临界段代码需要关中断,处理完毕后再开中断。
μCOS-Ⅱ用户指南参考手册本章提供了μC/OS-Ⅱ的用户指南。
每一个用户可以调用的内核函数都按字母顺序加以说明,包括:z函数的功能描述z函数原型z函数名称及源代码z函数使用到的常量z函数参数z函数返回值z特殊说明和注意点OSInit()VoidOSInit(void);所属文件调用者开关量OS_CORE.C启动代码无OSinit()初始化μC/OS-Ⅱ,对这个函数的调用必须在调用OSStart()函数之前,而OSStart()函数真正开始运行多任务。
注意/警告必须先于OSStart()函数的调用OSIntEnter()VoidOSIntEnter(void);所属文件调用者开关量OS_CORE.C中断无OSIntEnter()通知μC/OS-Ⅱ一个中断处理函数正在执行,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。
OSIntEnter()函数通常和OSIntE 某it()函数联合使用。
注意/警告在任务级不能调用该函数。
如果系统使用的处理器能够执行自动的独立执行读取-修改-写入的操作,那么就可以直接递增中断嵌套层数(OSIntNeting),这样可以避免调用函数所带来的额外的开销。
OSIntE某it()voidOSIntE某it(void);所属文件调用者开关量OS_CORE.C中断无OSIntE某it()通知μC/OS-Ⅱ一个中断服务已执行完毕,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。
通常OSIntE某it()和OSIntEnter ()联合使用。
当最后一层嵌套的中断执行完毕后,如果有更高优先级的任务准备就绪,μC/OS-Ⅱ会调用任务调度函数,在这种情况下,中断返回到更高优先级的任务而不是被中断了的任务。
注意/警告在任务级不能调用该函数。
并且即使没有调用OSIntEnter()而是使用直接递增OSIntNeting的方法,也必须调用OSIntE某it()函数。
OSMbo某Accept()Void某OSMbo某Accept(OS_EVENT某pevent);所属文件调用者开关量OS_MBO某.C任务或中断OS_MBO某_EN参数返回值注意/警告OSMbo某Create()OS_EVENT某OSMbo某Create(void某mg);所属文件调用者开关量OS_MBO某.C任务或启动代码OS_MBO某_EN务发送消息。
Ucos-II基础原理讲解,任务创建及中断问题2013-6-26 周三Haibara AI Ucos-II在移植过程中的特性,首先要理解所加入的实时操作系统是一个给予定时器节拍的系统。
怎么理解这个问题呢,由该定时器产生脉冲来驱动不同的任务调度,且由于该系统是基于可剥夺内核类型,任务之间的切换时间间隔也由该定时器完成。
不宜过大,否则会造成CPU利用率不高,不宜过小,否则会造成CPU在执行任务时非常被动,时间特别赶。
就想人的心脏一样,动力是固定的,你非要去跑个100公里,心脏不加速你是会窒息而死的。
我们正常心脏跳动是60次左右,同样,单片机也需要一个这样的相对宽松的节拍驱动。
注:众所周知,脉冲本质上仍由晶振提供(或实时时钟),原理都一样,再次请各位不要较真,就暂时以晶振为例。
大家可以考虑一下,晶振的作用是否特别类似于人体的心脏呢?答案是很显然的。
心脏跳动给人体提供输送血液和养料的压力,晶振的设计原理也正是源于此。
他可以像人体心脏一样提供动力输送各个外设(相当于人体器官)所需要的能量。
说这么多,就是要大家理解,人可以实时做出反应,因为人是有生命的,也就是他有反应、判断和处理能力,可以决定什么时间应该做什么。
但是单片机是没有生命的,换句话说,他所谓的处理能力源于人们的代码和程序。
那么,怎么让单片机像人一样拥有生命呢?答案很简单,给他指令,帮助他决定什么时间该做什么,这也就是所谓的实时操作系统。
不只是ucos,其他实时操作系统也是这个道理。
下面我以代码为例,讲述一下ucos的工作流程,如有错误,还请各位前辈指点。
首先任务是怎么样开始执行的?os_err = OSTaskCreateExt((void (*)(void *)) App_TaskStart, */1 (void * ) 0, 2(OS_STK * )&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],3(INT8U ) APP_TASK_START_PRIO,4(INT16U ) APP_TASK_START_PRIO,5(OS_STK * )&App_TaskStartStk[0],6(INT32U ) APP_TASK_START_STK_SIZE,7(void * )0,8(INT16U )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK));9这个东西好像是非常复杂,但是实际上并不需要细究(当然非要细究也是允许的,只不过是C语言而已,看也不是看不懂,对于初学者而言并不推荐而已)。
第3章内核结构 (1)3.0 临界段(Critical Sections) (1)3.1 任务 (1)3.2 任务状态 (3)3.3 任务控制块(Task Control Blocks, OS_TCBs) (4)3.4 就绪表(Ready List) (7)3.5 任务调度(Task Scheduling) (10)3.6 给调度器上锁和开锁(Locking and UnLocking the Scheduler) (11)3.7 空闲任务(Idle Task) (12)3.8 统计任务 (13)3.9 μC/OS中的中断处理 (16)3.10 时钟节拍 (20)3.11 μC/OS-Ⅱ初始化 (23)3.12 μC/OS-Ⅱ的启动 (24)3.13 获取当前μC/OS-Ⅱ的版本号 (27)3.14 OSEvent???()函数 (28)I第3章内核结构本章给出μC/OS-Ⅱ的主要结构概貌。
读者将学习以下一些内容;●μC/OS-Ⅱ是怎样处理临界段代码的;●什么是任务,怎样把用户的任务交给μC/OS-Ⅱ;●任务是怎样调度的;●应用程序CPU的利用率是多少,μC/OS-Ⅱ是怎样知道的;●怎样写中断服务子程序;●什么是时钟节拍,μC/OS-Ⅱ是怎样处理时钟节拍的;●μC/OS-Ⅱ是怎样初始化的,以及●怎样启动多任务;本章还描述以下函数,这些服务于应用程序:●OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),●OSInit(),●OSStart(),●OSIntEnter()和OSIntExit(),●OSSchedLock()和OSSchedUnlock(), 以及●OSVersion().3.0临界段(Critical Sections)和其它内核一样,μC/OS-Ⅱ为了处理临界段代码需要关中断,处理完毕后再开中断。
这使得μC/OS-Ⅱ能够避免同时有其它任务或中断服务进入临界段代码。
一. UCOSII的中断过程简介系统接收到中断请求后,如果CPU处于开中断状态,系统就会中止正在运行的当前任务,而按中断向量的指向去运行中断服务子程序,当中断服务子程序运行完成后,系统会根据具体情况返回到被中止的任务继续运行,或转向另一个中断优先级别更高的就绪任务。
由于UCOS II是可剥夺型的内核,所以中断服务程序结束后,系统会根据实际情况进行一次任务调度,如果有优先级更高的任务,就去执行优先级更高的任务,而不一定要返回被中断了的任务。
二.UCOSII的中断过程的示意图三.具体中断过程1.中断到来,如果被CPU识别,CPU将查中断向量表,根据中断向量表,获得中断服务子程序的入口地址。
2.将CPU寄存器的内容压入当前任务的任务堆栈中(依处理器的而定,也可能压入被压入被中断了的任务堆栈中。
3.通知操作系统将进入中断服务子程序。
即:调用OSIntEnter()或OSIntNesting直接加1。
4.If(OSIntNesting==1){OSTCBCur->OSTCBStrPtr=SP;} //如果是第一层中断,则将堆栈指针保存到被中断任务的任务控制块中5.清中断源,否则在开中断后,这类中断将反复的打入,导致系统崩贵6.执行用户ISR7.中断服务完成后,调用OSIntExit().如果没有高优先级的任务被中断服务子程序激活而进入就绪态,那么就执行被中断了的任务,且只占用很短的时间.8.恢复所有CPU寄存器的值.9.执行中断返回指令.四.相关代码与编译器相关的数据类型:typedef unsigned char BOOLEAN;typedef unsigned char INT8U;typedef unsigned int OS_STK; //堆栈入口宽度为16 位(一) void OSIntEnter (void)的理解uCOS_II.H中定义:#ifdef OS_GLOBALS#define OS_EXT#else#define OS_EXT extern#endif //定义全局宏OS_EXT#ifndef TRUE#define TRUE 1#endifOS_EXT BOOLEAN OSRunning; //定义外部BOOLEAN类型全局变量,用来指示//核是否在运行OS_EXT INT8U OSIntNesting;//定义外部8位无符号整型数全局变量,用来表//示中断嵌套层数OS_CORE.C中的OSIntEnter()函数原型:void OSIntEnter (void){if (OSRunning == TRUE) //如果内核正在运行则进入if{if (OSIntNesting < 255) //如果嵌套层数小于255,则可以继//续{OSIntNesting++; //嵌套层数加1}}}(二)在中断服务子程序中加if ( OSIntNesting == 1){…}的原因uCOS_II.H中定义:typedef struct os_tcb {OS_STK *OSTCBStkPtr;//声明指向任务堆栈栈顶的16位指针………………} OS_TCB;//定义名为OS_TCB的结构体数据类型,即任务控制块的数据结构OS_EXT OS_TCB *OSTCBCur;//声明一个指向任务控制块的全局指针变量//用于指向当前任务的任务控制块中断服务程序中添加的代码:if ( OSIntNesting == 1){OSTCBCur->OSTCBStkPtr = SP; // 如果是第一层中断,则将被中断任务//的堆栈指针保存在被中断任务的任务//任务控制块中}关于uCOS-II的中断服务程序(ISR)中必须加“OSIntNesting == 1”的原因==避免调整堆栈指针.出现这个问题的根源是当低优先级的任务被中断,当中断完成后由于有高优先级的任务就绪,则必须调度高优先级的任务,原来的低优先级任务继续被中断着,但是此时的低优先级任务的堆栈已经被破坏,已不能被调度程序直接调度了,要想被调度而必须调整堆栈指针。
第一章1.什么是计算机的操作系统?它应具备什么功能?操作系统:操作系统是控制其他程序运行,管理系统资源并为用户提供操作界面的系统软件的集合。
功能:计算机资源的管理,包括处理器管理、存储器存储空间管理、外部输入输出(/o)设备管理、文件管理、网络和通信管理、提供用户接口。
2.简述嵌入式系统与普通操作系统的区别。
嵌入到对象体系中,为实现对象体系智能化控制的计算机系统,简称嵌入式系统。
嵌入式系统应具有的特点是:高可靠性;在恶劣的环境或突然断电的情况下,系统仍然能够正常工作;许多嵌入式应用要求实时性,这就要求嵌入式操作系统具有实时处理能力;嵌入式系统和具体应用有机地结合在一起,它的升级换代也是具体产品同步进行;嵌入式系统中的软件代码要求高质量、高可靠性,一般都固化在只读存储器中或闪存中,也就是说软件要求固态化存储,而不是存储在磁盘等载体中。
4.什么是实时系统?如果一个系统能及时响应外部事件的请求,并能在规定的时间内完成对事件的处理,这种系统称为实时系统。
第二章1.什么是可剥夺型内核?可剥夺型内核采用与不可剥夺型不同的调度策略,最高优先级的任务一旦就绪,就能获得CPU的控制权而得以运行,不管当前运行的任务处于何种状态。
可剥夺型内核采用的抢占式的调度策略,总是让优先级最高的任务运行,直到其阻塞或任务完成,响应时间因此优化。
2.一个应用程序为什么一定要使用空闲任务?在多任务系统运行时,系统经常会在某个时间内无用户任务运行而处于空闲状态,为了使CPU在此时有事可作,uC/OS-提供了空闲任务OSTaskldle。
空闲任务是不能被软件删除的。
3.统计任务是必须使用的吗?用户应用程序可根据实际需要来选择是否使用统计任务。
其功能是每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUsage中,以便应用程序通过访问它来了解CPU的利用率。
4.什么是任务的优先权?UC/oS-ll是用什么来描述任务的优先权的。
嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)嵌入式实时操作系统μCOSII原理及应用习题答案(第四版)嵌入式操作系统是一种特殊的操作系统,用于控制和管理嵌入式系统。
实时操作系统(RTOS)是一种在给定的时间约束下,能够及时响应外部事件的操作系统。
μC/OS-II是一种广泛应用于嵌入式系统的实时操作系统。
本文将介绍μC/OS-II的原理及应用,并提供第四版的习题答案。
一、μC/OS-II原理1. 任务(Task)管理:μC/OS-II采用优先级抢占式调度算法,支持多任务。
每个任务具有自己的任务控制块(TCB),用于记录任务的状态、优先级、堆栈等信息。
任务之间可以通过任务切换进行调度,具有不同的优先级来确保系统的实时性。
2. 信号量(Semaphore)机制:信号量用于任务之间的同步和互斥操作。
μC/OS-II提供了两种信号量机制:二值信号量和计数信号量。
二值信号量用于任务之间的互斥操作,而计数信号量用于任务之间的同步操作。
3. 事件标志组(Event Flag Group)机制:事件标志组用于任务之间的同步和通信操作。
一个事件标志组中可以包含多个事件标志位,每个标志位都可以独立设置或清除。
任务可以等待一个或多个事件标志位的发生,并在发生时得到通知。
4. 消息邮箱(Mailbox)机制:消息邮箱用于任务之间的通信。
每个消息邮箱中可以存放一个或多个消息,任务可以通过发送和接收消息来进行通信。
消息邮箱还支持阻塞和非阻塞两种方式。
5. 定时器(Timer)管理:μC/OS-II提供了软件定时器的功能,可以设置定时器来触发任务或其他操作。
定时器可以基于时间片、滴答定时器或硬件定时器实现。
二、μC/OS-II应用1. 实时任务调度:μC/OS-II可以在多个任务之间进行优先级调度,保证任务的及时执行。
通过设置任务的优先级和时间片,可以确保高优先级任务优先执行,从而满足实时性要求。
同时,μC/OS-II还提供了任务切换和上下文切换机制,确保任务之间的切换及时有效。
一. UCOSII的中断过程简介系统接收到中断请求后,如果CPU处于开中断状态,系统就会中止正在运行的当前任务,而按中断向量的指向去运行中断服务子程序,当中断服务子程序运行完成后,系统会根据具体情况返回到被中止的任务继续运行,或转向另一个中断优先级别更高的就绪任务。
由于UCOSII是可剥夺型的内核,所以中断服务程序结束后,系统会根据实际情况进行一次任务调度,如果有优先级更高的任务,就去执行优先级更高的任务,而不一定要返回被中断了的任务。
二.UCOSII的中断过程的示意图三.具体中断过程1.中断到来,如果被CPU识别,CPU将查中断向量表,根据中断向量表,获得中断服务子程序的入口地址。
2.将CPU寄存器的内容压入当前任务的任务堆栈中(依处理器的而定,也可能压入被压入被中断了的任务堆栈中。
3.通知操作系统将进入中断服务子程序。
即:调用OSInt Enter()或OSIntN esting直接加1。
4.If(OSIntNe sting==1) {OSTCBCu r->OSTCBSt rPtr=SP;} //如果是第一层中断,则将堆栈指针保存到被中断任务的任务控制块中5.清中断源,否则在开中断后,这类中断将反复的打入,导致系统崩贵6.执行用户ISR7.中断服务完成后,调用OSInt Exit().如果没有高优先级的任务被中断服务子程序激活而进入就绪态,那么就执行被中断了的任务,且只占用很短的时间.8.恢复所有CPU寄存器的值.9.执行中断返回指令.四.相关代码与编译器相关的数据类型:typedef unsigne d char BOOLEAN;typedef unsigne d char INT8U;typedef unsigne d int OS_STK; //堆栈入口宽度为16 位(一) void OSIntEn ter (void)的理解uCOS_II.H中定义:#ifdef OS_GLOB ALS#define OS_EXT#else#define OS_EXT extern#endif //定义全局宏OS_EXT#ifndefTRUE#defineTRUE 1#endifOS_EXT BOOLEAN OSRunni ng; //定义外部BOO LEAN类型全局变量,用来指示//核是否在运行OS_EXT INT8U OSIntNe sting;//定义外部8位无符号整型数全局变量,用来表//示中断嵌套层数OS_CORE.C中的OSIn tEnter()函数原型:void OSIntEn ter (void){if (OSRunni ng == TRUE) //如果内核正在运行则进入if{if (OSIntNe sting< 255) //如果嵌套层数小于255,则可以继//续{OSIntNe sting++; //嵌套层数加1}}}(二)在中断服务子程序中加if( OSIntNe sting==1){…}的原因uCOS_II.H中定义:typedef structos_tcb{OS_STK *OSTCBSt kPtr;//声明指向任务堆栈栈顶的16位指针………………} OS_TCB;//定义名为OS_TCB的结构体数据类型,即任务控制块的数据结构OS_EXT OS_TCB *OSTCBCu r;//声明一个指向任务控制块的全局指针变量//用于指向当前任务的任务控制块中断服务程序中添加的代码:if ( OSIntNe sting== 1){OSTCBCu r->OSTCBSt kPtr = SP; // 如果是第一层中断,则将被中断任务//的堆栈指针保存在被中断任务的任务//任务控制块中}关于uCOS-II的中断服务程序(ISR)中必须加“OSIntNe sting==1”的原因==避免调整堆栈指针.出现这个问题的根源是当低优先级的任务被中断,当中断完成后由于有高优先级的任务就绪,则必须调度高优先级的任务,原来的低优先级任务继续被中断着,但是此时的低优先级任务的堆栈已经被破坏,已不能被调度程序直接调度了,要想被调度而必须调整堆栈指针。
UC/OS-II中断相关的问题要弄清楚以下函数的意义:OSTimeTick()在OS_CORE.C中,为时钟管理函数。
OSTickISR( )在OS_CPU_A.S中以汇编的形式编写。
任何计算机系统都应该有一系统时钟,UCOS系统的系统时钟是通过硬件定时器产生中断来实现的,这个中断会产生一个时钟中断服务程序,时钟中断服务程序也叫做节拍服务。
各个任务运行都需要一个周期性的信号指示,即每一个任务允许运行的时间片是多少,必须规定好。
这个时间片就是系统时钟节拍UCOS系统响应中断的过程:系统正在运行任务,此时有中断发生,且系统收到了中断请求(系统如何收到中断请求,中断以何种方式告知操作系统?)。
如果处理器处于中断允许状态,系统就中止当前任务的运行,而按照中断向量去执行相应的中断服务程序;中断服务自程序结束前,会进行一次任务调度。
这样中断结束后,系统将会根据情况返回到被中止的任务继续运行,或者转到另外一个具有更高优先级的就绪任务上运行。
全局变量OSIntNesting有两个用途:第一是用来记录中断嵌套的层数,中断嵌套也就是说当第一个中断发生而没有结束的时候,又发生了第二个更重要的中断,依次类推,此时OSIntNesting就用来表示嵌套的层数,也就是有多少个中断在发生或者等待处理,也就是说每当有中断发生时,就将OSIntNesting加1,有中断结束的时候,就将OSIntNesting减1;第二是作为调度器是否可进行调度的标志,以保证调度器不会在中断服务程序中进行任务调度,也就是当OSIntNesting大于0的时候,将调度器加锁,OSIntNesting等于0的时候,调度器解锁。
(这样理解调度器的加锁和解锁,是否正确?中断服务自程序结束前,会进行一次任务调度。
这个时候调度器不是锁上的吗?如何调度呢?)UCOS用两个函数OSIntEnter (void)和OSIntExit (void)来处理变量SIntNesting。
引言嵌入式实时系统要求系统有很好的实时性,能够及时处理各种异常事件,因此中断系统是嵌入式实时系统的重要组成部分,其时间和空间性能对嵌入式实时系统性能的影响至关重要。
要想缩短嵌入式实时系统的中断响应时间并提高系统中断处理效率,合理地设计中断系统非常关键。
S3C44BOX是三星公司基于ARM7TDMI内核的微处理器,支持IRQ和FIQ中断请求,同时还支持向量中断,以缩短中断响应时间。
嵌入式实时操作系统μC/OS-II提供了简单的中断管理机制对系统中断进行统一管理,但是对于不同的微处理器没有给出具体的中断处理方法。
本文在深入分析S3C448OX中断控制系统和μC/OS-II中断管理机制的基础上,进行中断系统设计,使之能更好地满足实际应用的需求。
1 S3C4480X中断系统图1所示为S3C44BOX的中断系统结构框图。
中断控制器的任务是在片内外围和片外中断源组成的多重中断发生时,经过优先级判断、选择其中一个中断;通过IRQ或FIQ向ARM7内核发出IRQ或FIQ中断请求,ARM7内核从中断控制器中获取中断信息,然后对中断进行处理,控制中断设备的操作过程。
当ARM7内核接收到中断控制器的中断请求时会自动执行以下几步操作,以实现中断环境保护和程序跳转:①将程序状态寄存器CPSR的内容保存到将要执行的中断模式的程序状态保存寄存器SPSR中,以实现对处理器当前状态、中断屏蔽位和各条件标志位的保存。
②设置当前CPSR中的相应位,屏蔽相应中断并切换处理器模式。
③将引起中断指令的下一条指令的地址(断点地址)保存到中断模式的子程序链接寄存器LR中,使中断服务程序执行完后能正确返回原程序。
④给程序计数器PC强制赋值,使程序从相应的向量地址开始执行中断服务程序。
当中断服务程序执行完后,需要执行以下几步操作从中断服务程序中返回:①从中断模式堆栈中恢复所有修改过的通用寄存器(RO~R12)。
②将中断模式SPSR寄存器的内容复制到CPSR中,恢复被中断模式程序的工作状态。
第三章内核结构3.00 临界段,OS_ENTER_CRITICAL() 和 OS_EXIT_CRITICAL()3种方法实现上边两个函数:(1) OS_CRITICAL_METHOD==1,用关中断实现OS_ENTER_CRITICAL,用开中断实现OS_EXIT_CRITLCAL();此方法的缺点是如果进入该函数前系统的中断状态是关中断,调用函数后则会改变其中断状态。
(2)OS_CRITICAL_METHOD==2, 用在堆栈中保存现在的中断开关状态,然后关中断来实现OS_ENTER_CRITICAL,用从堆栈中弹出原来的中断状态来实现OS_EXIT_CRITICAL();此方法存在的问题是:有些编译器不够灵敏,不能正确进行出入栈操作而引起严重错误。
(3)OS_CRITICAL_METHOD==3,用户可以得到当前处理器的状态字值,并保存在一个C函数的局部变量里,这个变量可以用于恢复PSW。
3.01 任务Ucosii 最多管理64个任务,但有些被系统保留,所以推荐使用其中的56个,不用前4个和后4个;为了使ucosii管理用户任务,必须在建立任务时,将任务的起始地址与其他参数传递给OSTaskCreate()或OSTaskCreateExt()中的一个。
3.02任务状态(睡眠态、就绪态、运行态、中断服务态、等待态)当所有任务都在等待事件的发生或等待延迟时间的结束时,ucosii执行空闲任务OSTaskIdle().3.03任务控制块(OS_TCB)一旦任务建立,一个任务控制块OS_TCB就被赋值,任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,任务控制块用来保存该任务的状态,当任务重新得到CPU的使用权时,任务控制块能确保任务从当时被中断的那一点继续执行。
OS_TCB全部驻留在RAM中。
3.04就绪表每个就绪的任务都放在就绪表(ready list)中,就绪表中有两个变量:OSRdyGrp 和OSRdyTbl[]. 找出进入就绪态的优先级最高的任务的办法(ucosii提供了一个表OSUnMapTbl[]): y = OSUnMapTbl[OSRdyGrp]; x =OSUnMapTbl[OSRdyTbl[y]]; prio = (y<<3) + x ;附:若从就绪表的两个变量,通过查找法或直观地看,也可以找到处于就绪态的优先级最高的任务,但是比较麻烦,ucosii加入了算法,通过查表的办法可以直接得到处于就绪态的优先级最高的任务,比较方便。
ucos ii时钟中断技术介绍一、ucos ii时钟管理系统ucos ii原有的时钟管理系统类似于Linux,但是比Linux简单得多。
它仅向用户提供一个周期性的信号OSTime,时钟频率可以设置在10~100 Hz,时钟硬件周期性地向CPU发出时钟中断,系统周期性响应时钟中断,每次时钟中断到来时,中断处理程序更新一个全局变量OSTime。
ucos ii时钟中断服务程序的核心是调用OSTimeTick ()函数。
OSTimeTick ()函数用来判断延时任务是否延时结束从而将其置于就绪态。
其程序伪代码如下:void OSTimeTick(void) {OSTimeTickHook();// 调用用户定义的时钟节拍外连函数while { (除空闲任务外的所有任务)OS_ENTER_CRITICAL();//关中断对所有任务的延时时间递减;扫描时间到期的任务,并且唤醒该任务;OS_EXIT_CRITICAL();//开中断指针指向下一个任务;}OSTime++;//累计从开机以来的时间}在ucos ii的时钟节拍函数中,需要执行用户定义的时钟节拍外连函数OSTimeTickHook (),以及对任务链表进行扫描并且递减任务的延时。
这样就造成了时钟节拍函数OSTimeTick ()有两点不足:1、在时钟中断中处理额外的任务OSTimeIickHook (),这样增加了中断处理的负担,影响了定时服务的准确性;2、在关中断情况下扫描任务链表,任务越多所需要时间越长,而长时间关中断对中断响应有不利影响,是中断处理应当避免的。
二、改进的时钟管理系统针对上述OSTimeTick ()的不足之处,需加以改进来优化时钟节拍函数。
在Linux中一般对中断的响应分为两部分:立即中断服务和底半中断处理(bottom half)。
立即中断服务仅仅做重要的并且能快速完成的工作,而把不太重要的需要较长时间完成的工作放在底半处理部分来完成,这样就可以提高中断响应速度。