23.2 uCos-II移植
我们将下载好的uCOS-II的源代码解压出来如下图所示。
23.2.1 在工程中添加相应的文件
(1)在工程目录下建立UCOSII文件夹,并在该文件夹内新建三个文件夹CONFIG,CORE和PORT
(2)将除了os_cfg_r.h和os_dbg_r.c这两个文件以外的所有文件全部复制到CORE文件夹下
(3)在CONFIG文件夹中新建includes.h文件和os_cfg.h文件
(4)在PORT文件夹中新建os_cpu.h,os_cpu_a.asm,os_cpu_c.c这3个文件
(5)在工程中添加这三个目录下的文件,如下图所示。
注:不要把ucos-ii.c文件添加到UCOS-CORE分组中,否则会提示有重复定义错误。
23.2.2 文件修改
我们编译工程后可以发现报了11个错误,但都是同一个错误,如下图所示。
我们在移植的时候并没有发现这个文件,那是因为我们并没有用到这个文件,这个文件是在ucos-ii.h文件中引用的,我们跳转到这个文件将其屏蔽掉。
注 :我们可以发现在修改的时候,文件虽然可以打开,但是修改不了,这是因为我们下载的源码都被设置成了只读模式,在工程中只读文件会有一个钥匙的标志,这就需要我们将文件的只读属性去掉即可。
去掉只读属性之后,我们会发现项目中的文件上钥匙标志消失了,如下图所示。
此时,我们就可以对文件内容进行修改了。打开ucos_ii.h文件,屏蔽44行的文件引用,如下图所示。
此时会发现报更多的错误,此时我们进行新建文件的修改。
(1)os_cpu_a.asm文件详解
①这部分代码主要用于定义外部变量,IMPORT表示这是一个外部变量,不是在本程序内定义的,EXPORT则表示这些函数位于该文件内,供其他文件调用,类似于C语言中的extern关键字。
IMPORT OSRunning
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSIntNesting
IMPORT OSIntExit
IMPORT OSTaskSwHook
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw
EXPORT OS_CPU_SR_Save
EXPORT OS_CPU_SR_Restore
EXPORT PendSV_Handler
②EQU和C语言中的define关键字一样,用于宏定义,定义了一些寄存器的地址
NVIC_INT_CTRL EQU 0xE000ED04 ;中断控制寄存器
NVIC_SYSPRI2 EQU 0xE000ED20 ;系统优先级寄存器
NVIC_PENDSV_PRI EQU 0xFFFF0000 ;PendSV中断和系统节拍中断
NVIC_PENDSVSET EQU 0x10000000 ;触发软件中断的值
PRESERVE8
AREA |.text|, CODE, READONLY
THUMB
③OS_CPU_SR_Save和OS_CPU_SR_Restore是用于开关中断的汇编函数,通过给PRIMASK写1来关闭中断,写0来开启中断,这里也可以使用CPS指令来快速开关中断
OS_CPU_SR_Save
MRS R0, PRIMASK ;读取PRIMASK到R0,R0为返回值
CPSID I ;PRIMASK=1,关中断(NMI和硬件FAULT可以响应)
BX LR ;返回
OS_CPU_SR_Restore
MSR PRIMASK, R0 ;读取R0到PRIMASK中,R0为参数
BX LR ;返回
④OSStartHighRdy是由OSStart()调用,用来开启多任务,如果多任务开启失败就会进入OSStartHang函数中
OSStartHighRdy
LDR R4, =NVIC_SYSPRI2 ;设置PendSV优先级
LDR R5, =NVIC_PENDSV_PRI
STR R5, [R4]
MOV R4, #0 ;设置PSP=0
MSR PSP, R4
LDR R4, =OSRunning ;设置OSRunning=1
MOV R5, #1
STRB R5, [R4]
;切换到最高优先级的任务
LDR R4, =NVIC_INT_CTRL ;R4=NVIC_INT_CTRL
LDR R5, =NVIC_PENDSVSET ;R5=NVIC_PENDSVSET
STR R5, [R4]
CPSIE I ;开启所有中断
OSStartHang
B OSStartHang ;死循环