ucosII移植笔记

这篇博客详细介绍了μC/OS-II操作系统在不同CPU上的临界区管理机制,包括OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()的三种实现方式。同时,讲解了μC/OS-II的文件结构,特别是OS_CPU.H的编写,包括数据类型的定义和任务切换宏的配置,以及进入和退出临界区的方法。内容适合嵌入式开发者参考。

μC/OS-II临界区管理机制

OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()

同样是通过关中断来保护临界区,OS_ENTER_CRITICAL/OS_EXIT_CRITICAL一共实现了三种实现方式,如下所示:

 

#if OS_CRITICAL_METHOD == 1  

#define OS_ENTER_CRITICAL() __asm__("cli")  

#define OS_EXIT_CRITICAL() __asm__("sti")  

#endif  

 

#if OS_CRITICAL_METHOD == 2  

#define OS_ENTER_CRITICAL() __asm__("pushf \n\t cli")  

#define OS_EXIT_CRITICAL() __asm__("popf")  

#endif  

 

#if OS_CRITICAL_METHOD == 3  

#define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR())  

#define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr))  

#endif  

 

移植

一、 μC/OS-II的文件结构

    第一种方式,OS_ENTER_CRITICAL()简单地关中断,OS_EXIT_CRITICAL()简单地开中断。这种方式虽然简单高效,但无法满足嵌套的情况。如果有两层临界区保护,在退出内层临界区时就会开中断,使外层的临界区也失去保护。虽然ucos的内核写的足够好,没有明显嵌套临界区的情况,但谁也无法保证一定没有,无法保证今后没有,无法保证在附加的驱动或什么位置没有,所以基本上第一种方法是没有人用的。ucos的系统函数中通常含会有一段代码进入临界状态,故使用这种方式非常不可靠。

    第二种方式,先将中断状态保存到堆栈,再关中断;执行OS_EXIT_CRITICAL时,从堆栈中恢复原来的中断状态。缺点,当用户使用的处理器有堆栈指针相对寻址模式时,可能出现严重错误。

    第三种方式,些编译器提供了扩展功能,用户可以得到当前处理器状态字的值,并将其保存在C函数局部变量之中。

相关临界代码如下

    OS_CPU_SR  cpu_sr

    cpu_sr  =  get_processor_psw();//获取状态字

    disable_interrupts();//关中断

    set_processor_psw();//恢复状态字

文件结构

   μC/OS-II提供有1112个内核文件:

·<os_core.c>

·<os_flag.c>

·<os_mbox.c>

·<os_mem.c>

·<os_mutex.c>

·<os_q.c>

·<os_sem.c>

·<os_task.c>

·<os_time.c>

·<os_tmr.c>

·<ucos_ii.h>

·可能还有<ucos_ii.c>

 

    注意到,在1112个内核文件中,只有1.H文件<ucos_ii.h>,在此头文件中,有

/*

*********************************************************************************************************

*                                           INCLUDE HEADER FILES

*********************************************************************************************************

*/

 

#include <app_cfg.h>

#include <os_cfg.h>

#include <os_cpu.h>

 

注意到,此处的三个头文件<app_cfg.h> <os_cfg.h> <os_cpu.h>μC/OS-II官方都没有提供。

<app_cfg.h> :用户配置文件,旧版本用<includes.h>表示

<os_cfg.h> :用于对ucos-ii内核的裁剪。可以直接参考<os_cfg_r.h>文件,若没有,则可在工程模板中寻找,然后根据自己的徐秀

<os_cpu.h> :与CPU或编译平台相关的配置,如变量类型定义、进入临界状态的方式、任务调度的实现等。需用户自行建立,而有些cpu官方有提供模板。

    μC/OS-II除了提供上面1112个内核文件外,可能还提供了:

·<os_cfg_r.h>

    作为<os_cfg.h>的参考,ucos-ii的配置头文件,如果没有提供,可以在ucos-ii的工程模板中寻找<os_cfg.h>文件;

·<os_dbg_r.c>

作为<os_dbg.h>的参考,ucos-ii的调试文件。

 

  继续观察<ucos_ii.h>

/*

*********************************************************************************************************

*                                          FUNCTION PROTOTYPES

*

* IMPORTANT: These prototypes MUST be placed in OS_CPU.H

*********************************************************************************************************

*/

 

#if 0

void          OSStartHighRdy          (void);

void          OSIntCtxSw              (void);

void          OSCtxSw                 (void);

#endif

 

3个函数要在<OS_CPU.H>中创建

二、 OS_CPU.H的编写

//////////////////////////////////////////////////////////

//  OS_CPU.H文件的移植

//////////////////////////////////////////////////////////

OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。

#ifdef  OS_CPU_GLOBALS

#define OS_CPU_EXT   //全局变量

#else

#define OS_CPU_EXT  extern

#endif

 

/******************************************************************************

*                    定义与编译器无关的数据类型

******************************************************************************/typedef unsigned char  BOOLEAN;

typedef unsigned char  INT8U; /* Unsigned  8 bit quantity       */

typedef signed   char  INT8S; /* Signed    8 bit quantity       */

typedef unsigned short INT16U; /* Unsigned 16 bit quantity       */

typedef signed   short INT16S; /* Signed   16 bit quantity       */

typedef unsigned int   INT32U; /* Unsigned 32 bit quantity       */

typedef signed   int   INT32S; /* Signed   32 bit quantity       */

typedef float          FP32; /* Single precision floating point*/

typedef double         FP64; /* Double precision floating point*/

 

//STM3232位位宽的,这里OS_STKOS_CPU_SR都应该为32位数据类型typedef unsigned int  OS_STK;    //定义堆栈的宽度,

typedef unsigned int  OS_CPU_SR; //定义状态寄存器的宽度

//////////////////////////////////////////////////////////

下面的部分主要是为了和UC/OS 第一版的兼容

#define BYTE            INT8S          

#define UBYTE          INT8U  

#define WORD          INT16S 

#define UWORD        INT16U

#define LONG           INT32S

#define ULONG          NT32U

//////////////////////////////////////////////////////////

 

/*

*******************************************************************************

*                          ARM Miscellaneous

*******************************************************************************

*/

//定义栈的增长方向.

//CM3,栈是由高地址向低地址增长的,所以OS_STK_GROWTH设置为1

#define  OS_STK_GROWTH        1      /* Stack grows from HIGH to LOW memory on ARM    */

//任务切换宏,由汇编实现.

#define  OS_TASK_SW()         OSCtxSw()

 

/*

*******************************************************************************

*                               PROTOTYPES

*                           (see OS_CPU_A.ASM)

*******************************************************************************

*/

//OS_CRITICAL_METHOD = 1 :直接使用处理器的开关中断指令来实现宏

//OS_CRITICAL_METHOD = 2 :利用堆栈保存和恢复CPU的状态

//OS_CRITICAL_METHOD = 3 :利用编译器扩展功能获得程序状态字,保存在局部变量cpu_sr

 

#define  OS_CRITICAL_METHOD   3   //进入临界段的方法

 

#if OS_CRITICAL_METHOD == 3

#define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}

#define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}

#endif

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值