2.1.4 μC/OS的中断
中断是指在任务运行的过程中,收到内部或者外部异步事件的请求终止当前任务,而去处理异步事件所要求的任务的一个过程[13]。中断服务子程序(ISR)是在收到中断请求后,为响应其请求而运行的程序[14]。
μC/OS中断响应的过程可以描述为:当系统接收到中断请求时,如果此时CPU处于中断允许状态,微处理器执行完当前任务的某个语句,系统就会中止正在运行的当前任务,保存虚拟处理器现场,将堆栈中已经保存的当前正在执行的任务的现场调入虚拟存储器,而根据中断向量的指向去运行中断服务子程序;当中断服务子程序运行结束后,系统将会根据具体情况恢复执行被中止的任务,或者运行另一个优先级别更高的任务[15]。
μC/OS允许中断嵌套的发生,即高优先级别的中断源的中断请求可以中断低优先级别的中断服务程序的运行[16]。为此,μC/OS定义了一个全局变量OSInitNesting来记录中断嵌套的层数[17]。在编写μC/OS的中断服务程序时,要用到两个主要的函数:OSIntEnter()函数和OSIntExit()函数。在执行OSIntEnter()函数之后,全局变量OSInitNesting会加1,从而用它来记录中断嵌套的层数[18]。该函数通常在中断服务代码之前被调用。OSIntExit()函数的流程图如图2-1所示,该函数表示,如果中断嵌套层数为0且调度器未被锁定[19],则找到最高优先级别的就绪任务,如果该任务不是被中断的任务,则获得TCB指针,执行中断任务切换,否则就返回中断服务程序。
图2-1函数OSIntExit()流程图
2.1.5 μC/OS的特点
(1) μC/OS是一个抢占式或占先式的操作系统内核,已经处于就绪状态的高优先级任务可以抢占正处于运行状态的低优先级任务的CPU使用权[20]。这一特点大大增加了该系统的实时性。在中断服务程序中,高优先级任务通常会先进入就绪状态,当中断服务程序运行结束时,任务将会切换到该高优先级的任务。在μC/OS中,数据处理程序的优先级被提高,并在中断服务程序中进入就绪状态,这样数据处理程序就会在中断结束后得到立即执行。同时,μC/OS还把中断响应的时间限制在有限的范围内,大大提高了系统的实时性。
(2) μC/OS不支持时间片轮转调度算法,它主要基于优先级调度。μC/OS中,每一个任务的优先级必须是不同的,任务的优先级即为当前任务的标识,如果优先级相同,将无法正确区分任务。高优先级的任务会比优先级低的任务先获得CPU的使用权,只有当优先级高的任务交出CPU的使用权后,低优先级别的任务才会获得CPU的使用权。从时效性角度来说,实时性操作系统可以保证CPU使用权总是被高优先级的重要任务占有。但在系统的运行过程中,由于所有任务都要被赋予优先级,造成了系统资源的极大浪费,毕竟重要的任务是有限的。
(3) μC/OS为资源的共享提供了一种保护机制。μC/OS是一个多任务的操作系统,因此一个完整的程序可以包含许多个不同功能的任务。为了实现对资源的共享, μC/OS引入了信号量机制。首先,创建一个信号量并对其进行初始化。在这一过程中,如果有更高优先级任务进入就绪状态,但其并没有申请到共享资源信号量,则该任务不能使用共享资源。这一机制在μC/OS中被称为优先级反转[21]。所以我们必须深入了解μC/OS的信号量机制,才能正确处理任务间的资源共享。来!自~751论-文|网www.751com.cn
2.2 Cortex-M3/M4基础
2.2.1 Cortex-M3/M4通用寄存器
Cortex-M3/M4系列处理器包括通用寄存器R0~R15和一些特殊功能的寄存器。32位的Thumb-2指令可以访问寄存器R0~R15,R0~R12是用于“最通用目的”的寄存器,但是绝大多数的16位指令只能使用低组寄存器R0~R7[8]。R13是堆栈寄存器,该寄存器堆栈指针包括主堆栈指针MSP和进程堆栈指针PSP,但同时只能使用其中的一个。当操作系统复位后,默认的堆栈指针是主堆栈指针MSP。R14为连接寄存器,又被称为LR,主要用来存储返回地址。R15是程序计数寄存器,又被称为PC。如果要实现预定义的功能,则必须由专用的指令来访问特殊功能寄存器。特殊功能寄存器主要包括控制寄存器(CONTROL)、程序状态字寄存器组(PSRs)和中断屏蔽寄存器组(BASEPRI、PRIMASK、FUALTMASK)。其中,PSRs主要用来控制异常的使能和除能,包括应用程序PSR(APSR)、执行PSR(EPSR)和中断号PSR(IPSR)。控制寄存器CONTROL主要用来定义特权的级别并选择当前使用的指针