uC/OS-II在ARM微处理器上的移植

uC/OS-IIARM微处理器上的移植

引言:在开发嵌入式系统时,一般选择基于ARM uC/OS-II 的嵌入式开发平台,因为ARM 微处理器具有处理速度快、超低功耗、价格低廉、应用前景广泛等优点。uC/OS - II 是由Jean J . Labrosse 先生编写的完整的可移植、固化、裁剪的占先式实时多任务内核。uC/OS - II 结构简单,容易移植,适于学习。

   1.硬件平台要求

要使uC/OS – II可以正常工作,处理器必须满足如下工作要求:

1.  处理器的C编译器能产生可重入代码。

2.  在程序中可以打开或者关闭中断。

3.  处理器支持中断,并且能产生中断(通常10HZ~100HZ之间)。

4.  处理器支持能够容纳一定数据的硬件堆栈。

5.  处理器有将堆栈指针和其他CPU寄存器存储和读出到堆栈的指令。

ARM的大多数处理器完全满足上述要求。

下面是uC/OS的文件结构图:

 

应用软件

核心代码

Os_core.c  OS_FLAG.C

Os_task.c  OS_MUTEX.C

Os_mem.c

Os_q.c

Os_sem.c

Os_time.c

Os_ii.c      Os_ii.h

Os_mbox.c

 

设置代码

(应用相关)

Os_cfg.h

Includes.h

移植代码(处理器相关)

OS_CPU.H ,  OS_CPU_A.ASM ,  OS_CPU.C

2. 移植需要修改的部分

数据类型:BOOLEA INT8U, INT8S, INT16U, INT16S, INT32U, INT32S, FP32, FP64, OS_STK, OS_CPU_SR, 这些都在OS_CPU.H中。

宏与宏定义:OS_STK_GROWTHOS_ENTER_CRITICAL() OS_EXIT_CRITICAL() 它们都在OS_CPU.H中。

汇编函数:OSStartHighRdy(),OSCtxSw(),OSIntCtxSw(),OSTickISR(), 这三个在OS_CPU_A.ASM中,它们的修改相对比较复杂。

OS_CPU_C.C 中要修改的C语言函数:OSTaskStkInit(), OSInitHookBegin (void), OSInitHookEnd (void), OSTaskCreateHook (OS_TCB *ptcb), OSTaskDelHook (OS_TCB *ptcb),  OSTaskStatHook (void), OSTaskSwHook (void), OSTCBInitHook (OS_TCB *ptcb), OSTimeTickHook (void), OSTaskIdleHook (void)。这10个函数都修改只有OSTaskStkInit()的修改比较复杂,其他的函数很多都是空的。

3 与处理器和编译器相关的代码

1)与编译器相关的数据类型,放在OS_CPU.H

比如typedef unsigned char  INT8U;  // Unsigned 8 bit quantity   

2) OS_ENTER_CRITICAL() OS_EXIT_CRITICAL()

#define  OS_CRITICAL_METHOD    1//修改这一句就可以修改两个以上两个函数的定义?                

3OS_STK_GROWTH

定义堆栈的增长方向:#define  OS_STK_GROWTH       1  //从下往上

同理#define  OS_STK_GROWTH        0   //从上往下

4. OS_CPU_C. C及其6个用 C语言编写的函数  

1OSTaskStkInint()用于任务栈的初始化,在创建任务和异常的时候都会被调用到,

2OSTaskCreateHook (OS_TCB *ptcb)在创建任务和异常的时候都会被调用到,该函数调用时中断是被禁止的,所以要缩短代码,以缩短中断的相应时间。当它被调用时,回收到指向已建立任务的OS_TCB指针。

3OSTaskDelHook (OS_TCB *ptcb)收到被删除任务的OS_TCB指针。

4OSTaskSwHook ()任务切换是调用到,这个函数也要注意缩短响应时间。

5OSTaskStatHook (void)每秒钟都会被OSTasKStat()调用一次。用户可用它来扩展统计功能。

6OSTimeTickHook()在每个时钟节拍都会被OSTaskTick()调用。实际上是在节拍被uC/OS-II真正处理,并通知用户的移植实例或应用程序之前别调用的。

5个可以不用加代码只有OS_CFG.H中的OS_CPU_HOOKS_EN被置为1时才会产生这些函数的代码。

5. 用汇编语言编写的4个处理器相关的函数(OS_CPU_A.ASM

OS_CPU_A. S 文件的移植需要对处理器的寄存器进行操作,所以必须用汇编语言来编写。这个文件的实现集中体现了所要移植到处理器的体系结构和uC/OS-II 的移植原理。它包括4 个子函数:OSStartHighRdy() OSCtxSw() OSIntCtxSw() OSTick2ISR() 其中难点在于OSIntCtxSw() OSTickISR() 函数的实现,因为这两个函数的实现与移植者的移植思路以及相关硬件定时器、中断寄存器的设置有关。在实际的移植工作中,这两处也是比较容易出错的地方。

  OSIntCtxSw( ) 函数由OSIntExit ( ) 函数调用,而OSIntExit () 函数又由OSTickISR() 调用。OSIntCtxSw()函数最重要的作用就是它完成在中断ISR 中直接进行任务切换,从而提高了实时响应的速度。它发生的时机是在ISR 执行到OSIntExit ( ) 时,如果发现有高优先级的任务因为等待time_tick 的到来获得了执行。uC/OS-II ARM系统上的移植与实现的条件,就可以马上被调度执行,而不用返回被中断的那个任务之后再进行任务切换。实现OSIntCtxSw() 的方法大致也有两种情况:一是通过调整SP 堆栈指针的方法,根据所用的编译器对于函数嵌套的处理,通过精确计算出所需要调整的SP 位置来使得进入中断时所作的保护现场的工作可以被重用。 二是设置需要切换标志位的方法,在OSIntCtxSw( ) 里面不发生切换,而是设置一个需要切换的标志,等函数嵌套从进入OSIntExit ( ) = > OS ENTER CRITI2CAL() = > OSIntCtxSw( ) = > OS EXIT CRITICAL() = > OSIntExit ( ) 退出后,再根据标志位来判断是否需要进行中断级的任务切换。

其次是对OSTickISR() 修改,OSTickISR() 首先在被中断任务堆栈中保存CPU 寄存器的值,然后调用OSIntEnter () 。随后调用OSTimeTick() ,检查所有处于延时等待状态的任务,判断是否有延时结束就绪的任务。最后调用OSIntExit ( ) 。如果在中断中(或其他嵌套的中断) 有更高优先级的任务就绪,并且当前中断为中断嵌套的最后一层,OSIntExit ( ) 将进行任务调度。如果进行了任务调度,OSIntExit () 将不再返回调用者,而是用新任务的堆栈中的寄存器数值恢复CPU 现场,然后实现任务切换。如果当前中断不是中断嵌套的最后一层,或中断中没有改变任务的就绪状态,OSIntExit ( ) 将返回调用者OSTickISR ( ) OSTickISR() 返回被中断的任务。 最后就是退出临界区和进入临界区函数。 进入临界区时,必须关闭中断,用ARMDisableInt () 函数实现。在退出临界区的时候恢复原来的中断状态,通过ARMEnableInt ( ) 函数来实现。 至于进行任务级上下文切换,则是由汇编子程序OSCtxSw 实现。

应用软件

核心代码

Os_core.c  OS_FLAG.C

Os_task.c  OS_MUTEX.C

Os_mem.c

Os_q.c

Os_sem.c

Os_time.c

Os_ii.c      Os_ii.h

Os_mbox.c

 

设置代码

(应用相关)

Os_cfg.h

Includes.h

移植代码(处理器相关)

OS_CPU.H ,  OS_CPU_A.ASM ,  OS_CPU.C

[参考文章]

《嵌入式实时操作系统uC/OS-II》(第二版) Jean J.Labrosse 邵贝贝 等译

uC/OS-IIARM系统上的移植与实现》作者:李学桥、刘放美

《嵌入式系统设计与实例开发——基于ARM微处理器与uC/OS-II实时操作系统》(第二版)   王田苗 主编

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值