ucos-II在Atmega128上的移植.doc_第1页
ucos-II在Atmega128上的移植.doc_第2页
ucos-II在Atmega128上的移植.doc_第3页
ucos-II在Atmega128上的移植.doc_第4页
ucos-II在Atmega128上的移植.doc_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

安徽大学本科毕业论文(设计)题目:C/OS-II在ATmega128中的移植 与测试方法研究 学生姓名: 学号: 院(系): 电子科学与技术学院 专业:电气工程及其自动化 入学时间: 二零零六 年 九 月导师姓名: 职称/学位: 讲师/硕士 导师所在单位: 安徽大学电子科学与技术学院电气工程系 C/OS-II在ATmega128中的移植与测试方法研究摘 要本论文主要探讨了C/OS-II在mega128上的移植与测试。文中首先简单介绍了国内外的嵌入式系统设计开发的现状,探讨了在项目设计中使用嵌入式实时操作系统的意义。然后重点介绍C/OS-II的内核结构、整体的组织架构以及各个模块的功能等,还对ATmega128的架构特点、存储器组织、中断管理等做了详细的介绍。然后讨论了在具体的移植过程中所做的工作,主要包括编写与处理器密切相关的三个函数、相关的集成开发环境、硬件平台设计以及测试方法的研究。最后展望了C/OS-II等实时内核在未来的嵌入式系统开发中的应用前景,以及在以后的学习工作中还要继续某些方面作深入的研究。关键词:C/OS-II;硬实时内核;ATmega128;移植;测试Research of the Transplantation and Test Methods about C / OS-II in ATmega128 AbstractThis article primarily discusses transplantation and the test methods about C/OS-II in ATmega128. The article first provides a brief introduction to the State-of-the-art embedded system design and development of the situation, in the design of the significance of the operating system. And then focuses on ATmega128 and the real-time kernel structure, overall organizational structure and functions of each module, also on the characteristics of the schema ATmega128, storage, organization, interrupt management do detail. And then discusses the migration process in the work to be done, including key uses the Assembly to write and processors that are closely related to the three functions, related to use of the integrated development environment, and test methods. Last look C/OS-II and other real-time kernel in the future of embedded system development prospects. Keywords: C/OS-II; hard real-time kernel ; ATmega128; transplant ; test目录第一章 前言1.1 嵌入式系统的介绍11.2 国内嵌入式系统发展的现状31.3 本课题研究内容和意义3第二章 C/OS-II和ATmega128的架构分析42.1 C/OS-II介绍42.1.1 关于C/OS-II42.1.2 C/OS-II的总体架构分析62.1.3 C/OS-II的内核结构72.2 ATmega128介绍102.2.1 关于ATmega128102.2.2 ATmega128的内核特点112.2.3 ATmega128的片内外设15第三章 移植分析163.1 移植的总体分析163.2 移植平台的搭建173.3 与移植相关的源文件编写173.3.1 基于ATmega128的OS_CPU.H源文件:183.3.2 基于ATmega128的OS_CPU_C.C源文件:193.3.3 基于ATmega128的OS_CPU_A.S源文件:23第四章 硬件平台设计与代码测试分析314.1硬件平台设计314.2 代码测试314.2.1 代码测试概述314.2.2 验证移植代码32第五章 总结与展望385.1 心得体会385.2 不足与改进395.3 展望40参考文献:42致谢43C/OS-II在ATmega128中的移植与测试方法究第一章 前言1.1嵌入式系统的介绍嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户应用程序等部分组成,用于实现对其他设备的控制、监视或管理等功能。嵌入式系统一般指非PC系统,它包括硬件和软件两部分。硬件包括处理器/微处理器、存储器及外设器件和I/O端口、图形控制器等。软件部分包括操作系统软件(OS)和应用程序编程。有时设计人员把这两种软件组合在一起。应用程序控制着系统的运作和行为;而操作系统控制着应用程序编程与硬件的交互作用。嵌入式产品已经在航空航天、交通、电子、医疗仪器、通信、工控、金融、家电等行业得到广泛应用。嵌入式系统的特点:嵌入式系统的核心是嵌入式微处理器。嵌入式微处理器一般具备以下特点:(1)对实时多任务有很强的支持能力,能完成多任务并且有较短的中断响应时间,从而使内部的代码和实时内核的执行时间减少到最低限度;(2)具有功能很强的存储区保护功能。这是由于嵌入式系统的软件结构已模块化,而为了避免在软件模块之间出现错误的交叉作用,需要设计强大的存储区保护功能,同时也有利于软件诊断;(3)可扩展的处理器结构,以便最迅速地开发出满足应用的最高性能的嵌入式微处理器;(4)嵌入式微处理器必须功耗很低,尤其是用于便携式的无线及移动的计算和通信设备。嵌入式系统有很长的历史,事实上,在很早以前,嵌入式这个概念就已经存在了。在通信方面,嵌入式系统在20世纪60年代就用于对电子机械电话交换的控制,当时被称为“存储式程序控制系统”(Stored Program Control)。嵌入式计算机的真正发展是在微处理器问世之后。1971年11月,Intel公司成功地把算术运算器和控制器电路集成在一起,推出了第一款微处理器Intel 4004,其后各厂家陆续推出了许多8位、16位的微处理器,包括Intel 8080/8085、8086,Motorola 的6800、68000,以及Zilog的Z80、Z8000等。1976年Intel公司推出Multibus,1983年扩展为带宽达40MB/s的Multibus。20世纪80年代可以说是各种总线层出不穷、群雄并起的时代。20世纪90年代,在分布控制、柔性制造、数字化通信和信息家电等巨大需求的牵引下,嵌入式系统进一步加速发展。面向实时信号处理算法的DSP产品向着高速、高精度、低功耗发展。TI推出的第三代DSP芯片TMS320C30,引导着微控制器向32位高速智能化发展。在应用方面,发展也较为迅速。21世纪无疑是一个网络的时代,将嵌入式系统应用到各类网络中也必然是嵌入式系统发展的重要方向。嵌入式系统在各个领域应用的发展潜力巨大,其在医疗仪器领域的应用也越来越广泛。1.2国内嵌入式系统发展的现状中国单片机二十年论坛总结出,我国嵌入式起步较早,但总体来说发展缓慢,和国外的开发应用具有很大的差距,造成这一局面的原因是多方面的。在国内嵌入式系统开发方面,多是一些低层次的应用,停留在以前老的技术基础之上。例如,经典51系列单片机在上世纪我国的工业信息化改造过程中发挥了重要的作用,渗透到生产生活的各个方面。与此同时在大学电类相关的工科单片机教学中,依然是经典的51,微机原理依然是8086/88,这显然体现不了最新的技术特征,造成了大学教育与实际社会需要的脱节。国外的大部分高校和国内的极少数大学相继开设嵌入式微处理器设计等相关的前沿性的课程,可见EDA技术将是未来硬件开发方式的主流方向,所以我们不能继续在过时的技术上浪费时间了。同时我国广大硬件开发人员计算机软件的技术层次太低,传统的硬件的工程人员几乎不太了解嵌入式操作系统,只能在“裸系统”上开发低层次的应用,没能够充分利用计算机技术,进行二次开发。而计算机专业的工程师虽然在操作系统上比他们有更深刻的理解,但是计算机专业开的操作系统与嵌入式实时操作系统又有很大的不同。所以软件层次上的知识缺乏对我国的嵌入式系统的发展造成了非常大障碍。1.3 本课题研究内容和意义本论文研究的内容是C/OS-II在ATmega128上的移植。文中详细介绍了C/OS-II和ATmega128的内核结构,以及对ATmega128硬件开发板的介绍(用来测试C/OS-II)。给出了移植中要修改的三个源文件的代码,并做了注释,还给出了测试移植代码的方法和测试结果。ATmega128是美国ATMEL公司最新的推出的8位RISC单片机,片内资源丰富,指令执行效率高,拥有软件自动升级等功能,总体性能在8位单片机中非常出色。ATmega128在电力电子等众多领域中,有着非常广泛的应用。C/OS-II是一个非常优秀的嵌入式操作系统,开放源代码,实时性能好,可以用于与人性命攸关、安全性条件极为苛刻的系统。故能在嵌入式开发中,嵌入C/OS-II实时操作系统将对系统的实时性、安全性等性能有极大的提高,同时还可以简化应用程序的开发难度,缩短开发周期,对项目的开发具有重大的意义。可以看出本论文的选题充分体现了嵌入式发展的主流方向,具有重大理论意义和应用价值。第二章 C/OS-II和ATmega128的架构分析2.1 C/OS-II介绍2.1.1 关于C/OS-II C/OS-II是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统。C/OS-II的前身是C/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在嵌入式系统编程杂志的5 月和6 月刊上刊登的文章连载,并把C/OS-II的源码发布在该杂志的B B S 上。C/OS和C/OS-II是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将C/OS-II嵌人到开发的产品中。C/OS-II具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。C/OS-II已经移植到了几乎所有知名的CPU 上。严格地说C/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于C/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。C/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。2.1.2 C/OS-II的总体架构分析图1 C/OS-II的整体架构C/OS-II的总体架构如上图所示。C/OS-II最核心的是放在source文件中的十一个源文件,这部分构成了C/OS-II内核的整个架构。在具体应用中,应首先把C/OS-II移植到项目所用的硬件平台上,与此相关的三个源文件见上图,这三个握手文件是使用C/OS-II嵌入式实时操作系统必不可少的,与处理器密切相关的、实时性要求很高的几个函数一定要由汇编语言编写,这部分工作是整个项目软件实现的基础部分。关于移植的具体过程见下章分析。C/OS-II的配置文件是由具体应用决定的,C/OS-II是可裁剪的内核,它本身拥有很丰富的功能,根据需要裁剪一些用不到的功能,如互斥信号量、消息队列等。这样做可以使实时内核的可以变得很小,可以达到几KB,这非常有利于满足嵌入式应用中存储空间有限的要求,同时有利于提高实时性、可靠性。建立了良好的软硬件平台之后,应用软件的编写将是一件相对容易实现的工作,可以把整个功能分解成多个任务,由C/OS-II来协调多任务协同工作。与传统的没有操作系统支持的系统相比,这样做拥有极大地优势,首先可以简化软件开发的难度,同时提高整个系统运行的效率,完全可以满足对实时性、可靠性的要求。有以上分析可知,C/OS-II的整体架构是完美的,容易理解的。方便起见,我们可以在具体的应用中,建立四个文件分别对上述的四部分:APP目录存放应用程序代码、AVR目录存放于ATmega128相关的三个握手文件、CONFIG目录存放配置文件和总的INCLUDE文件、SOUCRE目录存放C/OS-II的十一个内核文件。当然上述的存放格式在具体的应用中是可以灵活使用的。2.1.3 C/OS-II的内核结构C/OS-II的内核架构最核心的就是任务的调度,这也是所有操作系统最核心的,理解C/OS-II的任务调度器的工作原理,将是掌握C/OS-II的最关键的一步。下面就C/OS-II的调度器的工作原理做一个具体的介绍。首先声明,在全面学习C/OS-II之前,最好要有操作系统和数据结构的知识,这对于看懂C/OS-II的源码很重要,因为C/OS-II大部分内容都是对某些数据结构的操作。先来大体上看一下,C/OS-II是如何实现多任务切换。移植C/OS-II要对硬件一定的要求,要有定时器等,这当然不是问题,因为现在绝大多数的微处理器都至少有一个八位定时/计数器。我们知道,多任务操作系统的最大本质就是实现:对于每一个任务而言,微处理器都是面对自己的一个任务的。所以操作系统要做的就是按照某种机制不停切换任务的执行环境,也就是不停地保存某一个任务的PC、SP、PSW和寄存器组,又不停的恢复另外任务的PC、SP、PSW和寄存器组,C/OS-II也是如此。C/OS-II是由一个定时器提供一个周期性的中断(大概是10-100Hz),在中断服务程序中完成的任务执行环境的中断级切换。下面针对ATmega28的详细描述一下具体的中断级任务切换过程:一个任务正在被执行,当时钟中断来临时,128首先把PC压入当前任务的堆栈中, SP减二,中断向量再被送入PC中,然后进入中断服务程序,在中断服务程序中,把当前任务的32个八位的通用寄存器组和PSW的内容压入堆栈中,最后再保存SP,这样就把当前任务的执行环境完全保存了下来。接下来中断服务程序查找任务就绪表中级别最高的任务的优先级,据此来恢复这个任务上次在任务切换中保存的内容,过程是把堆栈中的SP推入SP寄存器中,然后以现在的SP的内容来继续恢复堆栈中的其他内容,也就是按照上述保存一个任务执行环境的相反顺序来恢复PSW和32个通用寄存器组,最后执行中断程序返回指令RETI,把PC推入PC寄存器中,这样就实现了多任务的中断级切换。对于任务级切换的过程和中断级几乎一样,不同之处在于,保存当前任务的返回地址是由调用子程序而引起的,返回过程和中断级的一样。实际上在128上跑的C/OS-II的任务切换过程要比上述的切换过程复杂,还要考虑很多别的情况,比如只有在执行最外层的中断服务中才保存SP,在不是最外层的中断嵌套中是不允许切换的等。C/OS-II的内核是可裁剪的,裁剪是通过条件编译的方式实现的。在OS_CFG.H文件中完成相关的配置,例如当在应用中不需要消息邮箱,那就可以把OS_MBOX_EN通过宏定义置位0,那么所有的邮箱函数都将被屏蔽,若是想使用消息邮箱或是使用消息邮箱的部分功能可以将相应的宏定义定义为1。对于C/OS-II中其他的通信和同步方式以及可以使用同样的手段完成相应的配置,这对于非常适合于嵌入式应用的特点,可以对编译后的软件规模进行有效地控制。C/OS-II虽然是一个短小精悍的实时内核,但是它的规模依然可观,所以很难在一篇文章中进行非常详细的讲解。以上已对C/OS-II的任务切换进行了本质的阐述,如想深入的全面的理解C/OS-II可以参考邵贝贝译的原著等,上面有非常深入的分析。2.2 ATmega128介绍2.2.1 关于ATmega128ATmega128是美国ATMEL公司最新的推出的8位RISC结构低功耗CMOS微控制器,也是ATMEL公司推出的8位系列单片机中配置最高的一款,片内资源非常丰富,集成了128KB的系统内可编程Flash、4KB的EEPROM、4KB的SRAM。ATmega128拥有丰富的指令集,指令执行效率高,比普通的复杂指令集微处理器高10倍的数据吞吐率,达到1MIPS/MHz。拥有软件自动升级,软件加密等功能,体现了微控制器设计的最新理念。总体性能在几乎所有的8位单片机中非常出色,在电力电子等众多领域中,有着非常广泛的应用。2.2.2 ATmega128的内核特点图2 AVR内核结构方框图如上图我们可以看出:微控制器ATmega128的MCU包括一个算术逻辑单元(ALU),一个状态寄存器(SREG),一个通用工作寄存器组和一个堆栈指针。状态寄存器(SREG)的最高位I是全局中断允许位。如果全局中断允许位为零,则所有中断都被禁止。当系统响应一个中断后,I位将由硬件自动清“0”;当执行中断返回(RETI)指令时,I位由硬件自动置“1”,从而允许系统再次响应下一个中断请求。 通用工作寄存器组是由32个8位的通用工作寄存器组成。其中R26R31这6个寄存器还可以两两合并为3个16位的间接地址寄存器。这些寄存器可以用来对数据存储空间进行间接寻址。这3个间接地址寄存器的名称为:X寄存器、Y寄存器、Z寄存器。其中Z寄存器还能用作对程序存储空间进行间接寻址的寄存器。堆栈指针(SP)是一个指示堆栈顶部地址的16位寄存器。AVR单片机上电复位后,SP指针的初始值为0x0000,由于AVR单片机的堆栈是向下生长的(从高地址向低地址生长),所以系统程序一开始必须对堆栈指针SP进行初始化,即将SP的值设为数据存储空间的最高地址。数据存储空间(仅内部)AVR单片机的数据存储器是线形的,从低地址到高地址依次是CPU寄存器区(32个通用寄存器),I/O寄存器区,数据存储区。如下图3所示:图3 数据存储映像ATmega128的中断响应机制 :ATmega128有34个不同的中断源,每个中断源和系统复位在程序存储空间都有一个独立的中断向量(中断入口地址)。每个中断源都有各自独立的中断允许控制位,当某个中断源的中断允许控制位为“1”且全局中断允许位I也为“1”时,系统才响应该中断。当系统响应一个中断请求后,会自动将全局中断允许位I清零,此时,后续中断响应被屏蔽。当系统执行中断返回指令RETI时,会将全局中断允许位I置“1”,以允许响应下一个中断。若用户想实现中断嵌套,必须在中断服务子程序中将全局中断允许位I置“1”。(这一点与8051系列的单片机不同)在中断向量表中,处于低地址的中断具有高的优先级。优先级高只是表明在多个中断同时发生的时候,系统先响应优先级高的中断,并不含有高优先级的中断能打断低优先级的中断处理工程的意思。这与8051系列单片机的中断优先级概念不同。 中断发生时,ATmega128按以下步骤顺序执行:A. 全局中断允许位I清零。B. 将指向下一条指令的PC值压入堆栈,同时堆栈指针SP减2。C. 选择最高优先级的中断向量装入PC,程序从此地址继续执行中断处理。D. 当执行中断处理时,中断源的中断允许控制位清零。中断结束后,执行RETI指令,此时A. 全局中断允许位I置“1”。B. PC从堆栈推出,程序从被中断的地方继续执行。特别要注意的是:AVR单片机在响应中断及从中断返回时,并不会对状态寄存器SREG和通用寄存器自动进行保存和恢复操作,因此,对状态寄存器SREG和通用寄存器的中断保护工作必须由用户来完成。 以上关于ATmega128的内核特点的介绍是从方便移植C/OS-II的角度来阐述的,当然对于程序员来讲,这些介绍已经够了。2.2.3 ATmega128的片内外设ATmega128具有丰富的片内外设,除了基本的两个具有独立的预分频器和比较器功能8位定时器/计数器和两个具有预分频器、比较功能和捕捉功能的16位的定时器/计数器以及看门狗外,还集成了其他的功能模块。JTAG 接口( 与IEEE 1149.1 标准兼容) 遵循JTAG 标准的边界扫描功能 支持扩展的片内调试 通过JTAG 接口实现对Flash, EEPROM, 熔丝位和锁定位的编程外设特点 具有独立预分频器的实时时钟计数器 两路8 位PWM 6路分辨率可编程(2 到16 位)的PWM 输出比较调制器 8路10 位ADC8 个单端通道7 个差分通道2 个具有可编程增益(1x, 10x, 或200x)的差分通道 面向字节的两线接口 两个可编程的串行USART 可工作于主机/ 从机模式的SPI 串行接口 具有独立片内振荡器的可编程看门狗定时器 片内模拟比较器特殊的处理器特点 上电复位以及可编程的掉电检测 片内经过标定的RC 振荡器 片内/ 片外中断源有上述分析可知,ATmega128的片内外设是完全可以满足一般的应用要求。第三章 移植分析3.1移植的总体分析 经过以上几章的讨论,即对ATmega128和C/OS-II的内核结构有了深入的认识之后,现在可以进行具体的移植过程分析了。所谓移植,就是使一个实时内核能在其它的微处理器或微控制器上运行。C/OS-II在设计之初就充分考虑了可移植性,所以该内核的大部分代码都是用C语言写的,但是在读写微控制器的寄存器时,只能通过汇编语言来实现。具体的移植过程相对来说不是很困难,关键是前期的准备工作要做充分,即要对C/OS-II的大致工作原理有深刻的了解,还要对要移植的硬件平台有深入的认识。通常来说,向目标平台移植C/OS-II要满足以下条件:1. 处理器的C编译器能产生可重入型代码;2. 处理器支持中断,并且能产生定时中断(通常为10-100Hz);3. 用C语言可以开关中断;4. 处理器能支持一定数量的数据存储硬件堆栈(可能几千字节);5. 处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令;ATmega128以及移植用到的WINAVR是满足以上的条件的。参照图1,可以看出整个的移植工作就是编写与处理器相关的三个文件,总共大约需要些二百多行代码。 3.2移植平台的搭建在移植的工作中,我们需要:1. 通用的电脑平台:软件环境是Windows7(WindowsXP、2003、2000等都行),WinAVR-2009+AVRstudio4.17。WinAVR是GNU的在Windows平台下的交叉编译器,拥有编译代码的效率高、源码完全公开、软件体积小等优点,是一款非常优秀的集成开发环境。AVRstudio是ATMEL公司推出的针对AVR系列单片机的汇编语言的开发环境,拥有下载程序、在线调试等功能。2. ATmega128测试板:该测试板(包括仿真器)是专为测试C/OS-II代码而购买,具体的构成将在第四章的硬件平台实现中详细介绍。3.3 与移植相关的源文件编写由图1可知,与ATmega128具体硬件相关需要修改的的三个文件分别是:OS_CPU.H、OS_CPU_C.C、OS_CPU_A.S。3.3.1 基于ATmega128的OS_CPU.H源文件:/数据类型(与编译器相关)typedef unsigned char BOOLEAN;typedef unsigned char INT8U; typedef signed char INT8S; typedef unsigned int INT16U; typedef signed int INT16S; typedef unsigned long int INT32U; typedef signed long int INT32S;typedef unsigned char OS_STK; /堆栈入口的数据宽度typedef unsigned char OS_CPU_SR;/使用OS_CRITICAL_METHOD = 3时,用来声明CPU状态寄存器的数据类型#define OS_STK_GROWTH 1 /128的堆栈增长方向有高地址到低地址#define OS_TASK_SW() OSCtxSw()/与处理器有关的代码(进入临界段的三种方式,推荐方式3)#if OS_CRITICAL_METHOD = 1 /#define OS_ENTER_CRITICAL() _asm_ _volatile_ (cli :)#define OS_EXIT_CRITICAL() _asm_ _volatile_ (sei :)#endif#if OS_CRITICAL_METHOD = 2#define OS_ENTER_CRITICAL() _asm_ _volatile_ (in _tmp_reg_,_SREG_ cli push _tmp_reg_:)#define OS_EXIT_CRITICAL() _asm_ _volatile_ (pop _tmp_reg_ out _SREG_,_tmp_reg_:)#endif#if OS_CRITICAL_METHOD = 3#define OS_ENTER_CRITICAL() (cpu_sr = OS_CPU_SR_Save()#define OS_EXIT_CRITICAL() (OS_CPU_SR_Restore(cpu_sr) OS_CPU_SR OS_CPU_SR_Save(void);void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);#endif/在OS_CPU_A.S中的与方式3有关的汇编程序代码OS_CPU_SR_Save:IN R16,_SFR_IO_ADDR(SREG) CLI RET OS_CPU_SR_Restore: OUT _SFR_IO_ADDR(SREG),R16 3.3.2 基于ATmega128的OS_CPU_C.C源文件:总共有10个C函数,唯一必要的函数是OSTaskStkInit()。其他的九个函数必须声明,但并不必要包含任何代码,这些函数只是给用户提供一个扩展功能的机会。OSInitHookBegin ( );OSInitHookEnd ( );OSTaskCreateHook ( );OSTaskDelHook ( );OSTaskIdleHook ( );OSTaskStatHook ( );OSTaskSwHook ( );OSTCBInitHook ( );OSTimeTickHook ( );OSTaskStkInit ( );唯一必要的函数OSTaskStkInit()的源代码如下:OS_STK *OSTaskStkInit (void (*task)(void *pd),void *pdata, OS_STK *ptos,INT16U opt) OS_STK* stk; opt=opt;/*废物,防止编译器报警*/ stk=ptos;/*得到栈顶指针*/ *stk- = (INT8U)(INT16U)task)&0xFF); *stk- = (INT8U)(INT16U)task)8); *stk- = (INT8U)0x00;*stk- = (INT8U)0x01;*stk- = (INT8U)0x02;*stk- = (INT8U)0x03;*stk- = (INT8U)0x04;*stk- = (INT8U)0x05;*stk- = (INT8U)0x06;*stk- = (INT8U)0x07;*stk- = (INT8U)0x08;*stk- = (INT8U)0x09;*stk- = (INT8U)0x10; *stk- = (INT8U)0x11; *stk- = (INT8U)0x12; *stk- = (INT8U)0x13;*stk- = (INT8U)0x14;*stk- = (INT8U)0x15;*stk- = (INT8U)0x16;*stk- = (INT8U)0x17;*stk- = (INT8U)0x18; *stk- = (INT8U)0x19; *stk- = (INT8U)0x20;*stk- = (INT8U)0x21;*stk- = (INT8U)0x22;*stk- = (INT8U)0x23;*stk- = (INT8U)(INT16U)pdata)&0xFF);*stk- = (INT8U)(INT16U)pdata)8);*stk- = (INT8U)0x26;*stk- = (INT8U)0x27;*stk- = (INT8U)0x28;*stk- = (INT8U)0x29;*stk- = (INT8U)0x30;*stk- = (INT8U)0x31; *stk- = (INT8U)0x80; /使能中断 相当于保存状态字 return (OS_STK *)stk);图4说明了经过OSTaskStkInit()的初始化后任务堆栈的结构,与中断刚刚发生过的栈结构一样,另外要说明WINAVR编译器是用寄存器传递pdata参数,这与某些C编译器采用局部变量传递pdata的栈结构是不同的。图4 任务堆栈初始化结构3.3.3 基于ATmega128的OS_CPU_A.S源文件:在这个文件中有四个要用汇编语言编写的源文件分别介绍如下/宏定义 保存通用寄存器和状态寄存器.macroPUSHRS pushr0pushr1pushr2pushr3pushr4pushr5pushr6pushr7pushr8pushr9pushr10pushr11pushr12pushr13pushr14pushr15pushr16pushr17pushr18pushr19pushr20pushr21pushr22pushr23pushr24pushr25pushr26pushr27pushr28pushr29pushr30pushr31inr16,_SFR_IO_ADDR(SREG) pushr16;保存状态寄存器.endm/宏定义 逐次弹出通用寄存器和状态寄存器.macroPOPRSpopr16out_SFR_IO_ADDR(SREG),r16;弹出状态寄存器popr31popr30popr29popr28popr27popr26popr25popr24popr23popr22popr21popr20popr19popr18popr17popr16popr15popr14popr13popr12popr11popr10popr9popr8popr7popr6popr5popr4popr3popr2popr1popr0.endm/使已就绪的任务中优先级最高的任务开始运行OSStartHighRdy:#if OS_CPU_HOOKS_EN 0CALL OSTaskSwHook;调用用户定义的接口函数#endif LDS R16,OSRunningINC R16STS OSRunning,R16 ;记录中断嵌套层数LDS R30,OSTCBHighRdyLDS R31,OSTCBHighRdy+1 LD R28,Z+OUT _SFR_IO_ADDR(SPL),R28LD R29,Z+OUT _SFR_IO_ADDR(SPH),R29;弹出堆栈指针POPRS RET ;中断返回,弹出中断返回地址/任务级切换OSCtxSw:PUSHRS LDS R30,OSTCBCur LDS R31,OSTCBCur+1IN r28,_SFR_IO_ADDR(SPL)ST Z+,R28IN r29,_SFR_IO_ADDR(SPH)ST Z+,R29;保存堆栈指针到任务控制块#if OS_CPU_HOOKS_EN 0CALL OSTaskSwHook #endifLDS R16,OSPrioHighRdySTS OSPrioCur,R16;OSPrioCur = OSPrioHighRdyLDS R30,OSTCBHighRdy LDS R31,OSTCBHighRdy+1STS OSTCBCur,R30 STS OSTCBCur+1,R31 ;OSTCBCur = OSTCBHighRdyLD R28,Z+ OUT _SFR_IO_ADDR(SPL),R28LD R29,Z+ OUT _SFR_IO_ADDR(SPH),R29;弹出堆栈指针POPRS RETI ;中断返回,弹出中断返回地址/中断级任务切换函数OSIntCtxSw:#if OS_CPU_HOOKS_EN 0CALL OSTaskSwHook#endifLDS R16,OSPrioHighRdySTS OSPrioCur,R16;OSPrioCur = OSPrioHighRdyLDS R30,OSTCBHighRdyLDS R31,OSTCBHighRdy+1 ;OSTCBCur = OSTCBHighRdySTS OSTCBCur,R30 STS OSTCBCur+1,R31LD R28,Z+OUT _SFR_IO_ADDR(SPL),R28LD R29,Z+OUT _SFR_IO_ADDR(SPH),R29;弹出堆栈指针POPRSRET ;中断返回,弹出中断返回地址/时钟中断服务函数TIMER0_COMP_vect:OSTickISR:PUSHRS LDS R16,OSIntNesting INC R16STS OSIntNesting,R16CLZ CPI R16,1BREQ OSTickISR2SEI CALL OSTimeTick ;跟踪所有任务的定时器以及超时时限CALL OSIntExit;调用中断退出函数POPRS RET ;中断返回,弹出中断返回地址OSTickISR2:LDS R30,OSTCBCurLDS R31,OSTCBCur+1IN r28,_SFR_IO_ADDR(SPL)ST Z+,R28IN r29,_SFR_IO_ADDR(SPH)ST Z+,R29SEICALL OSTimeTickCALL OSIntExit POPRSRET ;中断返回,弹出中断返回地址第四章 硬件平台设计与代码测试分析4.1 硬件平台设计硬件平台设计的出发点主要是考虑能上操作系统,方便检验C/OS-II的各项功能,而且尽量简洁,原理图见下图。由图分析可知,平台提供了ISP和JTAG两种程序下载功能,而且JTAG还可用于在线调试功能。八只LED用来体现C/OS-II的多任务的处理能力。 图5 硬件平台原理图4.2 代码测试4.2.1代码测试概述在为ATmega128写好移植的代码后,下一步的工作就是为移植的代码进行测试,检查C/OS-II能否正常工作。测试C/OS-II主要是测试与处理器相关的三个源文件中的OSTaskStkInit()、OSStartHighRdy()、OSCtxSw(),OSIntCtxSw()、OSTickISR()等五个函数,而C/OS-II的内核的十一个源文件是不用测试的,这些源文件是经过官方测试通过的。测试移植代码不用加任何应用代码,也就是说测试内核自身的运行状况。这样做有两个原因:首先,是不希望将测试工作复杂化;其次,如果有些部分没有正常工作,可以明白是移植本身的问题,而不是应用代码产生的问题。如果已经将两个基本任务和节拍中断运行起来,那么接下来添加应用任务是非常简单的。另外说明一下,在添加应用任务前,建议采用线性测试的方法先对应用任务进行测试,即把一个个任务单独写成main函数的形式进行线性测试,这样比添加到C/OS-II中测试更方便,因为运行C/OS-II会不断进行任务切换,不方便观看任务执行的流程。测试移植代码的具体的步骤如下:l 确保WINAVR和AVRstudio正常工作;l 验证OSTaskStkInit()和OSStartHighRdy()函数;l 验证OSCtxSw()函数;l 验证OSIntCtxSw()和OSTickISR()函数; 测试的时候,先建立四个文件夹,即OSsrc存放内核的十一个源文件,Config存放总的头文件和配置文件,AVR存放移植的代码,TEST存放测试用的代码。这样组织文件而不采用集成环境开发的方式是为了拥有更大灵活性,这样也与以后的应用开发相一致,那么自然需要一个Makefile文件来组织进行编译链接工作。为了便于观察,采用在线仿真与在线下载相结合的方式。4.2.2 验证移植代码在验证上述的五个函数之前,写一个非常简单的TEST.C来验证编译器和Makefile是否能正常工作,看是否能正常编译出正确的代码,如遇到错误或警告,应进行分析解决。代码如下:#include include.hint main(void) OSInit(); OSStart();如上面一步没有问题,真正的测试工作开始了。下面来验证OSTaskStkInit()、OSStartHighRdy()和OSCtxSw()函数,用AVRstudio对上面的TEST.C的.COF进行汇编代码级的在线仿真,单步执行观看程序的执行流程,经过初始化后的堆栈结构、弹出最高就绪态任务的执行环境和任务切换的过程分别见下图:图6 任务初始化过程图7 弹出任务堆栈的内容图8 任务切换过程下面验证OSIntCtxSw()和OSTickISR()函数,把程序下载到评估板上观看LED的闪烁,若闪烁,说明两函数能正常工作;若不闪烁,可以在线调试,设置断点,看哪里出了问题。程序如下:#include include.hOS_STK TestTaskStk100;void TestTask(void* pdata);void init_timer0(void);/*利用atmega128的8位定时器Timer0的输出比较匹配单元产生定时中断,程序中设定为200Hz(5ms)*/int main(void) OSInit(); OSTaskCreate(TestTask,(void*)0,&TestTaskStk99,0); OSStart();void TestTask(void* pdata) pdata=p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论