第九章 在ARM7上移植μC/OS-Ⅱ
9.1 移植规划
9.1.1 编译器的选择
适用于ARM处理器核的C编译器有很多种,例如:ADS、SDT、IAR、TASKING和GCC,其中使用比较多的是SDT、ADS和GCC。
9.1.2 ARM7工作模式的选择
ARM7处理器核具有用户、系统、管理、中止、未定义、中断和快中断7种模式。
为了实现工作模式的切换,在移植时为μC/OS-Ⅱ增加了两个用于模式切换的系统函数ChangeToSYSMode()和ChangeToUSRMode()。
9.2 移植
9.2.1 文件OS_CPU.H的编写
1. 不依赖于编译的数据类型
2. 利用软中断实现底层接口
作为系统管理软件,操作系统安全与否直接影响了系统的安全性。可以使操作系统μC/OS-Ⅱ所提供的所有函数运行在系统模式,而使用户应用程序运行于用户模式,从而实现对操作系统代码的保护。
用户软件可以使用软中断指令SWI来切换模式,ADS编译器允许用户使用关键字__swi作为前缀来声明一个利用软中断的系统调用。
__swi(功能号) 返回值类型 名称(参数列表)
3. OS_STK_GROWTH
编译器ADS仅支持堆栈从上往下长,并且必须是满递减堆栈,所以在文件中用来定义堆栈增长方式的常量OS_STK_GROWTH的值应该为1。
#defineOS_STK_GROWTH 1
9.2.2 文件OS_CPU_C.C的编写
1. 任务堆栈初始化函数OSTaskStkInit()
在编写任务堆栈初始化函数之前,必须先根据处理器的结构和特点确定任务的堆栈结构。
堆栈中的OsEnterSum比较特别,它不是CPU的寄存器,而是一个全局变量,目的是用它来保存开关中断的次数,于是,用户在任务中就不必过分考虑开关中断对其他任务的影响。
2. OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()
关中断:
__asm
{
MRS R0,SPSR
ORR R0,R0,#NoInt
MSR SPSR_c,R0
}
OsEnterSum++;
开中断:
if(--OsEnterSum == 0)
{
__asm
{
R0,SPSR
ORRR0,R0,#NoInt
SPSR_c,R0
}
}
3. 处理器模式转换函数ChangeToSYSMode()和ChangeToUSRMode()
移植时在μC/OS-Ⅱ中增加了4个系统函数。
转换处理模式的函数:ChangeToSYSMode()和ChangeToUSRMode()
设置任务的初始指令集的函数:TaskISARM()和TaskISTHUMB()
ChangeToSYSMode()和ChangeToUSRMode()使用软件中断功能0x80和0x81实现
ChangeToSYSMode():把当前任务转换到系统模式
ChangeToUSRMode():把当前任务转换到用户模式
4. 设置任务的初始化指令集函数TaskISARM()和TaskISTHUMB()
TaskISARM():声明一个待运行任务所使用的指令集是ARM指令集
TaskISTHUMB():声明一个待运行任务所使用的指令集是Thumb指令集
在调用这两个函数时,都需要传递一个唯一的参数——被指定指令集的任务的优先级别。
TaskISARM()和TaskISTHUMB()软件中断功能号为0x82和0x83。
这两个函数必须在相应的任务建立后但还未运行时调用,解决方法如下:
高优先级任务使用默认的指令集;
改变函数OSTaskCreateHook()使任务默认不是处于就绪状态,建立任务后调用函数OSTaskResume()来使任务进入就绪状态。
5. 软件中断服务函数的C语言部分
6. OSStartHighRdy()
void OSStartHighRdy(void)
{
_OSStartHighRdy();
}
软中断功能号为0x01.
7. 钩子函数
9.2.3 文件OS_CPU_A.S的编写
1. 软件中断服务程序的汇编语言部分
2. OS_TASK_SW()和OSInitCtxSw()(汇编语言)
任务及切换函数OS_TASK_SW()
中断级任务切换函数OSInitCtxSw()
一定要在ARM的系统模式下进行任务切换。
3. 启动最高优先级就绪任务函数OSStartHighRdy()(汇编语言)
9.2.4 关于中断及时钟节拍
在本移植中,只使用了ARM和IRQ中断,为了使用户可用C语言编写中断服务程序时不必为处理器的硬件区别而困扰,编写了一个适应于所有基于ARM7核处理器的汇编宏,这个宏实现了μC/OS-Ⅱfor ARM7中断服务程序的汇编代码与C函数代码之间的通用接口。
9.3 移植μC/OS-Ⅱ到LPC2000
9.3.1 挂接SW1软件中断
将软件异常处理程序挂接到内核是通过修改启动代码来实现的。
9.3.2 中断及时钟节拍中断
1. 增加汇编语言接口的支持
在文件中IRQ.S适当位置添加代码:
×××_Handler HANDLER Xxx_Exception
×××替换为用户自己所需要的字符串。
2. 初始化向量中断控制器
VICVecAddrX= (uint32) ×××_Handler;
VICVecCntlX= (0x20|Y);
VICIntEnable= 1 << Y;
X为分配给中断的优先级,Y为中断的通道号。
9.3.3 一个基于μC/OS-Ⅱ和ARM的应用程序实例