os_cpu.h
移植一个操作系统到一个CPU体系的结构上,移植者必须的要求:
1、对目标体系结构要有很深的了解 -- ARM Architecture Reference Manual
2、对OS原理要有较深入的了解 -- 嵌入式实时操作系统uC/OS-II
3、对所使用的编译器要有较深入的了解 -- ADS自带的编译器和连接器的手册
4、对需要移植的操作系统要有相当的了解 -- 嵌入式实时操作系统uC/OS-II
5、对具体使用的芯片也要有一定的了解 -- 芯片的数据手册
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: 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; /* 无符号8位整型变量*/
typedef signed char INT8S; /* 有符号8位整型变量*/
typedef unsigned short INT16U; /* 无符号16位整型变量*/
typedef signed short INT16S; /* 有符号16位整型变量*/
typedef unsigned int INT32U; /* 无符号32位整型变量*/
typedef signed int INT32S; /* 有符号32位整型变量*/
typedef float FP32; /* 单精度浮点数(32位长度)*/
typedef double FP64; /* 双精度浮点数(64位长度)*/
typedef INT32U OS_STK; /* 堆栈是32位宽度*/
/* 以下是兼容UC/OS V1.XX的数据类型,在uC/OS-II没有使用 */
#define BYTE INT8S
#define UBYTE INT8U
#define WORD INT16S
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
/******************************************************************************
与ARM7体系结构相关的一些定义******************************************************************************/
#define OS_CRITICAL_METHOD 2 /* 选择开、关中断的方式 */
__swi(0x00) void OS_TASK_SW(void); /* 任务级任务切换函数*/
__swi(0x01) void _OSStartHighRdy(void); /* 运行优先级最高的任务 */
__swi(0x02) void OS_ENTER_CRITICAL(void); /* 关中断 */
__swi(0x03) void OS_EXIT_CRITICAL(void); /* 开中断 */
__swi(0x40) void *GetOSFunctionAddr(int Index); /* 获取系统服务函数入口*/
__swi(0x41) void *GetUsrFunctionAddr(int Index); /* 获取自定义服务函数入口*/
__swi(0x42) void OSISRBegin(void); /* 中断开始处理*/
__swi(0x43) int OSISRNeedSwap(void); /* 判断中断是否需要切换*/
__swi(0x80) void ChangeToSYSMode(void); /* 任务切换到系统模式*/
__swi(0x81) void ChangeToUSRMode(void); /* 任务切换到用户模式*/
__swi(0x82) void TaskIsARM(INT8U prio); /*任务代码是ARM代码*/
__swi(0x83) void TaskIsTHUMB(INT8U prio); /*任务代码是THUMB*/
#define OS_STK_GROWTH 1 /*堆栈是从上往下长的*/
#define USR32Mode 0x10 /* 用户模式*/
#define SYS32Mode 0x1f /* 系统模式 */
#define NoInt 0x80
#ifndef USER_USING_MODE
#define USER_USING_MODE USR32Mode /* 任务缺省模式 */
#endif
#ifndef OS_SELF_EN
#define OS_SELF_EN 0 /* 允许返回OS与任务分别编译、固化*/
#endif
OS_CPU_EXT INT32U OsEnterSum; /* 关中断计数器(开关中断的信号量)*/
/******************************************************************************
End Of File
******************************************************************************/
1.OS_ENTER_CRITICAL( )关中断 和 OS_EXIT_CRITICAL( )开中断
与所有的实时内核一样,uC/OS-II需要先关中断,再处理临界段代码,并且再处理完毕后再重新开中断。能够保护临界段代码免受多任务或者中断服务子程序的破坏。
uC/OS-II定义了两个宏,用开开关中断:OS_ENTER_CRITICAL( )关中断 和 OS_EXIT_CRITICAL( )开中断。事实上它们都是成对使用,并且分别在临界代码的前后。
然而要特别小心,如果在调用一些如OSTimeDel()之类的功能函数之前关中断,应用程序将会死机;原因是任务被挂起一段时间,直到挂起时间到,但由于中断关掉了,时钟节拍中断一直得不到服务,显然所有的挂起类调用都有这样的问题,所以要特别小心。作为一条普遍适用的规则,调用UCOS-ii功能函数时,中断总是开着的。
OS_ENTER_CRITICAL()只关IRQ中断,_SWI和FIQ是不动的。
2.它们可以用不同的方法去实现。用户定义(#define)常数OS_CRITICAL_METHOD可以选择具体的方法。OS_CRITICAL_METHOD 2
3.OS_STK_GROWTH 1 //1:堆栈是从上(高地址)往下(低地址)长的0:堆栈是从下往上递增的
4.OS_TASK_SW( )
它是一个宏,是在低优先级任务切换到高优先级任务时必须要用到的。任务切换只是简单地将处理器的寄存器保存到将被挂起的任务堆栈中,并且从堆栈中恢复要运行的更高优先级任务。要运行处于就绪状态的任务必须要做的事情就是从任务堆栈中恢复处理器所有的寄存器,并且执行中断返回指令,为了调度任务可以通过执行OS_TASK_SW()模仿中断产生。中断服务子程序(也叫作异常处理函数)的中断向量地址必须指向汇编语言函数OSCtxSw()。
在μC/OS-II中,OS_TASK_SW()用来实现任务切换。就绪任务的堆栈初始化应该模拟一次中断发生后的样子,堆栈中应该按进栈次序设置好各个寄存器的内容。OS_TASK_SW()函数模拟一次中断过程,在中断返回的时候进行任务切换。中可采用软中断指令SWI实现任务切换。中断服务程序的入口点必须指向汇编函数OSCtxSw()。
OS_TASK_SW()的定义:
#define OS_TASK_SW() asm swi
OS_TASK_SW()实际上是一个宏,#define OS_TASK_SW() ASM int 80h,模拟了一个中断产生。
#define OS_TASK_SW() ASM int 80h,是一个软件中断,执行的结果,CPU查找第80H号中断向量,按中断向量提供的地址执行一个长调用。在调用过程中,PC和PSW已保存,其它要保存的寄存器,应在中断程序中处理。