位置:51电子网 » 技术资料 » 嵌入式系统

μC/OSII 内核任务调度模块的分析与改进

发布时间:2008/5/27 0:00:00 访问次数:477

引 言:

  现今,嵌入式系统的应用已十分广泛,也是新兴计算模式如普适计算等的支撑技术之一。在嵌入式技术发展的初期,由于嵌入式系统控制的外设和执行的任务较少,利用简单的循环和少量模块调用即可满足要求。随着应用的复杂化,多数嵌入式操作系统都采用了微内核结构。在当前较流行的操作系统如vxworks、qnx、psos、windowsce、μc/osii以及rtlinux中,μc/osii是一个完整、可移植、可固化、可裁减的抢占式多任务内核,可用于各类8位、16位和32位单片机和dsp[1]。微内核与具体硬件环境相结合构成了嵌入式系统,硬件环境则通常由单片机为核心配合一些辅助电路和外围设备构成[2]。在嵌入式系统中使用的单片机较多,主要有80c51、avr和arm等系列。其中,arm系列的应用较为广泛,并包括多个系列,尤其是arm7系列更多用于多媒体和嵌入式设备,包括internet设备、网络和调制解调器设备以及移动电话和pda等无线设备,且开发环境容易获得,价格也较低廉。

  任务调度模块是嵌入式内核中最为核心的部分,任务调度算法的好坏以及执行效率直接关系到嵌入式内核的应用范围及实时性程度[3]。任务调度算法中,主要涉及的问题包括任务切换、现场保护以及优先级的确定和任务调度方法等。在应用中,必须将μc/osii内核中与此相关的代码移植到具体硬件环境下。理论上,可以有多种任务调度模块的移植方法,但选择一种适合硬件环境的方法至关重要。此外,由于μc/osii任务调度模块采用可抢占式的固定优先级分配方法,适用于较为简单的应用[4],而在实时系统中还有多种优先级的分配要求,这就要求在实际应用中对μc/osii的任务调度模块加以改造,以适应不同的优先级分配要求。当然,改造要以不破坏原系统的高效性为前提。

1 内核移植分析

  μc/osii内核较小,全部代码量约6000~7000行,共15个文件,其中90%的代码用c语言完成,已被移植到40多种单片机上[1]。任务调度模块中需要移植的与硬件环境相关的代码主要包括os_enter_critical、os_exit_critical和osctxsw模块,这里采用修改μc/osii的状态寄存器cpsr并模拟中断保存现场的方法来实现移植。

1.1μc/osii状态寄存器 

  程序状态寄存器cpsr包含条件码标志、中断禁止位和当前处理器模式以及其他状态和控制信息,其中的n(negative)、z(zero)、c(carry)和v(overflow)位为条件码标志,经常作为标志位引用,可供大多数指令作为是否执行的检测标志。cpsr的最低8位i、f、t 和m[4:0]用作控制位,其中的i、f 为中断禁止位,当i位置1禁止irq中断,而f位置1则禁止frq中断[5]。

1.2移植代码

  当任务切换时要先关中断,保存状态寄存器和各个通用寄存器的内容。在μc/osii中,这些功能由os_enter_critical宏、os_exit_critical宏和osctxsw()函数来实现[3]。os_enter_critical和os_exit_critical的功能分别为关中断和开中断,即将cpsr中的i、f 中断禁止位置1。实现代码如下。

① os_enter_critical宏#define os_enter_critical() irqfiqde
#define irqfiqde asm volatile ("stmfd sp!,{r0}");
//r0→堆栈中
asm volatile ("mrs r0,cpsr");
//cpsr→r0,需要修改r0
asm volatile ("stmfd sp!,{r0}");
//保存cpsr旧的值
asm volatile ("orr r0,r0,#0xc0");
//屏蔽irq和fiq
asm volatile ("msr cpsr_c,r0");

② os_exit_critical宏#define os_exit_critical() irqfiqre
#define irqfiqre asm volatile ("ldmfd sp!,{r0}");
//恢复旧的cpsr的值
asm volatile ("msr cpsr_c,r0");
//恢复cpsr 的控制位
asm volatile ("ldmfd sp!,{r0}");
//恢复旧的r0

  osctxsw()函数的主要功能是保存处理器寄存器和状态寄存器的内容,再将ospriohighrdy的值赋予ospriocur并恢复当前最高优先级任务的断点。因为此段代码为临界代码,所以在调用osctxsw()前要使用os_enter_critical()函数开中断,完成全部功能之后再使用os_exit_critical()函数关中断。这种移植方法的长处是实现简单,不需在用户状态与系统状态间转换,但由于使用宏而会占用较大空间。

2 任务调度算法分析

  任务管理、任务的调度与状态改变是任何内核必备的功能,其实现方法直接关系到系统的性能。对于某个任务需要创建任务控制块,以记录该任务执行的“上下文”,包括在某个特定时间点以前执行历史中尚未完成的任务,以及用于这些过程的局部变量在此时间点上的映像信息等。

  任务首先由ostaskcreate()和ostaskcreateext()函数创建,后者为前者的扩展,它们的主要功能是从空闲的os_tcb缓冲池中获得一个任务控制块,并用给定的参数初始化。任务的调度与切换由osshed()函数管理,它首先从就绪表中找出优先级最高的任务,再调用osctxsw()实现任务切换,这是与硬件相关而需要移植到具体芯片的

引 言:

  现今,嵌入式系统的应用已十分广泛,也是新兴计算模式如普适计算等的支撑技术之一。在嵌入式技术发展的初期,由于嵌入式系统控制的外设和执行的任务较少,利用简单的循环和少量模块调用即可满足要求。随着应用的复杂化,多数嵌入式操作系统都采用了微内核结构。在当前较流行的操作系统如vxworks、qnx、psos、windowsce、μc/osii以及rtlinux中,μc/osii是一个完整、可移植、可固化、可裁减的抢占式多任务内核,可用于各类8位、16位和32位单片机和dsp[1]。微内核与具体硬件环境相结合构成了嵌入式系统,硬件环境则通常由单片机为核心配合一些辅助电路和外围设备构成[2]。在嵌入式系统中使用的单片机较多,主要有80c51、avr和arm等系列。其中,arm系列的应用较为广泛,并包括多个系列,尤其是arm7系列更多用于多媒体和嵌入式设备,包括internet设备、网络和调制解调器设备以及移动电话和pda等无线设备,且开发环境容易获得,价格也较低廉。

  任务调度模块是嵌入式内核中最为核心的部分,任务调度算法的好坏以及执行效率直接关系到嵌入式内核的应用范围及实时性程度[3]。任务调度算法中,主要涉及的问题包括任务切换、现场保护以及优先级的确定和任务调度方法等。在应用中,必须将μc/osii内核中与此相关的代码移植到具体硬件环境下。理论上,可以有多种任务调度模块的移植方法,但选择一种适合硬件环境的方法至关重要。此外,由于μc/osii任务调度模块采用可抢占式的固定优先级分配方法,适用于较为简单的应用[4],而在实时系统中还有多种优先级的分配要求,这就要求在实际应用中对μc/osii的任务调度模块加以改造,以适应不同的优先级分配要求。当然,改造要以不破坏原系统的高效性为前提。

1 内核移植分析

  μc/osii内核较小,全部代码量约6000~7000行,共15个文件,其中90%的代码用c语言完成,已被移植到40多种单片机上[1]。任务调度模块中需要移植的与硬件环境相关的代码主要包括os_enter_critical、os_exit_critical和osctxsw模块,这里采用修改μc/osii的状态寄存器cpsr并模拟中断保存现场的方法来实现移植。

1.1μc/osii状态寄存器 

  程序状态寄存器cpsr包含条件码标志、中断禁止位和当前处理器模式以及其他状态和控制信息,其中的n(negative)、z(zero)、c(carry)和v(overflow)位为条件码标志,经常作为标志位引用,可供大多数指令作为是否执行的检测标志。cpsr的最低8位i、f、t 和m[4:0]用作控制位,其中的i、f 为中断禁止位,当i位置1禁止irq中断,而f位置1则禁止frq中断[5]。

1.2移植代码

  当任务切换时要先关中断,保存状态寄存器和各个通用寄存器的内容。在μc/osii中,这些功能由os_enter_critical宏、os_exit_critical宏和osctxsw()函数来实现[3]。os_enter_critical和os_exit_critical的功能分别为关中断和开中断,即将cpsr中的i、f 中断禁止位置1。实现代码如下。

① os_enter_critical宏#define os_enter_critical() irqfiqde
#define irqfiqde asm volatile ("stmfd sp!,{r0}");
//r0→堆栈中
asm volatile ("mrs r0,cpsr");
//cpsr→r0,需要修改r0
asm volatile ("stmfd sp!,{r0}");
//保存cpsr旧的值
asm volatile ("orr r0,r0,#0xc0");
//屏蔽irq和fiq
asm volatile ("msr cpsr_c,r0");

② os_exit_critical宏#define os_exit_critical() irqfiqre
#define irqfiqre asm volatile ("ldmfd sp!,{r0}");
//恢复旧的cpsr的值
asm volatile ("msr cpsr_c,r0");
//恢复cpsr 的控制位
asm volatile ("ldmfd sp!,{r0}");
//恢复旧的r0

  osctxsw()函数的主要功能是保存处理器寄存器和状态寄存器的内容,再将ospriohighrdy的值赋予ospriocur并恢复当前最高优先级任务的断点。因为此段代码为临界代码,所以在调用osctxsw()前要使用os_enter_critical()函数开中断,完成全部功能之后再使用os_exit_critical()函数关中断。这种移植方法的长处是实现简单,不需在用户状态与系统状态间转换,但由于使用宏而会占用较大空间。

2 任务调度算法分析

  任务管理、任务的调度与状态改变是任何内核必备的功能,其实现方法直接关系到系统的性能。对于某个任务需要创建任务控制块,以记录该任务执行的“上下文”,包括在某个特定时间点以前执行历史中尚未完成的任务,以及用于这些过程的局部变量在此时间点上的映像信息等。

  任务首先由ostaskcreate()和ostaskcreateext()函数创建,后者为前者的扩展,它们的主要功能是从空闲的os_tcb缓冲池中获得一个任务控制块,并用给定的参数初始化。任务的调度与切换由osshed()函数管理,它首先从就绪表中找出优先级最高的任务,再调用osctxsw()实现任务切换,这是与硬件相关而需要移植到具体芯片的

相关IC型号

热门点击

 

推荐技术资料

DFRobot—玩的就是
    如果说新车间的特点是“灵动”,FQPF12N60C那么... [详细]
版权所有:51dzw.COM
深圳服务热线:13692101218  13751165337
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式


 复制成功!