




免费预览已结束,剩余29页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2010届电子信息工程专业毕业设计(论文)目 录摘要1关键词11 引言12 C/OS-II简介22.1 C/OS-II的特点22.2 C/OS-II的体系结构33 移植规划33.1 移植条件33.1.1 可重入代码与非可重入代码43.1.2 OS_ENTER_CRITICAL( )与OS_EXIT_CRITICAL( )43.2 移植要求43.3 移植需要编写的文件43.4 移植代码包括的主要内容53.5 编译器的选择54 移植的实现64.1 OS_CPU.H的移植64.1.1数据类型的定义64.1.2堆栈的定义64.1.3中断与临界区代码74.1.4使用软中断SWI作底层接口84.2 OS_CPU_C.C的移植94.2.1 OSTaskStkInit( )94.2.2 Hook( )函数104.3 OS_CPU_A.ASM的移植114.3.1 OSStartHighRdy()函数114.3.2 OSCtxSw( )函数124.3.3 OSIntCtxSw()函数134.3.4 OSTickISR()函数145 嵌入式系统的初始化165.1初始化程序的下载执行165.2嵌入式系统的初始化过程175.2.1硬件初始化阶段175.2.2 RTOS初始化阶段185.3 ARM920T系统初始化的一般过程195.3.1设置程序入口指针195.3.2设置中断向量195.4初始化存储器系统205.4.1存储器地址分布205.4.2 ROM地址重映射的实现205.5初始化堆栈215.6初始化应用程序执行环境225.6.1初始化C环境225.6.2改变处理器模式235.6.3调用C程序235.7 uC/OS系统的初始化235.7.1 ARM的硬件抽象层uHALuC/OS245.7.2 ARMTargetInit()函数结构245.7.3 uHAL的功能256 移植测试256.1测试移植代码256.1.1确保编译器、汇编编译器及链接器正常工作256.1.2验证OSTskStkInit() 和OSStartHighRdy()函数256.1.3验证OSCtxSw() 函数266.1.4验证OSIntCtxSw()和OSTickISR()函数266.2在S3C2440上测试移植结果266.2.1编译uCOS2266.2.2把uCOS2下载到内存中运行287 结论30致 谢31参考文献31英文翻译3212010届电子信息工程专业毕业设计(论文)实时操作系统C/OS-II在ARM上的移植研究陈利顺重庆三峡学院物理与电子工程学院电子信息工程专业06级 重庆万州 404000摘要 本设计采用三星公司生产的一款基于ARM920T核的高性能低功耗soc芯片S3C2440作为移植的硬件平台。对实时操作系统C/OS-II的特点、体系结构、移植所需要的条件、移植所需要编写的文件,移植所需要的编译器作了深入的了解,通过编写移植代码,对移植的测试,实现了C/OS-II在S3C2440的移植。关键词 嵌入式系统 C/OS-II 移植1. 引言随着信息化技术的发展和数字化产品的普及,以计算机技术、芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用的热点。对功能、可靠性、成本、体积和功耗严格要求的嵌入式系统一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序等四个部分组成,其中嵌入式微处理器和嵌入式操作系统分别是其硬件和软件的核心。 自从嵌入式系统开发以来, 很长时间都采用前后台系统软件设计模式: 主程序为一个无限循环, 单任务顺序执行。通过设置一个或多个中断来处理异步事件。这种系统对于简单的应用是可以的, 但对于实时性要求比较高的处理任务较多的应用, 就会暴露出实时性差、系统可靠性低、稳定性差等缺点。C/OS-II是一种给予优先级的抢占式多任务实时操作系统, 包含了实时内核、任务管理、时间管理、任务间通信同步(信号量, 邮箱, 消息队列)和内存管理等功能。它可以使各个任务独立工作, 互不干涉, 很容易实现准时而且无误执行, 使得实时应用程序的设计和扩展变得容易, 使得应用程序的设计过程大为减化。而且它内核源代码公开,移植性强, 为编程人员提供了很好的一个软件平台。ARM(Advanced RISC Machines)公司是全球领先的16/32位RISC微处理器知识产权设计供应商。ARM公司通过转让高性能、低成本、低功耗的RISC微处理器、外围和系统芯片设计技术给合作伙伴,是他们能使用这些技术来生产各具特色的芯片。ARM已成为移动通信、手持设备、多媒体数字消费嵌入式解决方案的RISC标准。ARM处理器有三大特点:小体积、低功耗、低成本而高性能;16/32位双指令集;全球众多的合作伙伴。三星公司推出的16/32位RISC微处理器S3C2440,为手持设备和一般类型应用提供了低价格、低功耗、搞性能小型微控制器的解决方案。S3C2440的杰出的特点是其核心处理器(CPU),是一个由Advanced RISC Machines有限公司设计的16/32位ARM920T的RISC处理器,实现了MMU,AMBA,BUS和Harvard高速缓冲体系结构。这一结构具有独立的16KB指令Cache和16KB数据Cache。每个都是由具有8字长的行组成,通过提供一套完整的通用系统外设,S3C2440减少整体系统成本和无需配置额外的组件,因此本文选定三星公司生产的一款基于ARM920T核的高性能低功耗SOC芯片S3C2440作为移植方案的硬件平台。2. C/OS-II简介C/OS-是由Jean J . Labrosse 先生编写的完整的可移植、固化、裁剪的占先式实时多任务内核。是用ANSI的C语言编写的,包含小部分汇编语言代码,使之可供不同架构的微处理器使用。至今。从8位到64位,C/OS-已在超过40种不同架构的微处理器上运行。C/OS-功能强大,支持56个用户任务,支持信号量、邮箱、消息队列等多种常用的进程间通信机制,现已成功应用到众多商业嵌入式系统中,是一个成熟稳定的实时内核。2.1C/OS-II特点1) 提供源代码:购买作者撰写的嵌入式实时操作系统C/OS-II一书即可获得C/OS-II V2.52版本的所有源代码,购买此书的其它版本可以获得相应版本的全部源代码。2) 可移植性:C/OS-II的源代码绝大部分是使用移植性很强的ANSI C写的,将与微处理器硬件相关的汇编语言使用量压缩到最低的限度,以使C/OS-II便于移植到其它微处理器上。目前,C/OS-II已经被移植到多种不同架构的微处理器上。3) 可固化:只要具备合适的软硬件工具,就可以将C/OS-II嵌入到产品中成为产品的一部分。4) 可剪裁:C/OS-II使用条件编译实现可剪裁,用户程序可以只编译自己需要的(C/OS-II的)功能,而不编译不要需要的功能,以减少C/OS-II对代码空间和数据空间的占用。5) 可剥夺:C/OS-II是完全可剥夺型的实时内核,C/OS-II总是运行就绪条件下优先级最高的任务。6) 多任务:C/OS-II可以管理64个任务,然而,C/OS-II的作者建议用户保留8个给C/OS-II。这样,留给用户的应用程序最多可有56个任务。7) 可确定性:绝大多数C/OS-II的函数调用和服务的执行时间具有确定性,也就是说,用户总是能知道C/OS-II的函数调用与服务执行了多长时间。8) 任务栈:C/OS-II的每个任务都有自己单独的栈,使用C/OS-II的占空间校验函数,可确定每个任务到底需要多少栈空间。9) 系统服务:C/OS-II提供很多系统服务,例如信号量、互斥信号量、时间标志、消息邮箱、消息队列、块大小固定的内存的申请与释放及时间管理函数等。10) 中断管理:中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。 11) 稳定性与可靠性:C/OS-II是C/OS的升级版,C/OS自1992年以来已经有数百个商业应用。C/OS-II与C/OS的内核是一样的,只是提供了更多的功能。2000年7月,C/OS-II在一个航空项目中得到了美国联邦航空管理局对商用飞机的、符合RTCA DO 178B标准的认证。这表明,该操作系统的质量得到了认证,可以在任何应用中使用。2.2C /OS的体系结构图1 C /OS-的硬件/软件体系结构上图给出了C/OS-的软件体系结构,它包括如下结构:1) 应用程序软件是用户根据实际需求编写的代码,用户根据自己的应用系统,通过编写与应用相关的代码定制合适的内核服务功能,由此来实现对C /OS-的裁剪。2) 与处理器无关的代码就是通常所说的操作系统内核,它为C/OS-提供所有的系统服务,并将应用系统和底层硬件有机地结合成一个实时系统。这部分源代码是完全公开的。3) 要使同一个内核能适用于不同的硬件体系,就需要在内核和硬件之间添加一个中间层,这就是与处理器相关的代码。所谓移植,就是编写与处理器相关的这部分代码。3. 移植规划3.1移植条件一般来说,能移植C /OS-的微处理器必须满足以下条件:1) 处理器的C编译器能产生可重入型代码。2) 处理器支持中断,并且能产生定时中断。3) 用C语言就可以开/关中断。4) 处理器能支持一定数量的数据存储硬件堆栈。5) 处理器有将堆栈指针及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令。3.1.1可重入代码与非可重入代码可重入的代码指的是一段代码(比如:一个函数)可以被多个任务同时调用,而不必担心会破坏数据。也就是说,可重入型函数在任何时候都可以被中断执行,过一段时间以后又可以继续运行,而不会因为在函数中断的时候被其他的任务重新调用,影响函数中的数据。3.1.2 OS_ENTER_CRITICAL( )与OS_EXIT_CRITICAL( ) 同其他内核一样,C/OS- 为了处理临界段(critical sections)代码,须关中断,处理完毕后,再开中断。关中断使得C/OS- 能够避免同时有其他任务或中断服务进入临界代码段。在C/OS-中,可以通过:OS_ENTER_CRITICAL( )和OS_EXIT_CRITICAL( )宏来控制系统关闭或者打开中断。这需要处理器的支持。在S3C2440的处理器上,可以设置相应的寄存器来关闭或者打开系统的所有中断。OS_ENTER_CRITICAL( )和OS_EXIT_CRITICAL( )总是成对使用的,把临界段代码封包起来。 C/OS-是通过处理器产生的定时器的中断来实现多任务之间的调度的。在S3C2440的处理器上可以产生定时器中断3.2移植要求要移植一个操作系统到一个特定的CPU体系结构并不是一件很容易的事情,它对移植者有以下要求:(1)对目标体系结构要有很深了解;(2)对OS原理要有较深入的了解;(3)对所使用的编译器要有较深入的了解;(4)对需要移植的操作系统要有相当的了解;(5)对具体使用的芯片也要一定的了解3.3移植需要编写的文件C/OS-II的代码被分成3个部分:与处理无关的代码;与应用相关的代码;与处理器相关的代码。移植时只要考虑与处理器相关的代码。与处理器相关的代码由3个文件组成:OS_CPU.H文件;OS_CPU_C.C文件;OS_CPU_A.S文件。根据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)可以直接使用C语言保存CPU的所有寄存器。OS_CPU.H文件;OS_CPU_C.C文件;OS_CPU_A.S文件代码的正确配置与编写,只能确保基于S3C2440的C/OS-II微内核代码形成,并不能立即烧入目标板运行,要在目标板上运行,必须还要编写目标板初始化引导程序,初始化引导程序主要实现硬件初始化、内存映射、中断向量初始化、系统堆栈空间的分配等功能,以引导C/OS-II的正确运行。3.4移植代码包括的主要内容移植内容类型所属文件描述BOOLEAN INT8UINT8S数据类型OS_CPU.H与编译器无关的数据类型OS_STK数据类型OS_CPU.H堆栈的数据类型OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()宏OS_CPU.H开关中断的代码OS_STK_GROWTH常量OS_CPU.H定义堆栈的增长方向S_TASK_SW函数OS_CPU.H任务切换时执行的代码OSTaskStkInit()函数OS_CPU_C.C任务堆栈初始化函数OSInitHookBegin()OSInitHookEnd()函数OS_CPU_C.CuCOS-II在执行某些操作时调用的用户函数,一般为空OSStartHighRdy()函数OS_CPU_A,ASM进入多任务环境时运行优先级最高的任务OSInitCtxSw()函数OS_CPU_A,ASM中断退出时的任务切换函数OSTickISR()中断服务程序OS_CPU_A,ASM时钟节拍中断服务程序图2移植代码包括的主要内容实际上,还有一个文件很重要,它就是IRQ.INC,它定义了一个汇编宏,它是C/OS-II 对ARM9通用的中断服务程序的汇编与C函数接口代码。时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过IRQ.INC简化用户代码的编写。3.5编译器的选择1) 针对ARM处理器核的C语言编译器有很多,如SDT、ADS、IAR、TASKING和GCC等2) 目前在国内最流行的是ADS、SDT和GCC3) SDT和ADS均为ARM公司自己开发,ADS为SDT的升级版,以后ARM公司不再支持SDT,故不选择SDT。GCC虽然支持广泛,很多开发套件使用它作为编译器,但是与ADS比较其编译效率较低,这对充分发挥芯片性能不利故本次设计考虑使用ADS编译程序和调试程序。4.C/OS-II 移植的实现实际上,C /OS-可以简单地看作是一个多任务调度器,在这个任务调度器上添加了与多任务操作系统相关的一些系统服务,如信号量、邮箱等,其90 %的代码是用C语言写的。移植工作主要集中在多任务切换的实现上,因为这部分代码用来保存和恢复CPU现场(即写/读相关寄存器) ,不能用C语言实现,而只能用汇编语言完成。C /OS- 的全部源代码量大约是6 0007 000行,将其移植到ARM处理器上,需要修改3个与ARM 体系结构相关的文件: OS_CPU.H, OS_CPU_C.C, OS_CPU_A. ASM,代码量大约是500行。下面分别介绍这3个文件的移植工作。4.1 OS_CPU.H的移植在这个文件中主要定义了与编译器和处理器相关的代码,这部分代码包括数据类型定义、堆栈单位定义、堆栈增长方向定义、关中断和开中断的宏定义以及进行任务切换的宏定义等。4.1.1数据类型的定义这部分的修改是和所用的编译器相关的,不同的编译器会使用不同的字节长度来表示同一数据类型。C/OS-II不使用C语言中的short、int、long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。代之以移植性强的整数数据类型,这样既直观又可移植,不过这就成了必须移植的代码。根据ADS编译器的特性,这些代码如下程序清单所示(与编译有关)。具体定义代码如下:typedefunsigned charBOOLEANtypedefunsigned charINT8Utypedefsigned charINT8Stypedefunsigned shortINT16Utypedefsigned shortINT16Stypedefunsigned intINT32Utypedefsigned intINT32StypedeffloatFP32typedefdoubleFP64typedefint32uOS_STK图3数据类型的定义代码4.1.2堆栈的定义寄存器在任务切换时将会保存在当前运行任务的堆栈中,所以堆栈单位(即数据类型 OS_STK)应该是和处理器的寄存器长度一致的。堆栈也是和编译器有关的,当进行函数调用时,入口参数和返回地址都会保存在当前任务的堆栈中,编译器的编译选项和由此生成的堆栈指令决定堆栈的增长方向。在C/OS-中, 用OS_STK_GROWTH 来设置堆栈的增长方向, 其宏定义为:#define OS_STK_GROWTH 1; /* 堆栈从高地址向低地址增长*/#define OS_STK_GROWTH 0; /* 堆栈从低地址向高地址增长*/4.1.3中断与临界区代码C/OS-和其它所有的实时内核一样,在访问操作系统的临界区之前必须关闭中断,访问之后开中断。这可以保证C/OS-的临界区代码不会被多个任务或中断服务程序同时访问,避免造成共享数据(C/OS-的全局变量)的不一致性。对于不同的处理器和编译器,实现开、关中断的方法可能不一样。所以为了方便移植,C/OS-提供了两个宏定义:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),用这两个宏定义屏蔽开, 关中断的不同实现。相关宏定义如下:#define OS_TASK_SW() OSCtxSw() /*任务切换*/#define OS_EXIT_CRITICAL() ARMDisabIeInt() /*关闭中断*/#define OS_ENTER_CRITICAL() ARMEnableInt() /*开启中断*/OS_TASK_SW()函数用来实现任务切换。C/OS-会调用 OSCtxSw()函数实现任务切换。OSCtxSw()需要对寄存器进行操作,加上考虑到效率的因素,OSCtxSw()用 ARM 汇编来实现。具体实现过程将在OS_CPU_A. ASM中详细讲述。OS_ENTER_CRITICAL()和 OS_EXIT_CRITICAL() 采用汇编来实现禁止和允许中断,具体实现为 ARMDisableInt()和 ARMEnableInt()。在C/OS-移植过程中很关键的一个问题就是OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL ()这一对宏定义如何实现的问题。最简单的方法是仅用关中断指令实现宏OS_ENTER_CRITICAL() ,仅用开中断指令实现宏OS_EXIT_CRITICAL()。用以下的汇编子程序完成ARMDisableInt()函数来实现关中断:STMFD SP!,R0,LR /R0,LR入栈MRS R0,CPSR /CPSR-R0需要修改R0ORR R0,R0,#0XC0 /修改CPSR的运行IRQ位和FIQ位SWI UpdateCPSR /使修改生效LDMFD SP!,RO,PC 图4程序状态寄存器组成图注意子程序中改变中断状态的方法,这里用了一条软件中断指令。因为,当程序运行在用户模式时,不能用MSR指令来改变CPSR的内容,所以,必须用一条软件中断指令进入管理模式来改变中断状态。软件中断服务程序如下:UpdateCPSRMSR SPSR_cxsf,R0MOVS PC,LR其中,寄存器R0用于传递参数,包含新的CPSR。这里是利用在管理模式下改变其SPSR(软件中断前用户模式下的CPSR)的值达到改变用户模式下CPSR的目的。指令MOVS PC,R14在将返回地址赋给PC时, 同时也将管理模式下的SPSR值赋给用户模式的CPSR。用类似的方法可以实现开中断,而且中断状态的改变也必须用软件中断实现。这种方法可以减少中断延迟时间,但它可能存在一点小问题,就是如果程序在调用OS_ENTER_CRITICAL() 之前,中断已经被禁止,那么在调用OS_EXIT_CRITICAL () 之后,中断被允许,这可能不是程序所期望的。因此这种简单的实现方法对某些情况不适用。OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL ()的具体实现要根据原来的中断禁止/允许的状态来决定的。对原方案的改进是在退出临界区的时候会恢复进入之前的状态,使用堆栈保存状态和恢复状态。具体的方法是在实现宏OS_ENTER_CRITICAL() 的时候,先将当前程序的中断状态保存到堆栈, 然后关中断,而宏OS_EXIT_CRITICAL ()的实现只需将堆栈中的中断状态恢复。这样,就不会破坏程序原来的中断状态,但是这种实现会增加中断的延迟时间。4.1.4使用软中断SWI作底层接口C/OS-II运行时,处理器可能处于的模式如下图所示:图5处理器可能处于的模式为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数位置,在移植中使用软中断指令SWI作为底层接口,使用不同的功能号区分不同的函数。软中断功能号分配如下表所示,未列出的为保留功能。功能号接口函数简介0x00void OS_TASK_SW(void)任务级任务切换函数0x01void OSStartHighRdy(void)运行优先级最高的任务,由OSStartHighRdy产生0x02void OS_ENTER_CRITICAL(void)关中断0x03void OS_EXIT_CRITICAL(void)开中断0x80void ChangeToSYSMode(void)任务切换到系统模式0x81void ChangeToUSRMode(void)任务切换到用户模式0x82void TaskIsARM(INT8U prio)任务代码是ARM代码0x83void TaskIsTHUMB(INT8U prio)任务代码是THUMB代码图6软中断功能号分配用软中断作为操作系统的底层接口就需要在C语言中使用SWI(SoftWare Interrupt)指令。在ADS中,有一个关键字_swi,用它声明一个不存在的函数,则调用这个函数就在调用这个函数的地方插入一条SWI指令,并且可以指定功能号。同时,这个函数也可以有参数和返回值,其传递规则与一般函数相同。 4.2 OS_CPU_C.C的移植在此文件中, 要求我们必须编写10 个简单的C 函数。OStaskStkInit(); /*任务堆栈初始化函数*/OStaskCreateHook (); /*任务建立接口函数 */OStaskDelHook (); /*任务删除接口函数*/OStaskSwHook (); /*任务切换接口函数*/OStaskIdleHook (); /*空闲任务接口函数*/OStaskStatHook (); /*统计任务接口函数*/OSTimeTickHook (); /*时钟节拍接口函数*/OStaskHookBegin (); /*系统初始化开始接口函数*/OStaskHookEnd (); /*系统初始化结束接口函数*/OSTCBInitHook (); /*控制块初始化接口函数*/唯一必要的函数是OsTaskStkInt()函数。其他9 个函数必须声明, 但可以不包含任何代码。4.2.1 OSTaskStkInit( )该函数用于初始化任务堆栈,使任务的堆栈看起来就像刚发生中断一样。即任务被执行时,就像从中断返回一样。在编写此函数之前,必须先确定任务的堆栈结构。而任务的堆栈结构是与CPU的体系结构、编译器有密切的关联。本移植的堆栈结构如下图所示。 任务入栈的其他数据PCLRR12R11R10R9R8.R2R1R0OSEnterSum空闲空间 栈底 任务环境开始 SP图7 移植的堆栈结构其示意代码为:OS_STK * OSTaskStkInit(void (*task)(void *pd ),void *pdata,OS_STK *ptos,INT16U opt);模拟带参数(pdata)的函数调用;模拟ISR向量;按照预先设计的寄存器值初始化堆栈结构;返回栈顶指针给调用该函数的函数;执行OSTaskCreate ( )时,会调用OSTaskStkInit ( )的初始化过程,然后通过OSTCBInit ( )函数调用,将返回的SP指针保存到该任务的TCB 块中。初始状态的堆栈是模拟了一次中断后的堆栈结构,使建立好的进入就绪任务的堆栈与系统发生中断、并且将环境变量保存完毕时的设置与堆栈结构一致。因为任务创建后并不是直接就获得执行,而是通过OSSched ( )函数进行调度分配,当满足执行条件后才能获得执行。为了使调度简单一致,就预先将该任务的PC指针和返回地址LR都指向函数入口,以便被调度时从堆栈中恢复到刚开始运行时的CPU现场。4.2.2 Hook( )函数在Os_cpu_c.c文件中还有许多Hook()函数,它们在某个特定的系统动作时被调用,允许执行函数中的用户代码。这些函数默认是空函数,用户根据实际情况添加相关代码。它们分别如下表所示:函数名被执行条件OSInitHookBehin()在开始执行OSInit()函数时被执行OSInitHookEnd()在OSInit()函数结束时被执行OSTaskCreateHook()在任务建立时被调用OSTaskDelHook()在任务删除时被调用OSTaskSwHook()在进行任务切换时被调用OSTaskStatHook()被统计任务调用,每秒执行一次OSTCBInitHook()在建立所有的TCB后,由OSTCBInit函数调用OSTimeTickHook()每个时钟节拍产生后被调用OSTaskIdleHook()由空闲任务调用图8 Hook()函数的调用OSTaskCreateHook()在C/OS中没有,在由C/OS 向C/OS-II升级时,定义一个空函数就可以了。注意其中的赋值语句,如果不把Ptcb赋给Ptcb,有些编译器会产生一个警告错误,说定义的Ptcb变量没有用到。OSTaskCreateHook()#if OS_CPU_HOOKS_ENOSTaskCreateHook(OS_TCB *ptcb) ptcb = ptcb; /防止编译时出现警告 #endif用户还应该使用条件编译管理指令来处理这个函数。只有在OS_CFG.H文件中将OS_CPU_HOOKS _EN设为1时,OSTaskCreateHook()的代码才会生成。这样做的好处是允许用户移植时可在不同文件中定义钩子函数。void OSTaskDelHook ()与void OSTaskCreateHook ()的定义类似。4.3 OS_CPU_A.ASM的移植为了方便移植,大部分的 C/OS-代码是用 C 语言写的,但仍需要用 C 和汇编语言写一些与处理器相关的代码,这是因为C/OS-在读写处理器寄存器时只能通过汇编语言来实现。这部分代码都放在了OS_CPU_A.ASM文件中。在此文件中需改写4 个简单汇编语言函数。(1)OSStartHighRdy()函数(2)OSCtxSw( )函数(3)OSIntCtxSw()函数(4)OSTickISR()函数4.3.1 OSStartHighRdy()函数操作系统初始化后,开始执行系统内第一个最高优先级的任务。对于第一个执行的任务,不需要进行上下文保存,只需恢复任务上下文即可。第一个任务的执行是通过调用汇编子程序OSStartHighRdy 实现的。此子程序首先调用钩子函数OSTaskSwHook(),完成用户扩展的操作系统功能,然后将OSRunnig 的值置为真,表示开始任务的执行,从而保证任务切换操作的正确执行。紧接着从具有最高优先级的任务控制块中取得任务的堆栈指针,初始化堆栈指针寄存器SP 。然后恢复CPSR,恢复其它的寄存器,开始执行最高的优先级的任务。注意,这里CPRS的恢复也必须用前面所述的软件中断来实现,以保证有效性。具体代码如下:、LDR r4,addr_OSTCBCur; /*得到当前任务的 TCB 地址*/LDR r5,addr_OSTCBHighRdy; /*得到高优先级任务的 TCB 地址*/LDR r5,r5; /*得到堆栈指针*/LDR sp,r5; /*切换到新的堆栈*/STR r5,r4; /*设置新的当前任务的 TCB 地址*/LDMFD sp!,r4;MSR CPSR_cxsf,r4;LDMFD sp!, r4 ; /*从栈顶得到新的声明 */MSR CPSR_cxsf, r4 LDMFD sp!,r0-r12,lr,pc; /*开始新的任务*/END4.3.2 OSCtxSw( )函数任务级的上下文切换,当任务因为被阻塞而主动请求CPU调度时被执行,由于此时的任务切换在非异常模式下进行,因此区别于中断级别的任务切换。它的工作是先将当前任务的CPU现场保存到该任务堆栈中,然后获得最高优先级任务的堆栈指针,从该堆栈中恢复此任务的CPU现场,使之继续执行。这样就完成了一次任务切换任务级上下文切换是由汇编子程序OSCtxSw()实现。它是由操作系统的任务调度函数OSSched()调用,所有的操作都在用户模式下完成(除了使用软件中断进入管理模式改变CPSR)在整个过程中中断是关闭的,因为在上下文切换过程中要访问操作系统的全局变量。OSCtxSw()函数是一个任务级的任务切换函数。软中断向量指向此函数。在C/OS-中, 如果任务调用了某个函数, 而该函数的执行结果可能造成系统任务的重新调度, 则在函数的末尾会调用OSSched(),OSSched()查找当前就绪最高优先级的任务, 如果不是当前任务, 则找该任务的TCB 地址, 并复制到变量OSTcbHighRdy()中, 然后通过宏OS_TASK_SW( ) 执行软中断调用OSCtxSw()进行任务切换。变量OSTCBCur 始终包含指向当前运行任务TCB的指针。具体代码如下:STMFD sp!, lr ; 保存PC 指针 STMFD sp!, lr ; 保存lr 指针 STMFD sp!, r0-r12 ;保存寄存器文件和ret 地址 MRS r4, CPSR STMFD sp!, r4 ; 保存当前PSR MRS r4, SPSR STMFD sp!, r4 LDR r4, addr_OSPrioCur LDR r5, addr_OSPrioHighRdy LDRB r6, r5 STRB r6, r4 ; 得到当前任务的TCB 地址 LDR r4, addr_OSTCBCur LDR r5, r4 STR sp, r5 ; 保存栈指针在占先任务的TCB 上 ,取得高优先级任务的TCB 地址 LDR r6, addr_OSTCBHighRdy LDR r6, r6 LDR sp, r6 ;得到新任务的堆栈指针 OSTCBCur = OSTCBHighRdy STR r6, r4 ; 设置当前新任务的TCB 地址LDMFD sp!, r4 MSR SPSR_cxsf, r4 LDMFD sp!, r4 MSR CPSR_cxsf, r4 LDMFD sp!, r0-r12, lr, pc 4.3.3 OSIntCtxSw()函数ARM处理器在跳到中断服务程序时,自动关闭IRQ中断。为保证IRQ中断的可重入性,即一个IRQ中断程序能被另一个IRQ中断,需要使用ARM提供的系统模式。因此中断服务程序需要运行在系统模式下。为了能够跟踪中断服务程序,操作系统提供了两个函数,一个是OSIntEnter(),在开始运行实际的中断服务之前调用;另一个是OSIntExit(),在退出中断服务时调用。由于中断服务程序可能会激活一个更高优先级的任务,所以,OSIntExit()对就绪任务队列进行检查,如果有更高优先级的任务且任务调度允许,则调用中断级的上下文切换例程,保存被中断的任务,运行高优先级的任务。OSIntCtxSw()过程用于实现中断级的上下文切换,它由OSIntExit()调用。OSIntCtxSw()的主要功能是将被中断的任务的执行环境保存到其堆栈中,而被中断的任务堆栈指针的保存、高优先级任务执行环境的恢复与执行,由例程CmnCtxSw()完成。因此,实现OSIntCtxSw()的关键在于如何收集被中断任务的上下文。首先必须清楚,从中断发生到中断级上下文切换的过程中,例程的调用关系和处理器模式的变化情况。如图所示: 图9 调用关系和处理器模式的变化情况从上图可知,被中断任务的返回地址PC、通用寄存器R0-R12以及程序状态寄存器CPSR被保存在IRQ堆栈中,而连接寄存器LR_usr被保存在系统模式的堆栈中(实际上就是被中断任务的堆栈中)。由于中断级的任务切换发生在系统模式,为了访问IRQ堆栈,必须把处理器状态改变到IRQ模式并禁止中断,获取IRQ堆栈指针,将其保存到通用寄存器,然后回到系统模式并禁止中断。这样,在系统模式下可以访问到被中断任务的返回地址、R0-R12的值以及CPRS的值,而且LR_usr的值也已被保存在系统模式的堆栈中。从而,在系统模式下完成了被中断任务执行环境的保存。具体代码如下:STMFD sp! ,lr; /* 保存PC 指针*/STMFD sp! ,r0- r12; /* 保存寄存器文件和RET 地址*/STMFD sp! ,r4; /* 保存当前PSR*/LDR r4,addr_OSTCBCur; /* 得到当前任务的TCB 地址*/ STR sp,r5; /* 保存栈指针在占先任务的TCB 上*/LDR r6,addr_OSTCBHighRdy;/* 取得高优先级任务 的TCB 地址*/LDR sp,r6; /* 得到新任务的堆栈指针*/LDMFD sp,r4 ; /* 设置当前新任务的TCB 地址*/4.3.4 OSTickISR()函数当时钟中断(IRQ)到来时,处理器跳转到时钟中断服务程序,时钟中断服务程序主要调用函数OSTimeTick(),这个函数处理与系统时钟相关的工作,如将每个任务的等待时间减1、更新系统时间等等。时钟中断服务程序由汇编子程序OSTickISR()实现。因为OSTickISR()的具体实现与中断级上下文切换的实现有很大的关系,所以对其具体的实现步骤进行较详细的分析:1)它首先保存被中断程序的上下文环境。将被中断程序的返回地址、通用寄存器以及程序状态寄存器保存到IRQ堆栈中,此时,IRQ堆栈中的内容如图所示(堆栈指针寄存器指向内容为CPSR的堆栈单元)。IRQ堆栈中保存的寄存器内容非常重要,因为它影响中断级上下文切换的实现。在保存被中断任务执行环境的时候,中断级上下文切换必须从IRQ堆栈中读取相关的寄存器内容。IRQ 堆栈的内容如下图: 图10 IRQ堆栈的内容2)执行标识中断结束的指令。这是通过向AIC(高级中断控制器)的中断结束命令寄存器写一个任意数实现的。3)切换到系统模式并允许IRQ和FIQ中断。为了允许中断的嵌套,在开始中断服务以前,必须进入系统模式。因为如果在IRQ模式下允许中断嵌套,那么,当下一个IRQ中断发生的时候,就会破坏当前中断的执行环境。4)保存系统模式下相关的寄存器。主要是连接寄存器LR_usr(),因为系统模式和用户模式共用寄存器组,该操作实际上是把LR_usr()保存到了用户模式的堆栈中(被中断任务的堆栈中),这个寄存器的内容在中断级任务切换的时候要用到,所以必须保存。5)在调用OSTimeTick()函数之前,先调用操作系统提供的OSIntEnter()函数,以使操作系统对中断程序进行跟踪。调用OSTimeTick()之后,再调用函数OSIntExit(),通知操作系统中断完成。如果就绪队列中有更高优先级的任务且允许任务调度,OSIntExit()则进行中断级任务切换(在后面论述)。如果没有更高优先级的任务,则恢复系统模式下保存的寄存器,并切换到IRQ模式且禁止中断,恢复被中断任务的上下文环境,重新执行被中断的任务具体代码如下:STMDB SP!,r0-r11,lr MRS R0, CPSR ORR R0, R0, #0x80 ; 设置中断禁止标 MRS CPSR_cxsf, r0 ;中断结束 LDR R0, =I_ISPC LDR R1, =BIT_TIMER0 STR R1, R0 BL IrqStart BL OSTimeTick BL IrqFinish LDR R0, =need_to_swap_context LDR R2, R0 CMP R2, #1 LDREQ PC, =_CON_SW 通过前面的分析,我们可以画出下面这张结构图:图11 中断服务程序流程图完成上述工作后, C/OS-的就移植代码编写完毕,但是否可以正常运行还需要进行系统初始化、移植测试,以保证其在S3C2440板上可以正常运行。5.嵌入式系统的初始化5.1初始化程序的下载执行1)通过编程器将可执行目标文件烧写到BootROM(ROM、EPROM、FLASH)等;2)通过串行口和网口下载执行目标文件,要求宿主机系统上有数据传输工具程序、目标机装载器、嵌入式监视器或目标机系统上的调试代理。3)通过JTAG或BDM接口下载;5.2嵌入式系统的初始化过程 图12 嵌入式系统初始化过程5.2.1硬件初始化阶段 图13 硬件初始化阶段1、复位向量ENTRY b ResetHandler ;for debug b HandlerUndef ;handlerUndef b HandlerSWI ;SWI interrupt handler b HandlerPabort ;handlerPAbort b HandlerDabort ;handlerDAbort b . ;handlerReserved b HandlerIRQb HandlerFIQ2、最小硬件初始化1)设置适当的寄存器,使嵌入式处理器处于一个已知的状态:获得CPU的类型;获得或设置CPU的时钟频率。2)禁止中断和高速缓存3)初始化内存控制器、内存芯片和高速缓存单元,包括:得到内
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学生写字课件图片
- 2024年浙江省平阳县移动公司公开招聘工作人员试题带答案详解
- 2024年云南省华坪县烟草公开招聘工作人员试题带答案详解
- 2024年四川省仁寿县烟草公开招聘工作人员试题带答案详解
- 2024年陕西省府谷县烟草公开招聘工作人员试题带答案详解
- 2024年宁夏海原县烟草公开招聘工作人员试题带答案详解
- 2024年河南省南召县移动公司公开招聘工作人员试题带答案详解
- 小学生做客礼仪课件
- 真丝绒毯原料行业深度研究分析报告(2024-2030版)
- 中国芳香保健竹窗帘行业市场发展前景及发展趋势与投资战略研究报告(2024-2030)
- 固定资产报废申请表(样本)
- 八年级物理光学测试题含答案试题
- Unit1Myclassroom单元整体设计(学历案)四年级英语上册教学评一致性资源(人教PEP版)
- 皮带机使用说明书
- 住宅小区消防、排烟通风工程招标文件
- 四川省中小流域暴雨洪水计算表格(尾矿库洪水计算)
- 福建省危险性较大的分部分项工程安全管理标准
- 教学常规工作手册
- 学习解读2023年水行政处罚实施办法课件
- 建筑节能与绿色建筑监理细则
- 新编建筑施工扣件式钢管脚手架安全技术规范
评论
0/150
提交评论