嵌入式系统RTEOSμCOSII的移植.ppt

上传人:本田雅阁 文档编号:3305059 上传时间:2019-08-10 格式:PPT 页数:101 大小:1.22MB
返回 下载 相关 举报
嵌入式系统RTEOSμCOSII的移植.ppt_第1页
第1页 / 共101页
嵌入式系统RTEOSμCOSII的移植.ppt_第2页
第2页 / 共101页
嵌入式系统RTEOSμCOSII的移植.ppt_第3页
第3页 / 共101页
嵌入式系统RTEOSμCOSII的移植.ppt_第4页
第4页 / 共101页
嵌入式系统RTEOSμCOSII的移植.ppt_第5页
第5页 / 共101页
点击查看更多>>
资源描述

《嵌入式系统RTEOSμCOSII的移植.ppt》由会员分享,可在线阅读,更多相关《嵌入式系统RTEOSμCOSII的移植.ppt(101页珍藏版)》请在三一文库上搜索。

1、嵌入式系统 RTEOS C/OS-II 的移植,2006年6月9日,主要内容,移植规划 C/OS-II的移植 嵌入式系统的初始化,移植规划-概述,所谓“移植”,就是使一个实时内核能在其它的微处理器或微控制器上运行。 尽管大部分C/OS-II的代码是用C语言编写的,但是在编写与处理器硬件相关的代码时还是不得不使用汇编语言。 移植的主要工作就是编写这些与处理器硬件相关的代码。 操作系统的移植大体可以分为两个层次: 跨体系结构的移植 针对特定处理器的移植,移植规划,在移植前针对所使用的微处理器进行规划,主要有以下几个方面的考虑: 编译器的选择 任务模式的选择 支持的指令集,移植规划(续),编译器的选

2、择,针对ARM处理器核的C语言编译器有很多,如SDT、 ADS、IAR、TASKING和GCC等 目前在国内最流行的是ADS、SDT和GCC SDT和ADS均为ARM公司自己开发,ADS为SDT的升级版,以后ARM公司不再支持SDT,故不选择SDT。GCC虽然支持广泛,很多开发套件使用它作为编译器,但是与ADS比较其编译效率较低,这对充分发挥芯片性能不利 考虑使用ADS编译程序和调试,ARM的工作模式,ARM处理器有7种操作模式: 用户模式(usr) - 正常的程序执行模式 快速中断模式(fiq) - 支持高速数据传输或通道处理 中断模式(irq) - 用于通用中断处理 管理员模式(svc)

3、- 操作系统的保护模式. 中止模式(abt) - 支持虚拟内存和/或内存保护等异常 系统模式(sys) - 支持操作系统的特殊用户模式(运行操作系统任务) 未定义模式(und) - 支持硬件协处理器的软件仿真 除了用户模式外,其他模式均可视为特权模式,移植规划(续),任务模式的取舍,ARM7处理器核具有上述七种模式,其中除用户模式外其它均为特权模式。其中管理、中止、未定义、中断和快中断模式与相应异常相联系,任务使用这些模式不太适合。 系统模式除了是特权模式外,其它与用户模式一样,因而可选为任务使用的模式只有用户模式和系统模式。 为了尽量减少任务代码错误对整个程序的影响,缺省的任务模式定为用户模

4、式,可选为系统模式,同时提供接口使任务可以在这两种模式间切换。,移植规划(续),支持的指令集,带T变量的ARM7处理器核具有两个指令集: 标准32位ARM指令集 16位Thumb指令集 两种指令集有不同的应用范围。 为了最大限度地支持芯片的特性,任务应当可以使用任意一个指令集并可以自由切换,而且不同的任务应当可以使用不同的指令集,移植C/OS-II,概述,要移植一个操作系统到一个特定的CPU体系结构并不是一件很容易的事情,它对移植者有以下要求: 1 对目标体系结构要有很深了解; 2 对OS原理要有较深入的了解; 3 对所使用的编译器要有较深入的了解; 4 对需要移植的操作系统要有相当的了解;

5、5 对具体使用的芯片也要一定的了解,要移植一个操作系统到一个特定的CPU体系结构上并不是一件很容易的事情,它对移植者有以下要求: 1 对目标体系结构要有很深了解; 2 对OS原理要有较深入的了解; 3 对所使用的编译器要有较深入的了解; 4 对需要移植的操作系统要有相当的了解; 5 对具体使用的芯片也要一定的了解。,概述,要移植一个操作系统到一个特定的CPU体系结构上并不是一件很容易的事情,它对移植者有以下要求: 1 对目标体系结构要有很深了解; 2 对OS原理要有较深入的了解; 3 对所使用的编译器要有较深入的了解; 4 对需要移植的操作系统要有相当的了解; 5 对具体使用的芯片也要一定的了

6、解。,因为第4点的影响是全局性的,它决定移植代码的框架和功能。 所以重点介绍第4点。,主要内容,移植规划 C/OS-II的移植 嵌入式系统的初始化,C/OS-II的文件结构,C/OS-II移植,C/OS-II硬件软件体系结构,用于产生系统时钟,移植时需要编写的代码,移植C/OS-II满足的条件,处理器的C编译器能产生可重入代码 在程序中可以打开或者关闭中断 处理器支持中断,并且能产生定时中断(通常在10100Hz之间) 处理器支持能够容纳一定量数据的硬件堆栈(通常是几千字节) 处理器有将堆栈指针和其他CPU寄存器的内容存储和读出到堆栈(或者内存)的指令,什么是可重入代码,可重入的代码指的是一段

7、可以被多个任务同时调用,而不必担心会破坏数据的代码(比如:一个函数) 即:可重入型函数在任何时候都可以被中断执行,过一段时间以后又可以继续运行,而不会因为在函数中断的时候被其他的任务重新调用,而影响函数中的数据,可重入代码举例,程序1:可重入型函数 void swap(int *x, int *y) int temp; temp=*x; *x=*y; *y=temp; ,非可重入代码举例,程序2:非可重入型函数 int temp; void swap(int *x, int *y) temp=*x; *x=*y; *y=temp; ,不可重入函数被中断破坏,如何使函数具有可重入性,使Swap(

8、)函数具有可重入性的条件: 把Temp定义为局部变量 调用Swap()函数之前关中断,调用 后再开中断 用信号量禁止该函数在使用过程中 被再次调用,概述,根据C/OS-II的要求,移植C/OS-II到一个新的体系结构上需要提供2个或3个文件: OS_CPU.H(C语言头文件) OS_CPU_C.C(C程序源文件) OS_CPU_A.ASM(汇编程序源文件) 其中OS_CPU_A.ASM在某些情况下不需要,但极其罕见。不需要OS_CPU_A.ASM的必须满足以下苛刻条件: 1.可以直接使用C语言开关中断; 2.可以直接使用C语言编写中断服务程序; 3.可以直接使用C语言操作堆栈指针; 4.可以直

9、接使用C语言保存CPU的所有寄存器。,移植需要编写的文件,概述,实际上,还有一个文件很重要,它就是IRQ.INC,它定义了一个汇编宏,它是C/OS-II for ARM7通用的中断服务程序的汇编与C函数接口代码。时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过IRQ.INC简化用户代码的编写。,移植代码包括的主要内容,关于头文件includes.h和config.h,C/OS-II要求所有.C文件的都要包含头文件includes.h,这样使得用户项目中的每个.C文件不用分别去考虑它实际上需要哪些头文件。 使用INCLUDES.H的缺点是它可能会包含一

10、些实际不相关的头文件,这意味着每个文件的编译时间可能会增加,但却增强了代码的可移植性。 在移植中另外增加了一个头文件config.h,要求所有用户程序必须包含config.h,在config.h中包含includes.h和特定的头文件和配置项。而C/OS-II的系统文件依然只是包含includes.h,即C/OS-II的系统文件完全不必改动。所有的配置改变包括头文件的增减均在config.h中进行,而includes.h定下来后不必改动(C/OS-II的系统文件需要包含的东西是固定的)。这样,C/OS-II的系统文件需要编译的次数大大减少,编译时间随之减少。,设置与处理器和编译器相关的代码,O

11、S_CPU.H中定义了与编译器相关的数据类型。比如:INT8U、INT8S等。 与 ARM处理器相关的代码,使用OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 宏开启关闭中断 设置堆栈的增长方向 :堆栈由高地址向低地址增长,编写OS_CPU.H,C/OS-II使用结构常量OS_STK_GROWTH中指定堆栈的生长方式: 置OS_STK_GROWTH为0表示堆栈从下往上长。 置OS_STK_GROWTH为1表示堆栈从上(高地址)往下(低地址)长。 虽然ARM处理器核对于两种方式均支持,但ADS的C语言编译器仅支持一种方式,即从上往下长,并且必须是满递减堆栈,所以O

12、S_STK_GROWTH的值为1。 #define OS_STK_GROWTH 1,堆栈生长方式,编写OS_CPU.H,C/OS-II不使用C语言中的short、int、long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。代之以移植性强的整数数据类型,这样,既直观又可移植,不过这就成了必须移植的代码。根据ADS编译器的特性,这些代码如下程序清单所示(与编译有关)。,typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned sho

13、rt INT16U; typedef signed short INT16S; typedef unsigned int INT32U; typedef signed int INT32S; typedef float FP32; typedef double FP64; typedef INT32U OS_STK;,不依赖于编译的数据类型,设置includes.h,typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U;

14、 typedef signed int INT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef float FP32; typedef double FP64; typedef unsigned long OS_STK; typedef unsigned long OS_CPU_SR; extern int INTS_OFF(void); extern void INTS_ON(void); #define OS_ENTER_CRITICAL() cpu_sr = INTS_OFF(); #define

15、 OS_EXIT_CRITICAL() if(cpu_sr = 0) INTS_ON(); #define OS_STK_GROWTH 1 /*从高向低*/,程序状态寄存器(CPSR),条件位: N = 1-结果为负,0-结果为正或0 Z = 1-结果为0,0-结果不为0 C =1-进位,0-借位 V =1-结果溢出,0结果没溢出 Q 位: 仅ARM 5TE/J架构支持 指示增强型DSP指令是否溢出 J 位 仅ARM 5TE/J架构支持 J = 1: 处理器处于Jazelle状态,中断禁止位: I = 1: 禁止 IRQ. F = 1: 禁止 FIQ. T Bit 仅ARM xT架构支持 T

16、= 0: 处理器处于 ARM 状态 T = 1: 处理器处于 Thumb 状态 Mode位(处理器模式位): 0b10000 User 0b10001 FIQ 0b10010 IRQ 0b10011 Supervisor 0b10111 Abort 0b11011 Undefined 0b11111 System,编写OS_CPU.H,C/OS-II运行时,处理器可能处于的模式如下图所示:,使用软中断SWI作底层接口,用户任务使用的处理器模式,ARM7内核具有的指令集,ARM指令 用户模式,ARM指令 系统模式,Thumb指令 系统模式,Thumb指令 用户模式,编写OS_CPU.H,为了使底

17、层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数位置,在移植中使用软中断指令SWI作为底层接口,使用不同的功能号区分不同的函数。软中断功能号分配如下表所示,未列出的为保留功能。,使用软中断SWI作底层接口,编写OS_CPU.H,用软中断作为操作系统的底层接口就需要在C语言中使用SWI(SoftWare Interrupt)指令。在ADS中,有一个关键字_swi,用它声明一个不存在的函数,则调用这个函数就在调用这个函数的地方插入一条SWI指令,并且可以指定功能号。同时,这个函数也可以有参数和返回值,其传递规则与一般函数相同。,使用软中断SWI作底层接口,/* 任务级任务切换函数

18、 */ _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(0x80) void ChangeToSYSMode(void); /* 任务切换到用户模式 */ _swi(0x81) void ChangeToUSRMode(vo

19、id); /* 任务代码是ARM代码 */ _swi(0x82) void TaskIsARM(INT8U prio); /* 任务代码是THUMB代码 */ _swi(0x83) void TaskIsTHUMB(INT8U prio);,编写OS_CPU_C.C,C/OS-II的移植要求用户编写10个C函数: OSTaskStkInit(): OSTaskCreat()和OSTaskCreatExt()通过调用 本函数,初始化任务的栈结构 OSTaskCreateHook():每当添加任务时由OS_TCBInit( )函数调用 OSTaskDelHook(): 任务被删除后由OSTaskD

20、el()调用 OSTaskSwHook(): 任务切换时两种情况均会调用该函数 OSTaskIdleHook():OSTaskIdle()函数可调用该函数实现CPU低功耗模式 OSTimeTickHook():本函数在每个时钟节拍都会被OSTimeTick()调用 OSInitHookBegin():进入OSInit()函数后本函数会立即被调用 OSInitHookEnd(): OSInit()函数返回之前被调用 OSTCBInitHook():OS_TCBInit( )在调用OSTaskCreateHook()之前将先 调用本函数 唯一必要的函数是OStaskStkInit(),其他9个函数

21、必须声明,但不一定要包含任何代码,编写OS_CPU_C.C,该函数用于初始化任务堆栈,使任务的堆栈看起来就像刚发生中断一样。即任务被执行时,就像从中断返回一样。 在编写此函数之前,必须先确定任务的堆栈结构。而任务的堆栈结构是与CPU的体系结构、编译器有密切的关联。本移植的堆栈结构如下图所示。,OSTaskStkInit( ),编写OS_CPU_C.C,OSTaskStkInit( ),OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) OS_STK *stk; opt = o

22、pt; stk = ptos; *stk = (OS_STK) task; *-stk = (OS_STK) task; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = (unsigned int) pdata; *-stk = (USER_USING_MODE|0x00); *-stk = 0; return (stk); ,入栈的数据,编写OS_CPU_C.C,

23、OSTaskStkInit( ),OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) OS_STK *stk; opt = opt; stk = ptos; *stk = (OS_STK) task; *-stk = (OS_STK) task; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk

24、= 0; *-stk = 0; *-stk = (unsigned int) pdata; *-stk = (USER_USING_MODE|0x00); *-stk = 0; return (stk); ,该数据比较特别,它用于保存该任务关中断的次数,它在调用OS_ENTER_CRITICAL( )时加1,在调用OS_EXIT_CRITICAL( )时减1。 这样每个任务都可以独立控制本任务的中断允许状态,而不会影响其它任务的中断允许状态。因此关中断和开中断就可以嵌套。,编写OS_CPU_C.C,软件中断异常服务程序,操作系统与硬件相关的底层函数使用软件中断作为接口,如下表所示。 移植代码中

25、一个重要的工作就是为这些软件中断编写服务程序,编写OS_CPU_C.C,软件中断异常服务程序,void SWI_Exception(int SWI_Num, int *Regs) OS_TCB *ptcb; switch(SWI_Num) case 0x02: / 关中断 . case 0x03: / 开中断 . case 0x80: / 任务切换到系统模式 . case 0x81: / 任务切换到用户模式 . case 0x82: / 任务代码是ARM代码 . case 0x83: / 任务代码是Thumb代码 . default: ,编写OS_CPU_C.C,软件中断异常服务程序,编写OS

26、_CPU_C.C,软件中断异常服务程序,编写OS_CPU_C.C,软件中断异常服务程序,void SWI_Exception(int SWI_Num, int *Regs) . case 0x02: / 关中断 _asm MRS R0,SPSR ORR R0,R0,#NoInt MSR SPSR_c,R0 OsEnterSum+; break; case 0x03: / 开中断 if (-OsEnterSum = 0) _asm MRS R0,SPSR BIC R0,R0,#NoInt MSR SPSR_c,R0 break; .,关闭中断,打开中断,编写OS_CPU_C.C,软件中断异常服务

27、程序,编写OS_CPU_C.C,软件中断异常服务程序,void SWI_Exception(int SWI_Num, int *Regs) . case 0x80: / 任务切换到系统模式 _asm MRS R0,SPSR BIC R0,R0,#0x1f ORR R0,R0,#SYS32Mode MSR SPSR_c,R0 break; case 0x81: / 任务切换到用户模式 _asm MRS R0,SPSR BIC R0,R0,#0x1f ORR R0,R0,#USR32Mode MSR SPSR_c,R0 break; .,编写OS_CPU_C.C,软件中断异常服务程序,编写OS_C

28、PU_C.C,软件中断异常服务程序,. case 0x82: / 任务代码是ARM代码 if (Regs0 OSTCBStkPtr1 .,CPSR:程序状态寄存器,编写OS_CPU_C.C,软件中断异常服务程序,注意: 这两个函数必须在相应的任务建立后但还没有运行时调用。 如果在低优先级的任务中创建高优先级的任务就十分危险了。此时,解决的方法有三种: (1)高优先级任务使用默认的指令集; (2)改变函数OSTaskCreateHook()使任务默认不是处于就绪状态,建立任务后调用函数OSTaskResume()来使任务进入就绪状态; (3)建立任务时禁止任务切换,调用函数 TaskIsARM(

29、)或TaskIsTHUMB()后再允许任务切换。,编写OS_CPU_C.C,在Os_cpu_c.c文件中还有许多Hook()函数,它们在某个特定的系统动作时被调用,允许执行函数中的用户代码。这些函数默认是空函数,用户根据实际情况添加相关代码。它们分别如下表所示。,Hook( )函数,移植C/OS-II,编写OS_CPU_A.ASM,在OS_CPU_A.ASM文件中有: 软件中断的汇编接口程序 任务切换程序 OS启动时运行就绪最高优先级任务的程序,OS_CPU_A.ASM,C/OS-II的移植要求用户编写4个汇编语言函数: OSStartHighRdy() OSCtxSw() OSIntCtxS

30、w() OSTickISR() 如果编译器支持插入行汇编代码,就可以将所有与处理器相关的代码放到OS_CPU_C.C文件中,而不必再有单独的汇编语言文件,编写OS_CPU_A.ASM,在调用软中断之后,处理器切换到ARM指令和管理模式下工作。在执行软件中断服务函数之前,要提取中断号和其它入口参数,这些通过软件中断接口程序完成。,软件中断汇编接口,SoftwareInterrupt LDR SP, StackSvc STMFD SP!, R0-R3, R12, LR MOV R1, SP MRS R3, SPSR TST R3, #T_bit LDRNEH R0, LR,#-2 BICNE R0

31、, R0, #0xff00 LDREQ R0, LR,#-4 BICEQ R0, R0, #0xFF000000 CMP R0, #1 LDRLO PC, =OSIntCtxSw LDREQ PC, =_OSStartHighRdy BL SWI_Exception LDMFD SP!, R0-R3, R12, PC,编写OS_CPU_A.ASM,C/OS-II是抢占式实时操作系统,得到运行的始终是就绪条件下最高优先级的任务。当处于运行状态的任务因为某种原因进入就绪态,或者有其它更高优先级的任务进入就绪态,操作系统内核就要运行别的就绪任务,这时需要进行任务切换。,任务切换代码,编写OS_CPU

32、_A.ASM 任务切换代码,任务切换可能发生的情况有两种: 1.当前运行的任务主动交出CPU控制权,通常发生在等待某个事件或是调用系统延时。调用函数OS_TASK_SW( ) 2.发生中断,使更高优先级的任务进入就绪状态,内核剥夺当前任务的运行资格。即发生在中断退出时。调用函数OSIntCtxSw( ),SPSR:程序状态保留寄存器 CPSR:当前程序状态寄存器,编写OS_CPU_A.ASM,虽然OS_TASK_SW( )和OSIntCtxSw( )的执行条件不同,但是它们的功能相同,只要稍作处理就可以它们共用一段任务切换代码。这些处理就是保证在执行任务切换前两者的任务现场是一致的。共同执行的

33、任务切换代码是“OSIntCtxSw” 其中OS_TASK_SW( )是通过软件中断0完成的,通过前面的分析,可以知道执行任务切换时的现场环境如下所示,同时R3中保存着SPSR,它是任务中断前CPSR的备份。,任务切换代码,编写OS_CPU_A.ASM,OSIntCtxSw,流程图,编写OS_CPU_A.ASM,OSIntCtxSw,保存当前任务的 寄存器组及其它,OSIntCtxSw ;下面为保存任务环境 LDR R2, SP, #20 ;获取PC LDR R12, SP, #16 ;获取R12 MRS R0, CPSR ;保存LR,PC及R4-R12 MSR CPSR_c, #(NoInt

34、 | SYS32Mode) MOV R1, LR STMFD SP!, R1-R2 STMFD SP!, R4-R12 ;获取R0-R3,并出栈R12和PC寄存器 MSR CPSR_c, R0 LDMFD SP!, R4-R7 ADD SP, SP, #8 ;保存R0-R3 MSR CPSR_c, #(NoInt | SYS32Mode) STMFD SP!, R4-R7 ;获取OsEnterSum,并保存CPSR,OsEnterSum LDR R1, =OsEnterSum LDR R2, R1 STMFD SP!, R2, R3 .,任务环境保存结束后的栈结构,编写OS_CPU_A.ASM

35、,OSIntCtxSw,修改当前任务的TCB堆栈指针,用将要运行任务的优先级和TCB指针更新OSPrioHighRdy和OSTCBCur,OSIntCtxSw . ;保存当前任务堆栈指针到当前任务的TCB LDR R1, =OSTCBCur LDR R1, R1 STR SP, R1 BL STaskSwHook ;调用钩子函数 ;OSPrioCur = OSPrioHighRdy LDR R4, =OSPrioCur LDR R5, =OSPrioHighRdy LDRB R6, R5 STRB R6, R4 ;OSTCBCur = OSTCBHighRdy LDR R6, =OSTCBHi

36、ghRdy LDR R6, R6 LDR R4, =OSTCBCur STR R6, R4 .,编写OS_CPU_A.ASM,OSIntCtxSw,编写OS_CPU_A.ASM,OSIntCtxSw,恢复新任务的寄存器组及其它,运行新任务,OSIntCtxSw . OSIntCtxSw_1 ;从R6指向TCB中获取新任务堆栈指针 LDR R4, R6 ;调整堆栈指针 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP ADD SP, R4, #68 LDR LR, SP, #-8 ;进入管理模式,恢复任务的各寄存器和变量 MSR CPSR_c, #(NoInt | SVC32

37、Mode) MOV SP, R4 ;设置堆栈指针 ;获取CPSR和OsEnterSum LDMFD SP!, R4, R5 ;恢复新任务的OsEnterSum LDR R3, =OsEnterSum STR R4, R3 ;恢复CPSR MSR SPSR_cxsf, R5 ;运行新任务 LDMFD SP!, R0-R12, LR, PC ,编写OS_CPU_A.ASM,OSIntCtxSw,这段代码还被_OSStartHighRdy 函数调用,用于启动最高优先级的就绪任务,_OSStartHighRdy MSR CPSR_c, #(NoInt | SYS32Mode) ;告诉uC/OS-II自

38、身已经运行 LDR R4, =OSRunning MOV R5, #1 STRB R5, R4 ;调用钩子函数 BL OSTaskSwHook LDR R6, =OSTCBHighRdy ;取得新任务的TCB指针 LDR R6, R6 B OSIntCtxSw_1,编写OS_CPU_A.ASM,OSStartHighRdy,C/OS-II的多任务环境由函数OSStart( ) 启动。用户在调用该函数之前,必须已经建立了一个或更多任务。OSStart()最终调用函数OSStartHighRdy( )运行多任务启动前优先级最高的任务,而它最终是调用_OSStartHighRdy实现的,其代码如下所

39、示:,编写OS_CPU_A.ASM,通过前面的分析,我们可以画出下面这张结构图:,移植C/OS-II,关于中断及时钟节拍,在本移植中,IRQ是受C/OS-II管理的中断,而对于FIQ不做处理,这是为了提高FIQ的响应速度。由于各种ARM芯片的中断系统不一样,各个用户的目标板也不一样,对于中断和时钟节拍是需要进一步移植的代码。为此编写一个汇编宏,它是C/OS-II for ARM7通用的中断服务程序的汇编与C函数接口代码。,注:在不受管理的中断服务程序中不能调用任何系统函数。,关于中断及时钟节拍,流程图,关于中断及时钟节拍,流程图,保存当前任务的 寄存器组,中断嵌套数加1,切换到系统模式 执行中

40、断服务程序,关中断 执行OSIntExit( ),切换到IRQ模式 判断是否需要进行任务切换,切换任务或返回,MACRO $IRQ_Label HANDLER $IRQ_Exception_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号 $IRQ_Label SUB LR, LR, #4 ; 计算返回地址 STMFD SP!, R0-R3, R12, LR ; 保存任务环境 MRS R3, SPSR ; 保存状态 ; 保存用户状态的R3,SP,LR,不能回写 STMFD SP, R3, SP

41、, LR LDR R2, =OSIntNesting LDRB R1, R2 ADD R1, R1, #1 STRB R1, R2 SUB SP, SP, #4*3 ; 切换到系统模式 MSR CPSR_c, #(NoInt | SYS32Mode) CMP R1, #1 LDREQ SP, =StackUsr .,关于中断及时钟节拍,关于中断及时钟节拍,流程图,保存当前任务的 寄存器组,中断嵌套数加1,切换到系统模式 执行中断服务程序,关中断 执行OSIntExit( ),切换到IRQ模式 判断是否需要进行任务切换,切换任务或返回,中断服务程序 (ISR),在ISR中可以打开中断实现中断嵌套

42、,MACRO $IRQ_Label HANDLER $IRQ_Exception_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号 $IRQ_Label . BL $IRQ_Exception_Function ; 切换到系统模式 MSR CPSR_c, #(NoInt | SYS32Mode) ; OsEnterSum,使OSIntExit退出时中断关闭 LDR R2, =OsEnterSum MOV R1, #1 STR R1, R2 BL OSIntExit ; 因为中断服务程序要退出,

43、所以OsEnterSum=0 LDR R2, =OsEnterSum MOV R1, #0 STR R1, R2 ; 切换回irq模式,并恢复用户状态的R3,SP,LR MSR CPSR_c, #(NoInt | IRQ32Mode) LDMFD SP, R3, SP, LR ; 注意不能回写 .,关于中断及时钟节拍,关于中断及时钟节拍,流程图,保存当前任务的 寄存器组,中断嵌套数加1,切换到系统模式 执行中断服务程序,关中断 执行OSIntExit( ),切换到IRQ模式 判断是否需要进行任务切换,切换任务或返回,MACRO $IRQ_Label HANDLER $IRQ_Exception

44、_Function EXPORT $IRQ_Label ; 输出的标号 IMPORT $IRQ_Exception_Function ; 引用的外部标号 $IRQ_Label . LDR R0, =OSTCBHighRdy LDR R0, R0 LDR R1, =OSTCBCur LDR R1, R1 CMP R0, R1 ADD SP, SP, #4*3 MSR SPSR_cxsf, R3 ; 不进行任务切换 LDMEQFD SP!, R0-R3, R12, PC ; 进行任务切换 LDR PC, =OSIntCtxSw MEND,关于中断及时钟节拍,关于中断及时钟节拍,流程图,保存当前任务

45、的 寄存器组,中断嵌套数加1,切换到系统模式 执行中断服务程序,关中断 执行OSIntExit( ),切换到IRQ模式 判断是否需要进行任务切换,切换任务或返回,中断服务程序 (ISR),在ISR中可以打开中断实现中断嵌套,void ISR(void) OS_ENTER_CRITICAL()或直接给变量OsEnterSum赋1; 清除中断源; 通知中断控制器中断结束: 开中断: OS_EXIT_CRITICAL(); 用户处理程序; ,中断服务程序的编写,因为中断发生时肯定是允许中断的,所以如果用户在清除中断源之前调用C/OS-II的系统服务函数就很可能会造成芯片的中断系统工作异常而使程序工作

46、异常。因此在函数开始处关闭中断,或者直接给变量OSEnterSum赋1。如果用户程序没有这种情况,则不需要这个操作。在执行OS_EXIT_CRITICAL( )后,中断重新打开,如果在接下来的用户处理程序中发生中断,就可以实现中断嵌套。,主要内容,移植规划 C/OS-II的移植 嵌入式系统的初始化,初始化程序的下载执行,目标机,宿主机,1)通过编程器将可执行目标文件烧写到BootROM(ROM、EPROM、FLASH)等; 2)通过串行口和网口下载执行目标文件,要求宿主机系统上有数据传输工具程序、目标机装载器、嵌入式监视器或目标机系统上的调试代理。 3)通过JTAG或BDM接口下载;,嵌入式系统的初始化过程,嵌入式系统的初始化过程,硬件初始化阶段,1、复位向量 ENTRY b Res

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1