




已阅读5页,还剩124页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 嵌入式系统BootLoader的设计与实现 基于S3C44B0X的C/OS-移植 2 操作系统移植概述 u所谓操作系统的移植,是指一个操作系统能够在某个微处 理器平台上运行。 u操作系统C/OS-II是一个基于优先级的抢占式实时多任务 内核。C/OS-II的大部分代码是用ANSI C语言编写的,也 包含一小部分汇编语言代码,使之可以提供给不同架构的 微处理器使用。至今,从8位到64位,C/OS-II已经在多 种不同架构的微处理器上移植成功。 3 C/OS-II移植纲要 Phase 1Phase 2Phase 3Phase 3 1.C/OS-II移植的条件 2.编译器的选择 3.工作状态的选择 4.工作模式的选择 5.BootLoader 6.系统初始化流程 7.最小启动代码编写 8.C/OS-II相关文件修改 9.9.确保交叉编译环境确保交叉编译环境 正常工作正常工作 10.10.验证验证OSTaskStkInit()OSTaskStkInit() 和和OSStartHighRdy() OSStartHighRdy() 11.11.验证验证OSCtxSw()OSCtxSw() 12.12.验证验证OSTickISR()OSTickISR() 和和OSIntCtxSw() OSIntCtxSw() 移植前的规划操作系统移植 测试验证 4 Phase 1 移植前的规划 C/OS-II移植的条件1 2 3 4 编译器的选择 工作状态的选择 工作模式的选择 5 COS-II移植的条件 u处理器的C编译器能产生可重入代码; u在程序中可以打开/关闭中断; u处理器支持中断,并且能产生定时中断(通常为10-100Hz ); u处理器能支持一定数量的数据存储硬件堆栈; u处理器有将堆栈指针以及其它CPU寄存器的内容读出、并 存储到堆栈或内存中去的指令。 针对上述移植条件,基于ARM7TDMI Core的S3C44B0X处理 器满足其中的硬件要求。 6 Phase 1 移植前的规划 C/OS-II移植的条件1 2 3 4 编译器的选择 工作状态的选择 工作模式的选择 7 移植对编译器的要求及选择 u除了对硬件有要求外,还需要一个支持C语言和ARM汇编语 言的综合编译开发环境(IDE)。 u综合编译开发环境至少需要包括C编译器、ARM汇编器和链 接器。C编译器用来对C语言程序进行编译生成汇编代码。 由于移植时需要对CPU的寄存器进行操作,所以需要汇编 器能够支持汇编语言程序。链接器根据定位信息将不同的 模块(编译或汇编过的文件)链接成一个单一的、绝对定 位的可执行的映像文件。 u针对ARM处理器核的C语言编译器有很多,目前在国内比较 流行的有SDT、ADS、IAR、KEIL和GCC等; u其中SDT和ADS均为ARM公司自己开发,ADS为SDT的升级版 ,以后ARM公司不再支持SDT。 本移植采用ADS1.2集成开发环境进行程序的编译和调试。 8 Phase 1 移植前的规划 C/OS-II移植的条件1 2 3 4 编译器的选择 工作状态的选择 工作模式的选择 9 工作状态的选择 u自从ARM7TDMI Core以后,体系结构中具有T变种的ARM处 理器核可以工作在以下两种状态,并支持两个指令集: nARM状态 u ARM状态下执行字对准的32位ARM指令; nThumb状态 u Thumb状态下执行半字对准的16位Thumb指令; uCOS-II的任务可以在任何一种工作状态下运行,并可以 进行状态切换。 为了移植代码的编写简单,本移植只在ARM状态下实现。 10 Phase 1 移植前的规划 C/OS-II移植的条件1 2 3 4 编译器的选择 工作状态的选择 工作模式的选择 11 ARM处理器工作模式(1) 处理器模式说明备注 用户 (usr)正常程序工作模式不能直接切换到其它模式 系统 (sys) 用于支持操作系统的特权任 务 与用户模式类似,但具有可以直接切换 到其它模式等特权 快中断(fiq) 支持高速数据传输 及通道处 理 FIQ异常响应时进 入此模式 中断 (irq)用于通用中断处理IRQ异常响应时进 入此模式 管理 (svc)操作系统保护代码系统复位和软件中断响应时进 入此模式 中止 (abt) 用于支持虚拟内存和/或存储 器保护 在ARM7TDMI没有大用处 未定义(und) 支持硬件协处 理器的软件仿 真 未定义指令异常响应时进 入此模式 未定义 (und) 中止 (abt) 管理 (svc) 中断 (irq) 快中断 (fiq) 系统 (sys) 除用户模式外,其它模式均为特权 模式。ARM内部寄存器和一些片内外 设在硬件设计上只允许(或者可选为只 允许)特权模式下访问。此外,特权模 式可以自由的切换处理器模式,而用户 模式不能直接切换到别的模式。 12 ARM处理器工作模式(2) 处理器模式说明备注 用户 (usr)正常程序工作模式不能直接切换到其它模式 系统 (sys) 用于支持操作系统的特权任 务 与用户模式类似,但具有可以直接切换 到其它模式等特权 快中断(fiq) 支持高速数据传输 及通道处 理 FIQ异常响应时进 入此模式 中断 (irq)用于通用中断处理IRQ异常响应时进 入此模式 管理 (svc)操作系统保护代码系统复位和软件中断响应时进 入此模式 中止 (abt) 用于支持虚拟内存和/或存储 器保护 在ARM7TDMI没有大用处 未定义(und) 支持硬件协处 理器的软件仿 真 未定义指令异常响应时进 入此模式 未定义 (und) 中止 (abt) 管理 (svc) 中断 (irq) 快中断 (fiq) 这五种模式称为异常模式。它们除 了可以通过程序切换进入外,也可以由 特定的异常进入。当特定的异常出现时 ,处理器进入相应的模式。每种异常模 式都有一些独立的寄存器,以避免异常 退出时用户模式的状态不可靠。 本移植中COS-II的任务正常运行在管理 (SVC)模式。 13 Phase 2 操作系统移植 BootLoader 1 2 3 4 系统初始化流程 最小启动代码编写 C/OS-II相关文件修改 14 BootLoader的基本概念 u要想让COS-II在S3C44B0X处理器上正常运行,我们需要 对系统的硬件环境进行初始化。 u对于PC机,其开机后操作系统启动前的硬件初始化操作是 由BIOS(Basic Input/Output System)完成的,但对于 嵌入式系统来说,出于通用性、价格方面的考虑,通常并 没有像BIOS那样的固件程序,因此启动时用于完成初始化 操作的引导加载程序必须自行编写完成,这段程序一般被 称为Bootloader程序。 uBootLoader是系统加电(或复位)后运行的第一段软件代 码。通过这段代码,我们可以初始化系统硬件设备、建立 内存空间的映射图,从而将系统的软硬件环境带到一个合 适的状态,以便最终调用操作系统内核。 u简单地说,BootLoader就是在操作系统内核运行之前运行 的一段初始化程序。 15 BootLoader的特点 uBootLoader除了依赖CPU的体系结构外,还依赖于具体的 嵌入式板级设备的配置,比如板卡的硬件地址分配,RAM 芯片的类型,其它外设的类型等。对于两块不同的嵌入式 开发板,即使它们是基于同一种CPU而构建的,如果他们 的硬件资源和配置不一致,要想让运行在一块板子上的 BootLoader程序也能运行在另一块板子上,也还是需要作 一些必要的修改。 u因此,为嵌入式系统建立一个通用的BootLoader是很困难 的。尽管如此,我们仍然可以对BootLoader(尤其是基于 同种Core的微处理器)归纳出一些通用的概念和设计思路 ,用来指导用户特定的BootLoader设计与实现。 16 BootLoader的启动过程 u为了增加BootLoader的通用性和可移植性,本文把启动过 程分为phasel和phase2两个阶段。 nphase1阶段执行的是用汇编语言来实现的依赖CPU体系结构的代码 ,这样可以提高系统的启动速度; nphase2阶段完成的是OS内核启动前的准备工作,多采用处理能力 强、可移植性好的C语言来实现。 uphase1阶段执行的代码,我们称之为最小启动代码。所谓 最小启动代码是指为了完成系统(OS或用户应用程序)启 动所必须的最少硬件的初始化程序。 17 BootLoader的安装媒介 u系统加电或复位后,所有的CPU通常都从CPU制造商预先安 排的地址上取指令。 u基于ARM7TDMI Core的嵌入式系统中,系统在上电或复位 时是从0x00000000地址开始取第一条指令执行,而在这个 地址处安排的通常就是系统的BootLoader程序。 u嵌入式系统通常都有某种类型的固态存储设备(比如:ROM 、EPROM或FLASH等)被安排这个起始地址上用来存放 BootLoader程序。 18 BootLoader的下载方式 p 通过编程器将可执行目标文件烧写到 BootROM中; p 通常通过串行口、网口或JTAG等接口 下载。 串口 网口 JTAG 目标机 MPU RAM BOOT ROM 下载工具 宿主机 19 Phase 2 操作系统移植 BootLoader 1 2 3 4 系统初始化流程 最小启动代码编写 C/OS-II相关文件修改 20 嵌入式系统的初始化流程 1 2 3 4 5 6 7 硬件 初始化 RTOS 初始化 软件 初始化 设置 中断向量表 最小硬件 初始化 RTOS 初始化 启动RTOS 最 小 启 动 代 码 phase1 phase2 用户程序 RTOS运行环境 初始化 硬件抽象层 初始化 用户程序 初始化 21 嵌入式系统的初始化流程(1) 1 2 3 硬件初始化阶段 最小硬件 初始化 最 小 启 动 代 码 p 中断向量表放在上电后映射在从 0x00000000开始的8*4个字节的连续存储 空间中,其作用是指定了各种异常中断 处理程序的入口地址。 phase1 设置中断向量表 设置 中断向量表 RTOS运行环境 初始化 22 嵌入式系统的初始化流程(2) 硬件初始化阶段 p 禁用看门狗定时器; p 屏蔽所有中断; p 设定CPU的时钟频率; p 初始化存储器; p 分配各种模式下的栈空间。 最小硬件初始化 1 2 3 最小硬件 初始化 最 小 启 动 代 码 设置 中断向量表 RTOS运行环境 初始化 phase1 23 嵌入式系统的初始化流程(3) 硬件初始化阶段 p 为RTOS运行准备合适的RAM空间; p 呼叫RTOS主(Main)程序。 RTOS运行环境初始化 1 2 3 最小硬件 初始化 最 小 启 动 代 码 设置 中断向量表 RTOS运行环境 初始化 phase1 24 嵌入式系统的初始化流程(4) RTOS初始化阶段 4 5 6 硬件抽象层 初始化 RTOS 初始化 启动RTOS 硬件抽象层初始化 p 系统cache、总线设置; p 中断及中断向量处理子程序初始化; p I/O端口配置; p 初始化定时器,为时钟中断做好准备; p 对RTOS所需的其它设备初始化。 phase2 25 嵌入式系统的初始化流程(5) RTOS初始化阶段 4 5 6 硬件抽象层 初始化 RTOS 初始化 启动RTOS RTOS初始化 p RTOS内核启动参数初始化; p RTOS扩展部件初始化。 phase2 26 嵌入式系统的初始化流程(6) RTOS初始化阶段 4 5 6 硬件抽象层 初始化 RTOS 初始化 启动RTOS 启动RTOS p 运行优先级最高的就绪任务; p 启动RTOS时钟中断。 phase2 27 嵌入式系统的初始化流程(7) 用户程序初始化阶段 用户程序初始化 p 用户程序正常运行所进行的初始化 。 7用户程序 用户程序 初始化 28 Phase 2 操作系统移植 BootLoader 1 2 3 4 系统初始化流程 最小启动代码编写 C/OS-II相关文件修改 29 设置中断向量表 u因为中断向量表中每种异常只分配4个字节,所以不能放 下整个异常中断处理程序,只能放一条跳转指令,用以跳 转到相应的异常中断处理程序。 向量地址异常中断类型转移指令 0x0000001CFIQLDR PC,=FIQHandler 0x00000018IRQLDR PC,=IRQHandler 0x00000014ReservedNOP 0x00000010Data AbortLDR PC,=DabortHandler 0x0000000CPrefech AbortLDR PC,=PabortHandler 0x00000008SWILDR PC,=SWIHandler 0x00000004Undefined InstructionLDR PC,=UndefHandler 0x00000000ResetB ResetHandler 30 禁用看门狗定时器和屏蔽所有外部中断 u示意代码分析 WTCON EQU 0x01d30000 ;看门狗定时器控制寄存器 INTMSK EQU 0x01e0000c ;中断屏蔽寄存器 ResetHandler LDR r0,=WTCON LDR r1,=0x00000000 ;Watch Dog Disable STR r1,r0 LDR r0,=INTMSK LDR r1,=0x07ffffff ;All Interrupt Disable STR r1,r0 说明:默认初始状态允许看门狗定时器工作(p496),所以要关闭。 如果要屏蔽所有中断,可用MRS指令设置CPSR的I/F位(p431,p440)。 31 S3C44B0X时钟发生器组成(1) uS3C44B0X的时钟发生器可产生CPU和外设所需要的时钟信 号。时钟发生器可在S/W的控制下向外设提供时钟信号, 也可断开时钟与每个外设的连接来降低功耗。首先要求要 确定主时钟MCLK,然后以主时钟作为一种基准,通过分频 控制定时器,串口等外设的时钟频率。 uS3C44B0X时钟发生器组成: n主时钟源有两个:一个是XTAL0和EXTAL0连接的外部晶振,另一个 是EXTCLK连接的外部时钟; nPLL的功能是以低频振荡器的输出作为输入,产生S3C44B0X需要的 高频信号; n还有一个时钟控制逻辑部件来可产生稳定的时钟频率。 uS3C44B0X时钟源的选择由处理器的两个引脚OM3:2控制 。OM3:2=00时钟源为晶振,OM3:2=01时钟源为外部时 钟。 本移植采用晶振作为时钟源。晶振为6MHz,即fin=6MHz。 32 S3C44B0X时钟发生器组成(2) u时钟发生器框图 说明:时钟发生器(p446) 33 PLL锁相环原理框图 uPLL锁相环框图 说明:PLL锁相环原理(p446-p447) 34 设置PLL分频器 u输出时钟频率fpllo和输入的时钟频率fin的关系如下: fpllo=(m*fin)/(p*2s) 其中, m=MDIV (分频器M的分频值)+8, p=PDIV (分频器P的分频值)+2, s=SDIV (分频器S的分频值) uPLL值的选择向导: nfpllo必须大于20Mhz,小于66MHz; nfpllo*2s必须小于170MHz; 35 时钟控制逻辑部件 u当PLL被配置为一个新的频率值时,时钟控制逻辑部件在 PLL输出稳定之前禁止fout,直到PLL锁定系统时钟后取消 禁止。PLL锁时实际上是PLL输出稳定所需要的时间,这个 时间应长于208us。锁定时间值计算公式如下: tlock=(1/fin)*n 其中n=LTIMECNT值。 36 设定CPU及各功能模块时钟频率 u示意代码分析 PLLCON EQU 0x01d80000 ;PLL控制寄存器 CLKCON EQU 0x01d80004 ;时钟控制寄存器 LOCKTIME EQU 0x01d8000c ;锁时计数寄存器 M_DIV EQU 0x48 P_DIV EQU 0x02 S_DIV EQU 0x01 LDR r0,=LOCKTIME LDR r1,=0x00000fff ;tlock=(1/fin)*LTIMECNT STR r1,r0 LDR r0,=PLLCON ;fin=6MHz,fout=60MH LDR r1,=(M_DIVOSTCBStkPtr 按照OSTaskStkInit()中相反顺序 从新任务栈中恢复处理器的所有寄存器 模拟中断返回 84 OS_CPU_A.S-OSStartHighRdy()代码分析 u示意代码分析 OSStartHighRdy ;MSR CPSR_c, #(ARM_INT_DIS| ARM_SVC_MODE) BL OSTaskSwHook LDR R0, =OSRunning MOV R1, #1 STRB R1, R0 LDR R0, =OSTCBHighRdy LDR R0, R0 LDR SP, R0 ;LDR R1, =OSTCBCur ;STR R0, R1 LDMFD SP!, R0 MSR SPSR_cxsf, R0 LDMFD SP!, R0 MSR CPSR_cxsf, R0 LDMFD SP!, R0-R12, LR, PC 关中断,切换到SVC模式 调用OSTaskSwHook()函数 得到将要恢复 运行任务的栈指针 OSRunning = TRUE 从新任务栈中恢复处理器的 所有寄存器,模拟中断返回 85 Contents OSStartHighRdy()1 OSCtxSw()2 OSTickISR()3 OSIntCtxSw()4 86 OS_CPU_A.S-OSCtxSw() uOSCtxSw()是C/OS-II从低优先级任务切换到高优先级任 务时用到的任务级切换函数。该函数实现的功能可以分为 两部分,第一部分代码用来保存正在运行(将被中断)任 务的当前状态(即处理器寄存器的全部内容)到该任务的 栈中;第二部分代码是把将要运行的更高优先级任务的当 前状态从栈中恢复到处理器寄存器中。 87 OS_CPU_A.S-OSCtxSw()执行流程图 调用接口函数 OSTaskSwHook() OSPrioCur = OSPrioHighRdy; OSTCBCur = OSTCBHighRdy; 得到将要恢复运行任务的栈指针: SP = OSTCBHighRdy-OSTCBStkPtr 按照OSTaskStkInit()中相反顺序 从新任务栈中恢复处理器的所有寄存器 模拟中断返回 保存处理器寄存器; 在当前任务的任务控制块中保存栈指针: OSTCBCur-OSTCBStkPtr=SP 88 OS_CPU_A.S-OSCtxSw()实现分析(1) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc Before OSTCBStkPtr I F T MODE CPSR: 1100x13 OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy n 说明: 根据OSTaskStkInit()函数初始化的情况 ,当前任务运行在ARM状态、SVC模式。 当任务级的调度函数OS_Sched()函数调 用宏OS_TASK_SW()(即OSCtxSw())时, 是在临界段中进行的,所以IRQ和FIQ中 断都禁用。当OS_Sched ()调用 OSCtxSw()时,类似于下面操作: BL OSCtxSw 所以OSCtxSw()返回地址保存在R14_svc 。 89 OS_CPU_A.S-OSCtxSw()实现分析(2) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw STMFD SP!, LR STMFD SP!, LR STMFD SP!, R0-R12 MRS R0, CPSR STMFD SP!, R0 MRS R0, SPSR STMFD SP!, R0 Current Task Stack SVC Mode Before After OSTCBStkPtr OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy 保存处理器寄存器 I F T MODE CPSR: 1100x13 90 OS_CPU_A.S-OSCtxSw()实现分析(3) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw LDR R0, =OSTCBCur LDR R1, R0 STR SP, R1 Current Task Stack SVC Mode OSTCBStkPtr OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy OSTCBCur-OSTCBStkPtr=SP I F T MODE CPSR: 1100x13 91 OS_CPU_A.S-OSCtxSw()实现分析(4) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw BL OSTaskSwHook LDR R0, =OSPrioCur LDR R1, =OSPrioHighRdy LDRB R1, R1 STRB R1, R0 Current Task Stack SVC Mode OSTCBStkPtr OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy 将新任务的优先级 复制给当前任务优先级 在 OS_CPU_C.C中定义 I F T MODE CPSR: 1100x13 92 OS_CPU_A.S-OSCtxSw()实现分析(5) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw LDR R0, =OSTCBCur LDR R1, =OSTCBHighRdy LDR R1, R1 STR R1, R0 Current Task Stack SVC Mode OSTCBStkPtr I F T MODE CPSR: 1100x13 OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy OSTCBCur=OSTCBHighRdy 93 OS_CPU_A.S-OSCtxSw()实现分析(6) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw LDR SP, R1 New Task Stack SVC Mode OSTCBStkPtr OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy SP=OSTCBHighRdy-OSTCBStkPtr I F T MODE CPSR: 1100x13 94 OS_CPU_A.S-OSCtxSw()实现分析(7) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) CPSR SPSR_svc OSCtxSw LDMFD SP!, R0 MSR SPSR_cxsf, R0 LDMFD SP!, R0 MSR CPSR_cxsf, R0 LDMFD SP!, R0-R12, LR, PC SVC Mode Before After OSTCBStkPtr OS_TCBOS_TCB OSTCBCur OSTCBStkPtr OS_TCBOS_TCB OSTCBHighRdy New Task Stack 从新任务堆栈中恢复 处理器所有寄存器的值 模拟中断返回 运行新任务 I F T MODE CPSR: 1100x13 95 Contents OSStartHighRdy()1 OSCtxSw()2 OSTickISR()3 OSIntCtxSw()4 96 OS_CPU_A.S-时钟中断 uC/OS-要求用户提供一个周期性的时钟资源,来实现 时间的延时和超时功能。时钟节拍通常每秒发生10100次 /秒。为了完成该任务,可以使用硬件时钟,也可以从交 流电中获得50/60Hz的时钟频率。本移植采用S3C44B0X的 PWM定时器Timer1作为C/OS-系统时钟。 u用户必须在开始多任务调度后(即调用OSStart()后)允许 时钟节拍中断。但由于OSStart()函数不会返回,用户无 法实现这一操作。然而,可以在OSStart()运行后, C/OS-启动运行的第一个任务中初始化节拍中断。这 个任务是调用OSStart()之前建立的任务中优先级最高的 任务。通常所犯的错误是在调用OSInit()和OSStart()之 间允许时钟节拍中断。在这种情况下,C/OS-的运行 状态不确定,用户的应用程序也可能会崩溃。 97 OS_CPU_A.S-正确位置启动时钟节拍中断 u示意代码分析 int Main(void) OSInit(); / 初始化 /*应用程序初始化代码*/ /*建立至少一个任务*/ 启动时钟节拍中断; OSStart(); /开始多任务调度 return 0; /Main 在不正确的位置启动时钟节拍中断 int Main(void) OSInit(); / 初始化 /*应用程序初始化代码*/ /*建立至少一个任务*/ OSStart(); /开始多任务调度 return 0; /Main void 第一个任务(void *pdata) 启动时钟节拍中断; 正确的位置启动时钟节拍中断 98 OS_CPU_A.S-OSTickISR() uOSTickISR()是系统时钟节拍中断服务函数。其主要任务 是负责处理时钟中断,为内核提供时钟节拍。 n该函数调用OSIntEnter()时把全局变量OSIntNesting加1来记录中 断嵌套的层数; n调用OSTimeTick()主要做了两件事:一是给计数器OSTime加1;二 是遍历任务控制块链表,了解每个任务的延时状态,使其中已经 到了延时时限的非挂起任务进入就绪状态。 n调用OSIntExit()函数目的是决定是否因为当前中断服务程序的执 行,使得更高优先级的任务就绪。如果有更高优先级任务就绪 OSIntExit()就不会返回到被中断任务,而是切换到更高优先级的 任务;否则切换回被中断任务继续执行。 99 OS_CPU_A.S-OSTickISR()执行流程图 重新允许中断(可选); 给产生中断的设备清中断; 调用OSTimeTick(); 调用OSIntExit(); 恢复处理器寄存器; 执行中断返回 保存处理器寄存器; 调用OSIntEnter()或者直接将 OSIntNesting加1; if(OSIntNesting=1) OSTCBCur-OSTCBStkPtr=SP; 100 OS_CPU_A.S-OSTickISR()实现分析(1) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc Before OSTCBStkPtr I F T MODE CPSR: 0100x13(SVC) OS_TCBOS_TCB OSTCBCur n 说明: p根据前面所述的C/OS- 的运行环境和 OSTaskStkInit()函数初 始化的情况,当前任务在 被中断之前还是运行在 ARM状态、SVC模式、允许 IRQ中断和禁用FIQ中断。 p同时,我们采用矢量中断 模式,中断服务程序 OSTickISR()中不允许中 断嵌套。 101 OS_CPU_A.S-OSTickISR()实现分析(2) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc Before I F T MODE SPSR_irq: 0x13(SVC)010 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_irq(SP) R14_irq(LR) R15(PC) IRQ Mode CPSR SPSR_irq I F T MODE CPSR: 0x12(IRQ)011 IRQ Stack n说明: 当发生时钟中断时,系统自动完成以 下工作: p将PC(PC=中断返回地址+4)的 值保存在LR(R14_irq)中; p将CPSR_svc保存在SPSR_irq中 ; p由SVC工作模式切换到IRQ工作 模式; p禁用IRQ(CPSR7=1); pR13_irq 指向IRQ模式下的栈顶 。 102 OS_CPU_A.S-OSTickISR()实现分析(3) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) SVC Mode CPSR SPSR_svc R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_irq(SP) R14_irq(LR) R15(PC) IRQ Stack CPSR SPSR_irq OSTickISR STMFD SP!, R0-R2 R0 R1 R2 Before After IRQ Mode 一开始,任务运行在SVC模式,由于时钟中断切换 到了IRQ模式,为了保护被中断任务的CPU寄存器, 必须切换回SVC模式。如果直接由IRQ模式切换回 SVC模式,会破坏原来的现场。因为R13、R14和 SPSR均为各自模式下的影子寄存器,在其它模式下 不可见,所以采用在各种模式下均可见的不分组寄 存器R0-R3来存放上述影子寄存器。为了免于破坏 数据,先把R0-R3保存在IRQ模式下的栈中。 I F T MODE SPSR_irq: 0x13(SVC)010 I F T MODE CPSR: 0x12(IRQ)011 103 OS_CPU_A.S-OSTickISR()实现分析(4) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) SVC Mode CPSR SPSR_svc R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_irq(SP) R14_irq(LR) R15(PC) IRQ Stack CPSR SPSR_irq OSTickISR MRS R0, SPSR SUB LR, 4 MOV R1, LR MOV R2, SP R0 R1 R2 IRQ Mode PC- 4 保存SPSR_irq到R0; 保存返回地址到R1; 保存R13_irq到R2; I F T MODE SPSR_irq: 0x13(SVC)010 I F T MODE CPSR: 0x12(IRQ)011 104 OS_CPU_A.S-OSTickISR()实现分析(5) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) SVC Mode CPSR SPSR_svc R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_irq(SP) R14_irq(LR) R15(PC) IRQ Stack CPSR SPSR_irq OSTickISR ADD SP, SP, #(3 * 4) R0 R1 R2 IRQ Mode After Before I F T MODE SPSR_irq: 0x13(SVC ) 010 I F T MODE CPSR: 0x12(IRQ)011 调整IRQ模式下SP指针 105 OS_CPU_A.S-OSTickISR()实现分析(6) R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) SVC Mode CPSR SPSR_svc R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_irq(SP) R14_irq(LR) R15(PC) IRQ Stack CPSR SPSR_irq I F T MODE CPSR: 0x13(SVC ) 011 OSTickISR MSR CPSR_cxsf,#(ARM_INT_DIS|ARM_SVC_MODE) R0 R1 R2 IRQ Mode 切换到SVC模式 禁用IRQ中断 106 OS_CPU_A.S-OSTickISR()实现分析(7) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR STMFD SP!, R1 STMFD SP!, LR STMFD SP!, R3-R12 IRQ Stack R0 R1 R2 保存被中断任务的返回地址; 保存R3-R12和R14_svc 107 OS_CPU_A.S-OSTickISR()实现分析(8) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR LDMIA R2!, R3-R5 STMFD SP!, R3-R5 STMFD SP!, R0 MRS R1, SPSR STMFD SP!, R1 IRQ Stack R0 R1 R2 保存R0-R2,CPSR和SPSR_svc 108 OS_CPU_A.S-OSTickISR()实现分析(9) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq-4) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR BL OSIntEnter OSIntNesting+ 109 OS_CPU_A.S-OSTickISR()实现分析(10) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR LDR R3, =OSTCBCur LDR R4, R3 STR SP, R4 OSTCBStkPtr OS_TCBOS_TCB OSTCBCur if(OSIntNesting=1) OSTCBCur-OSTCBStkPtr=SP; 110 OS_CPU_A.S-OSTickISR()实现分析(11) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR BL OSTimeTick BL ClearTickIntpnd OSTimeTick()函数通过任务控制块中的 OSTCBDly来维护C/OS-内部的延时或超时。 ClearTickIntpnd()函数实现对系统时钟 中断设备清除中断,为下一次中断做好准备。 111 OS_CPU_A.S-OSTickISR()实现分析(12) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15(PC) Current Task Stack SVC Mode CPSR SPSR_svc I F T MODE CPSR: 1100x13(SVC) OSTickISR BL OSIntExit OSIntExit()函数决定是否因为这个中断服务 程序的执行,使得更高优先级的任务就绪。 如果更高级别的任务就绪, OSIntExit()就 不会返回到被中断的任务,而是调用 OSIntCtxSw()切换到更高优先级的任务。 如果没有跟高优先级的任务进入就绪态, OSIntExit()就会返回到中断服务程序。此时 只需要简单地恢复刚才保存的CPU寄存器就 可以了。 112 OS_CPU_A.S-OSTickISR()实现分析(13) SPSR_svc CPSR R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14_svc(LR) R15(PC) R0(SPSR_irq) R1(R14_irq) R2(R13_irq) R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13_svc(SP) R14_svc(LR) R15
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 温控结晶机理研究-洞察及研究
- 人际信任演化模型-洞察及研究
- 售楼部日常管理制度
- 器械出入库管理制度
- 团委室卫生管理制度
- 图书借阅与管理制度
- 土地全链条管理制度
- 地震科普馆管理制度
- 垃圾库防火管理制度
- 培训班收费管理制度
- 党课课件含讲稿:《关于加强党的作风建设论述摘编》辅导报告
- GB/T 19023-2025质量管理体系成文信息指南
- 多余物管理制度
- 2024北京朝阳区三年级(下)期末语文试题及答案
- 灌肠技术操作课件
- 电梯维保服务投标方案
- 郁证--PPT课件(PPT 35页)
- 1才小型浇注生产线方案
- 半命题作文“-------的你--------的我”写作指导及范文
- 证券从业资格考试金融市场基础知识
- FMEA试题集(有标准规范答案)39709
评论
0/150
提交评论