理论教育 编写OS_cpu

编写OS_cpu

时间:2023-11-03 理论教育 版权反馈
【摘要】:另外还需要在OS_CFG.H文件中,将常量OS_CPU_HOOKS_EN置1。2)改变函数OSTaskCreateHook()使任务默认不是处于就绪状态,建立任务后调用函数OSTaskResume()来使任务进入就绪状态。

编写OS_cpu_c.c文件-ARM嵌入式系统基础与应用

1.OSTaskStkInit()函数

OS_CPU_C.C文件是与处理器相关的C语言代码,一共包含10个函数:

978-7-111-44508-1-Chapter06-7.jpg

978-7-111-44508-1-Chapter06-8.jpg

其中,只有OSTaskStkInit()函数是必需的,其他9个必须声明,但不一定要有代码。另外还需要在OS_CFG.H文件中,将常量OS_CPU_HOOKS_EN置1。

在编写OSTaskStkInit()函数之前,必须先确定任务的堆栈结构,而任务的堆栈结构是与CPU的体系结构、编译器有密切的关联。

移植采用的堆栈结构如图6-2所示,据此写出函数OSTaskStkInit()的代码:

978-7-111-44508-1-Chapter06-9.jpg

图6-2 移植采用的堆栈结构

978-7-111-44508-1-Chapter06-10.jpg

978-7-111-44508-1-Chapter06-11.jpg

2.软件中断异常SWI服务程序

软件中断异常SWI服务程序主要采用汇编语言程序Os_cpu_a.asm来实现,也可以采用C语言函数来实现,一般来说C语言处理函数代码结构比较简单,使用一个switch语句把各个功能分隔开,各个功能相对独立。

3.OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()函数

μC/OS-II使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来实现关中断和开中断。关中断和开中断是为了保护临界段代码。这些代码与处理器有关,是需要移植的代码。ARM处理器关中断和开中断是通过改变程序状态寄存器CPSR中的相应控制位实现。由于使用了软件中断,程序状态寄存器CPSR保存到程序状态保存寄存器SPSR中,软件中断退出时会将SPSR恢复到CPSR中,所以程序只要改变程序状态保存寄存器SPSR中相应的控制位就可以了。改变这些位使用嵌入汇编实现,代码很简单。(www.daowen.com)

4.OSStartHighRdy()函数

μC/OS-II的启动多任务环境的函数叫做OSStart(),用户在调用OSStart()之前,必须已经建立了一个或更多任务。OSStart()最终调用函数OSStartHighRdy()运行多任务启动前优先级最高的任务,OSStartHighRdy()的代码如下:

978-7-111-44508-1-Chapter06-12.jpg

这是调用软中断的1号功能,软中断的1号功能并没有在这里实现,它在Os_cpu_asm中实现。

5.移植增加的特定函数

根据ARM内核的特点和移植目标,增加了两个处理器模式转换函数:ChangeTo SYSMode()、ChangeToUSRMode()和两个任务初始指令集设置函数TaskIsARM()、TaskIs THUMB()。它们都是通过软件中断指令SWI转换到系统模式,通过软件中断服务程序实现的。

处理器模式转换函数ChangeToSYSMode()和ChangeToUSRMode()使用软件中断功能0x80和0x81实现,其中函数ChangeToSYSMode()把当前任务转换到系统模式,函数ChangeToUSRMode()把当前任务转换到用户模式,它们可以在任何情况下使用。它们改变程序状态保留寄存器SPSR的相应位段,而程序状态保留寄存器会在软件中断退出时复制到程序状态寄存器CPSR,任务的处理器模式就改变了。

任务可以使用ARM指令集或Thumb指令集运行,但是,任务建立时默认的只是一种指令集。如果任务使用的第一条指令与默认的指令集不同,将导致程序运行错误。为了纠正这个错误,移植中增加两个函数TaskIsARM()和TaskIsTHUMB()用于改变任务建立时默认的指令集。函数TaskIsARM()用于声明指定优先级的任务的第一条指令是ARM指令,而函数TaskIsTHUMB()则用于声明指定优先级的任务的第一条指令是Thumb指令,它们都有唯一的参数,即需要改变的任务的优先级。值得注意的是,这两个函数必须在相应的任务建立后但还没有运行时调用。这样,如果在低优先级的任务中创建高优先级的任务就十分危险了。解决这个问题的方法有三种:

1)高优先级任务使用默认的指令集。

2)改变函数OSTaskCreateHook()使任务默认不是处于就绪状态,建立任务后调用函数OSTaskResume()来使任务进入就绪状态。

3)建立任务时禁止任务切换,调用函数TaskIsARM()或TaskIsTHUMB()后再允许任务切换。

函数TaskIsARM()和TaskIsTHUMB()使用软件中断功能0x82和0x83实现。两个功能代码极其相似,代码也比较简单。首先,程序判断传递的参数(任务的优先级)是否在允许的范围内,然后获取任务的任务控制块(tcb)地址,接着判断指针是否有效,有效则改变指定任务的堆栈中存储的CPSR的T位。这两个函数仅在任务建立时使用。

6.Hook()函数

μC/OS-II中有很多由用户编写的Hook()函数,它们在本移植中全为空函数,用户可以根据μC/OS-II的要求进行修改。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈