毕业论文uCOSII到ARM的移植【最终版】 03652

上传人:1666****666 文档编号:36869210 上传时间:2021-11-01 格式:DOC 页数:73 大小:5.31MB
收藏 版权申诉 举报 下载
毕业论文uCOSII到ARM的移植【最终版】 03652_第1页
第1页 / 共73页
毕业论文uCOSII到ARM的移植【最终版】 03652_第2页
第2页 / 共73页
毕业论文uCOSII到ARM的移植【最终版】 03652_第3页
第3页 / 共73页
资源描述:

《毕业论文uCOSII到ARM的移植【最终版】 03652》由会员分享,可在线阅读,更多相关《毕业论文uCOSII到ARM的移植【最终版】 03652(73页珍藏版)》请在装配图网上搜索。

1、洛阳理工学院毕业设计(论文)uC/OS-II到ARM的移植摘 要随着科技的进步,新技术的不断发展和工厂自动化体系不断完善,如仅仅依靠计算机来处理所有的任务就显得成本有些太高,当然也不能满足功耗低的和软硬件可裁剪的要求。所以以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统,即嵌入式系统应运而生。这就为工厂自动化提供了良好的技术条件和基础。为了充分突出嵌入式系统的优势,在嵌入式系统上移植操作系统显得很重要了,本文就是将C/OS-II移植到ARM7上从而实现在嵌入式系统上实现对ARM7任务的调度,从而实现任务的并发执行,提高各个任

2、务的工作效率。因本文主要针对C/OS-II移植到ARM系统平台这一部分进行展开的,所以下面的内容主要是围绕以下几个部分对C/OS-II的移植进行阐述: 1 论述操作系统下的编程的好处及C/OS-II 移植到我们所做课题上的优势。2. uC/OS-II操作系统的核心介绍 3. 本课题需要了解ARM体系架构知识。4. 详细介了C/OS-II在ARM上的移植过程。5. 简单介绍了操作系统移植后的测试步骤和方法。6. 最后对整个毕业设计作了一些总结并对进课题不足及进一步的研究提出展望。关键词:嵌入式系统,自动化,C/OS-II,ARM,移植 THE C/OS-II OF TRANSPLANTATION

3、 FOR ARMABSTRACTWith advances in technology, the continuous development of new technologies and factory automation system has improved constantly, just rely on the computers to handle all of the task makes the expenses become too high, of course, it can not meet the low power consumption and the req

4、uirements of hardware and software which can be tailored. Therefore, application-centric, computer technology, software and hardware can be tailored to meet the application system functionality, reliability, cost, size, power consumption, demanding for a special computer system and that is why the e

5、mbedded system came into being. Its can provide a good technical conditions and foundation for the factorys automation. In order to fully highlight the advantages of embedded systems, the transplant of the embedded operating system in the operating system becomes very important , This article is the

6、 C / OS-II ported to ARM7 which realize the ARM-based embedded systems can achieve the control of cars inner environment comfort level control.Because of this article for C / OS-II ported to ARM platform to start this part, so the following parts mainly about the transplantation of the C / OS-II. 1.

7、 Discusses the benefits of operating system programming and the advantages of using C / OS-II ported to the subject which we have done. 2. Discussion of existing hardware resources for ARM7 C / OS-II feasibility and characteristics of migration. 3.the knowledge we need about the ARM Architecture. 4.

8、 Detailly Introduced the C / OS-II in ARMs transplant process. 5. Briefly introduced the testing procedures and methods of the transplantation the operating system. 6. Finally, some conclusions were made throughout the project and raised the lack of the project and the further outlook about the rese

9、arch.KEY WORDS: embedded system,automation,C/OS-II,ARM,Transplantatio2目录前言1第1章 RTOS移植的意义31.1 本章概要31.2 选用RTOS的理由31.2.1 前后台系统31.2.2 实时操作系统(RTOS)41.2.3 RTOS与前后台系统的比较51.3结论及总结6第2章 uC/OS-II实时操作系统概述72.1 uC/OS-II的发展史72.2 uC/OS-II简介7第3章 uC/OS-II实时操作系统简要深入分析93.1 uC/OS-II代码结构93.2 uC/OS-II的任务管理和调度103.2.1 资源103

10、.2.2 多任务处理103.2.3 任务103.2.4 环境转换(或者任务切换)123.2.5 内核123.2.6 调度程序133.2.7 系统任务的创建133.2.8 任务堆栈的初始化OSTaskStkInit()163.2.9 任务控制块的初始化OSTCBInit()173.3 uC/OS-II事件管理23第4章 移植的硬件平台274.1 本章概要274.2 ARM7内核特点274.2.1 ARM内核与CPSR274.3 移植的可行性分析31第5章 uC/OS-II到ARM7移植详解335.1 总体的配置335.2 系统的裁剪实现345.3 uC/OS-II与ARM接口文件的实现355.3

11、.1 C/OS-II文件结构355.3.2 编写OS_CPU.H355.3.3 编写OS_CPU_C.C385.3.4 编写OS_CPU_A.S425.3.5关于中断和时钟节拍475.4 移植代码应用到LPC2400495.4.1 编写或获取启动代码495.4.2挂接SWI软件中断505.4.3中断与时钟节拍中断50第6章 系统整体测试526.1 本章概要526.2 系统测试526.3 系统测试步骤526.4 系统测试结果分析53结论54谢 辞55参考文献56附录57外文资料翻译63前言嵌入式计算系统(Embedded Computing System)是指以应用为中心,计算机技术为基础,并且

12、软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗等有严格要求的专用计算机系统;主要由嵌入式处理器、相关支撑硬件、嵌入式操作系统及应用软件系统等组成,嵌入式系统是执行专用功能并被内部计算机控制的设备或者系统。它一般不使用通用型计算机,而且运行的是固化的软件,用术语表示就是固件,终端用户很难或者不可能改变固件,操作系统和应用软件集成于计算机硬件系统之中,即系统的应用软件与系统的硬件一体化。嵌入式系统具有软件代码少、高度自动化、响应速度快等特点,特别适合于要求实时和多任务处理的情况。与通用型计算机系统相比,嵌入式系统功耗低、可靠性高:功能强大、性能价格比高、实时性强,支持多任务:占用空间

13、小,效率高,面向特定应用,可根据需要灵活定制。由于嵌入式系统通常应用于环境比较恶劣的环境中,因而嵌入式微处理器在工作温度、电磁兼容性以及可靠性方面的要求较通用的标准微处理器高。这也使嵌入式系统在工厂等条件非常苛刻的地方得到了广泛的应用。嵌入式系统在当今世界已经渗透到了各个领域,无论是航天,医疗器材,自动化工厂还是到我们生活的消费娱乐产品都可以找到嵌入式的应用实例。在本课题里我们利用嵌入式系统实现了以太网的通信,解决了现代化工厂通信的局限性的问题,达到了嵌入式系统与通用计算机的无缝连接且不受距离限制的目的,方便了处理器之间信息的传输和交流,对现代化工厂的实际应用起到了相应的推动作用。谈到嵌入式系

14、统, ARM就是用到用途比较广泛的处理器之一,ARM7内核是0.9MIPS/MHz的三级流水线和冯诺伊曼结构,ARM7TDMI提供了非常好的性能与功耗比。ARM处理器本身是32位设计,但也配备16位指令集。一般来讲存储器比等价32位代码节省达35,然而保留了32位系统的所有优势。ARM具有小型、快速、低能耗的特点,采用集成式的RISC内核。ARM7TDMI(Thumb):这是公司授权用户最多的一项产品,将ARM7指令集同Thumb扩展组合在一起,以减少内存容量和系统成本。同时,它还利用了嵌入式ICE调试技术用来简化系统的设计,并用一个DSP增强扩展来改进性能。该产品的典型用途是数字蜂窝电话和硬

15、盘驱动器。因此ARM的应用也是非常泛的。另外,根据ARM处理器的特点,ARM是非常适合跑操作系统的,这就为简单的操作系统移植到ARM上提供了一个良好的硬件平台,本文就是以C/OS-II 移植到ARM LPC2400进行开发设计的。 第1章 RTOS移植的意义 1.1 本章概要我们为什么要把C/OS-II移植到ARM上,操作系统下的编程和我们前后台编程相比又具有什么样的优势和意义呢?这是我们进行C/OS-II的移植首先要考虑到的问题,如果操作系统下的编程没有什么突出的优点的话我们的移植也就没有什么实际的意义了。因本课题用的是基于嵌入式的实时操作系统,所以下面我们就有必要带着这个问题探讨一下操作系

16、统编程的特点了。1.2 选用RTOS的理由1.2.1 前后台系统不复杂的小系统一般设计成如图1-1所示的样子。这种系统可称为前后台系统或超循环系统。应用程序是一个无限的循环,该循环调用了一些模块(也就是函数)来执行希望进行的操作(后台)。中断服务程序(ISR)处理异步事件(前台)。前台被称为中断级,后台被称为任务级。时间相关性很强的关键操作必须由ISR执行以确保它们能够以及时的方式进行处理。由于这个原因,ISR花的时间会更长。对于ISR可以使用的后台模块的信息,要到后台例程执行后才会被处理。这被称为任务级响应时间。最糟的情况是任务级的响应时间取决于整个循环的执行时间。因为循环的执行时间不是常数

17、,程序经过某一特定部分的准确时间也不能确定。而且,如果改变了其中的代码,则循环的时序会受到影响。大多数基于微型控制器的应用(例如,微波炉、电话、玩具,等等)设计为前台/后台系统。图1-1前台/后台系统1.2.2 实时操作系统(RTOS)从八十年代末开始,陆续出现了一些RTOS,比较著名的有Vxwork、pSOSystem、NucleusPLUS和WindowsCE。实时操作系统是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,并控制所有实时任务协调一致运行的操作系统。因而,提供及时响应和高可靠性是其主要特点。实

18、时操作系统有硬实时和软实时之分,硬实时要求在规定的时间内必须完成操作,这是在操作系统设计时保证的;软实时则只要按照任务的优先级,尽可能快地完成操作即可。我们通常使用的操作系统在经过一定改变之后就可以变成实时操作系统。实时操作系统是保证了在一定时间限制内完成特定的功能。例如,在一个生产线上可以为确保生产线上的机器人能获取某个物体而设计一个操作系统。在“硬”实时操作系统中,如果不能在允许时间内完成使物体可获得的计算,操作系统将因错误而结束。但是在“软”实时操作系统中,生产线仍然能继续工作,但产品的输出会因产品不能在允许时间内到达而减慢,这使机器人有短暂的不生产现象。这就是“软”实时与“硬”实时的主

19、要区别。1.2.3 RTOS与前后台系统的比较从以上二者的工作原理及其优缺点可知RTOS的实时性要明显高于传统意义是的前后台操作系统,并且实时操作系统的具有多种时间同步机制。为各个任务之间的通信和同步都带了极大的方便。同时也使程序的设计显得更为方便和容易。当然实时操作系统比前后台操作系统要占用更多的内存。所以要为实时操作系统预留一部分的内存空间。这也是使用实时操作系统进行开发设计首先考虑的。对于前后台系统而言,在实时操作系统里我们可以使用信号量简单的实现两个任务的同步,并且利用邮箱机制可以很容易实现任务之间的信息的安全、实时的传递;而在传统的前后台任务中我们就需要考虑各个子模块之间的有效通信的

20、细节问题,考虑各个任务执行的时间会不会影响要求具有高实时任务的运行,必要的时候还可能用到多个中断来提高任务的实时性,并对各个模块进行有效的组织和安排才能达到设计要求。相反,在实时操作系统中我们只需要处理好各个任务的子模块,然后只需要将各个任务划分为不同的优先级就能保证工作在高优先级的任务具有更高的实时性。另外,实时操作系统(如C/OS-II)还提供了内存管理及其事件标志管理功能,这样我们就可以很方便的通过的几个函数简单向里面传递几个参数很容易的实现多个事件的同步和复杂的内存操作与管理,所有的这些都简化了应用程序的设计,缩短了工程项目的开发时间,同时也提高了工作效率。最重要的是基于RTOS的程序

21、设计也使整个系统实时性和可靠性得到了明显的提高。从长远意义上来讲,嵌入式系统的软件开发过程已经日趋工程化,要求产品进入市场时间不断缩短,也迫使管理人员寻找一种有利于程序继承性、标准化、多人并行开发的管理开发模式。RTOS的出现和推广能够带来嵌入式系统软件工业更有效、更专业化的分工,减少社会重复劳动、提高劳动生产率,这些也是嵌入式系统今后发展的必然趋势。所以实时操作系统的发展对嵌入式软件编程具有重大的意义。1.3 结论及总结谈到这里,相信对于选用RTOS的理由也明朗了,接下来的工作才有了在现实中进行应用的意义。我们在进行嵌入式开发设计时首先需要选择一个开发平台,结合上述两种平台的对比分析,我们选

22、用C/OS-II操作系统,那么我们接下来就要考虑到C/OS-II操作系统的移植问题了,所以在下面几章里将详细介绍了将C/OS-II移植到ARM7内核的处理器。有了这样一个平台为基础我们就可以进行应用程序的设计了。第2章 uC/OS-II实时操作系统概述2.1 uC/OS-II的发展史C/OS-II 的前身是C/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在嵌入式系统编程杂志的5 月和6 月刊上刊登的文章连载,并把C/OS 的源码发布在该杂志的B B S 上。是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。与CPU 硬件相关部分是用汇编语言编写

23、的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将C/OS-II嵌人到开发的产品中。C/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。现在C/OS-II已经移植到超过200多种微处理器上,并通过美国航空航天管理局检测,可以用于极度苛刻环境中。C/OS-II以源代码的形式发布,但并不意味着它是免费软件。你可以将其用于教学和私下研究;但是如果你将其用于商业用途,那么你必须通过Micrium获得商用许可。2.2 uC/OS-I

24、I简介C/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。严格地说C/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于C/OS-II良好的可扩展性和源码开放,这些非必须的功能,完全可以由用户自己,根据需要分别实现。C/OS-II 中最多可以支持64 个任务,分别对应优先级063,其中0为最高优先级。63为最低优先级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所以用户可以使用的任务数有56个。C/OS-II提供了任务管理的

25、各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,该任务负责统计当前CPU的利用率。C/OS-II的时间管理是通过定时中断来实现的,该定时中断一般为10毫秒或100毫秒发生一次,时间频率取决于用户对硬件系统的定时器编程来实现。中断发生的时间间隔是固定不变的,该中断也成为一个时钟节拍。C/OS-II要求用户在定时中断的服务程序中,调用系统提供的与时钟节拍相关的系统函数,例如中断级的任务切换函数,系统时间函数。内存方面,在ANSI C中是使用

26、malloc和free两个函数来动态分配和释放内存。但在嵌入式实时系统中,多次这样的操作会导致内存碎片,且由于内存管理算法的原因,malloc和free的执行时间也是不确定。C/OS-II中把连续的大块内存按分区管理。每个分区中包含整数个大小相同的内存块,但不同分区之间的内存快大小可以不同。用户需要动态分配内存时,系统选择一个适当的分区,按块来分配内存。释放内存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的。本次设计没有设计到内存的管理,所以这部分就只做简单的介绍。通信方面,对一个多任务的操作系统来说,任务间的通信和同步是必不可少的。C/OS-II中提供了4种同步

27、对象,分别是信号量,邮箱,消息队列和事件。所有这些同步对象都有创建,等待,发送,查询的接口服务函数用于实现进程间的通信和同步。内核调度部分,C/OS-II采用的是可剥夺型实时多任务内核。可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务。C/OS-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务,获取CPU的使用权。为了简化系统设计,C/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。8洛阳理工学院毕业设计(论文)第3章 uC/OS-II实时操作系统简要深入分析3.1 uC/OS-I

28、I代码结构图3-1形象的列出了uC/OS-II内核代码的分布。图3-1 uC/OS-II内核文件结构整个内核代码从上至下,一共分为三部分(除去标号4方框,这部分是用户的应用程序,)。标号2方框内是主要用来配置系统和裁剪系统的大小,可以删除一些在具体的设计中不需要的代码,以节省系统的空间。标号1部分是系统核心的服务代码,包括系统工作的代码的定义,比如完成系统初始化,系统任务之间的调度,创建任务事件,系统算法等等。标号3部分代码与具体CPU息息相关,是本课题研究的核心内容(移植部分),通过改写它们来实现uC/OS-II与具体的CPU相联系。主要工作就是中断和任务切换过程中,现场的保护和恢复。3.2

29、 uC/OS-II的任务管理和调度在进入真正移植之前,首先需要明白系统是如何工作的,即任务是如何被系统管理和调度。3.2.1 资源一个任务使用的资源是任何实体。因此,一个资源可以是I/O设备,比如打印机、键盘、显示器,或者一个变量、结构或者数组。3.2.2 多任务处理多任务处理是在几个任务之间进行调度和切换CPU的过程;单个的CPU在几个任务之间转换其注意力。多任务处理像前/后台系统一样,带有多个后台。多任务处理能够最大程度地利用CPU,并且也提供应用程序的模块化构造。多任务处理中,最重要的特点之一就是它可以让编程人员来管理实时应用程序中的内在复杂性。如果使用了多任务处理,应用程序通常更容易设

30、计和维护。3.2.3 任务一个任务可以把它看成是一个完全占有CPU资源的简单程序。对于实时应用程序,这个设计过程就包括了把问题分割成为若干部分,每一部分由相应的任务进行处理。对每一个任务分配一个优先级,它拥有一组CPU寄存器,并且拥有堆栈区(如图3-2多任务处理)。图3-2 多任务处理每一个任务通常是一个可以包含如下五个状态的无穷循环:即睡眠状态、就绪状态、运行状态、等待状态,或者ISR状态(如图3-3)。对应于一个任务的睡眠状态,是指该任务驻留在内存中但是不能够使用多任务内核。当一个任务可以被执行但是它的优先级低于当前处于运行状态的任务时,该任务就处于就绪状态。一个任务控制CPU时处于运行状

31、态。当一个任务需要其他事件的发生才能被激活时,该任务就处于等待状态。最后,当一个中断发生时,该任务就处于ISR状态,CPU处于响应这个中断请求的过程中。图3-3也显示了由uC/OS-II提供的一些函数,这些函数可以让一个任务由一个状态转换为另一个状态。图3-3 任务状态3.2.4 环境转换(或者任务切换)当一个多任务处理内核决定运行一个不同的任务时,它将简单地把当前任务的环境(CPU的寄存器)保存到当前任务的环境存储区它的堆栈中(图3-2)。一旦执行了这个操作,新任务的环境将从存储区恢复,然后重新开始执行新的任务代码。这个处理过程称为环境转换或者任务切换。环境转换将增加应用程序的系统开销。一个

32、CPU需要的寄存器越多,它的系统开销将越高。执行环境转换的时间通常是由CPU需要保存和恢复多少个寄存器决定的。3.2.5 内核内核是负责任务管理(也就是负责管理CPU时间)及任务之间进行通信的多任务处理系统的一部分。它所提供的基本服务时环境转换。一个实时内核的使用通常简化了系统的设计,因为该系统可以允许把应用程序分割为由内核管理的多个任务。内核将增加系统的开销,因为它需要额外的ROM(代码空间)和附加的RAM来保存内核数据结构。但是最重要的是,每一个任务都有它自己的堆栈空间。3.2.6 调度程序调度程序也被称为分配器,它是内核的一部分,负责判断接下来将执行哪一任务。大多数实时内核是基于优先级的

33、。uC/OS-II也是如此。每一个任务根据它的重要性被分配一个优先级。每一个任务的优先级与应用程序相关。在基于优先级的内核中,CPU的控制权总是被即将运行的且优先级最高的任务所占有。然而,优先级最高的任务何时占有CPU是由所使用的内核类型来确定的。下面是任务创建,堆栈初始化以及任务控制块初始化的具体实现代码和简要分析,这部分内容对移植不是十分必要,有兴趣可以详细阅读,进一步深入了解。3.2.7 系统任务的创建在uC/OS-II中创建任务是件相当简单的事情。下面我们深入的探讨一下这个过程。INT8U OSTaskCreate(void(*task)(void* pd),void* pdata,O

34、S_STK *ptos,INT8U prio)入口参数:task:指向任务代码的指针(函数指针)pdata:传递给任务的参数(一个指针变量)ptos:指向任务堆栈栈顶的指针prio:任务的优先级返回值为:OS_NO_ERR:函数调用成功OS_PRIO_EXIST:具有该优先级的任务已经存在OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIOOS_NO_MORE_TCB:系统中没有OS_TCB可以分配给任务了 特殊说明:任务堆栈必须声明为OS_STK类型。注意:在中断处理程序中不能建立任务。在任务中必须调用C/OS提供的下述过程之一:延时等待、任务挂起、等待事件发生(

35、等待信号量,消息邮箱、消息队列),以便其它任务也能获得CPU的使用权。任务建立的详细代码如程序清单3-1所示程序清单3-1 OSTaskCreate代码INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) void *psp; INT8U err; if (prio OS_LOWEST_PRIO) (1) return (OS_PRIO_INVALID); OS_ENTER_CRITICAL(); if (OSTCBPrioTblprio = (OS_TCB *)0) (2) OST

36、CBPrioTblprio = (OS_TCB *)1;(3) OS_EXIT_CRITICAL();(4) psp = (void *)OSTaskStkInit(task, pdata, ptos, 0);(5) err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0);(6) if (err = OS_NO_ERR) (7) OS_ENTER_CRITICAL(); OSTaskCtr+;(8) OSTaskCreateHook(OSTCBPrioTblprio);(9) OS_EXIT_CRITICAL(); if (OSRun

37、ning) (10) OSSched();(11) else OS_ENTER_CRITICAL(); OSTCBPrioTblprio = (OS_TCB *)0;(12) OS_EXIT_CRITICAL(); return (err); else OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL() 由移植代码决定 。一般来说,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()为定义的宏,用来禁止、打开CPU的中断,无函数参数和返回值 。OS_ENTE

38、R_CRITICAL()和OS_EXIT_CRITICAL()必须成对使用。OSTaskCreate()一开始先检测分配给任务的优先级是否有效3-1(1)。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务3-1(2)。在使用C/OS-时,每个任务都有特定的优先级。如果某个优先级是空闲的,C/OS-通过放置一个非空指针在OSTCBPrioTbl中来保留该优先级3-1(3)。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断3-1(4)。然后,OSTaskCreate()调用OSTaskSt

39、kInit()3-1(5),它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。如果已经有人在你用的处理器上成功地移植了C/OS-,而你又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。C/OS-

40、支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(),而栈顶可能是堆栈的最高地址(堆栈从上往下递减),也可能是最低地址(堆栈从下往上长)。一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()3-1(6),从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()的代码如程序清单 3-2所

41、示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB3-2(1),如果OS_TCB池中有空闲的OS_TCB3-2(2),它就被初始化3-2(3)。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。因为我们用的功能相对简单,所以对于任务的初始化,主要就是堆栈初始化和任务控制块的初始化。下面我们来看看这两个初始化的过程。3.2.8 任

42、务堆栈的初始化OSTaskStkInit()这个函数属于移植部分需要介绍的函数,因为它牵扯到具体的堆栈问题,所以必须放到ARM接口部分进行代码的构造。因为ADS_V1.2集成开发环境的C编译器只支持满递减的堆栈存取方式,所以ARM只能采取这样的方式。具体的代码我们会在后面的移植部分详细的介绍,这里只是简单的介绍一下。一旦用户初始化了堆栈,OSTaskStkInit()就需要返回堆栈指针所指的地址。OSTaskCreate()会获得该地址并将它保存到任务控制块(OS_TCB)中。处理器文档会告诉用户堆栈指针是会指向下一个堆栈空闲位置,还是会指向最后存入数据的堆栈单元位置。3.2.9 任务控制块的

43、初始化OSTCBInit()在这个函数调用之前,甚至是任务创建函数调用之前,系统会完成对任务控制块的初始化,使系统创建的任务控制块结构体OS_TCB成为双向的链表,并完成几个控制变量的初始化。typedef struct os_tcb OS_STK*OSTCBStkPtr;#if OS_TASK_CREATE_EXT_ENVoid*OSTCBExtPtr;OS_STK*OSTCBStkBottom;INT32UOSTCBStkSize;INT16UOSTCBOpt;INT16UOSTCBId;#endifstruct os_tcb *OSTCBNext;struct os_tcb *OSTCB

44、Prev;#if (OS_Q_EN & (OS_MAX_QS = 2) | OS_MBOX_EN | OS_SEM_ENOS_EVENT*OSTCBEventPtr;#endif#if (OS_Q_EN & (OS_MAX_QS = 2) | OS_MBOX_ENVoid*OSTCBMsg;#endifINT16UOSTCBDly;INT8UOSTCBStat;INT8UOSTCBPrio;INT8UOSTCBX;INT8UOSTCBY;INT8UOSTCBBitX;INT8UOSTCBBitY;#if OS_TASK_DEL_ENBOOLEANOSTCBDelReq;#endif OS_TC

45、B;OSTCBStkPtr是指向当前任务栈顶的指针。C/OS-允许每个任务有自己的栈,尤为重要的是,每个任务的栈的容量可以是任意的。有些商业内核要求所有任务栈的容量都一样,除非用户写一个复杂的接口函数来改变之。这种限制浪费了RAM,当各任务需要的栈空间不同时,也得按任务中预期栈容量需求最多的来分配栈空间。OSTCBStkPtr是OS_TCB数据结构中唯一的一个能用汇编语言来处置的变量(在任务切换段的代码Context-switching code之中,)把OSTCBStkPtr放在数据结构的最前面,使得从汇编语言中处理这个变量时较为容易。OSTCBExtPtr 指向用户定义的任务控制块扩展。用

46、户可以扩展任务控制块而不必修改C/OS-的源代码。.OSTCBExtPtr只在函数OstaskCreateExt()中使用,故使用时要将OS_TASK_CREAT_EN设为1,以允许建立任务函数的扩展。例如用户可以建立一个数据结构,这个数据结构包含每个任务的名字,或跟踪某个任务的执行时间,或者跟踪切换到某个任务的次数。注意,笔者将这个扩展指针变量放在紧跟着堆栈指针的位置,为的是当用户需要在汇编语言中处理这个变量时,从数据结构的头上算偏移量比较方便。OSTCBStkBottom是指向任务栈底的指针。如果微处理器的栈指针是递减的,即栈存储器从高地址向低地址方向分配,则OSTCBStkBottom指

47、向任务使用的栈空间的最低地址。类似地,如果微处理器的栈是从低地址向高地址递增型的,则OSTCBStkBottom指向任务可以使用的栈空间的最高地址。函数OSTaskStkChk()要用到变量OSTCBStkBottom,在运行中检验栈空间的使用情况。用户可以用它来确定任务实际需要的栈空间。这个功能只有当用户在任务建立时允许使用OSTaskCreateExt()函数时才能实现。这就要求用户将OS_TASK_CREATE_EXT_EN设为1,以便允许该功能。OSTCBStkSize存有栈中可容纳的指针元数目而不是用字节(Byte)表示的栈容量总数。也就是说,如果栈中可以保存1,000个入口地址,每

48、个地址宽度是32位的,则实际栈容量是4,000字节。同样是1,000个入口地址,如果每个地址宽度是16位的,则总栈容量只有2,000字节。在函数OSStakChk()中要调用OSTCBStkSize。同理,若使用该函数的话,要将OS_TASK_CREAT_EXT_EN设为1。OSTCBOpt把“选择项”传给OSTaskCreateExt(),只有在用户将OS_TASK_CREATE_EXT_EN设为1时,这个变量才有效。C/OS-目前只支持3个选择项(见uCOS_II.H):OS_TASK_OTP_STK_CHK, OS_TASK_OPT_STK_CLR和OS_TASK_OPT_SAVE_FP

49、。OS_TASK_OTP_STK_CHK用于告知TaskCreateExt(),在任务建立的时候任务栈检验功能得到了允许。OS_TASK_OPT_STK_CLR表示任务建立的时候任务栈要清零。只有在用户需要有栈检验功能时,才需要将栈清零。如果不定义OS_TASK_OPT_STK_CLR,而后又建立、删除了任务,栈检验功能报告的栈使用情况将是错误的。如果任务一旦建立就决不会被删除,而用户初始化时,已将RAM清过零,则OS_TASK_OPT_STK_CLR不需要再定义,这可以节约程序执行时间。传递了OS_TASK_OPT_STK_CLR将增加TaskCreateExt()函数的执行时间,因为要将栈

50、空间清零。栈容量越大,清零花的时间越长。最后一个选择项OS_TASK_OPT_SAVE_FP通知TaskCreateExt(),任务要做浮点运算。如果微处理器有硬件的浮点协处理器,则所建立的任务在做任务调度切换时,浮点寄存器的内容要保存。OSTCBId用于存储任务的识别码。这个变量现在没有使用,留给将来扩展用。OSTCBNext和.OSTCBPrev用于任务控制块OS_TCBs的双重链接,该链表在时钟节拍函数OSTimeTick()中使用,用于刷新各个任务的任务延迟变量.OSTCBDly,每个任务的任务控制块OS_TCB在任务建立的时候被链接到链表中,在任务删除的时候从链表中被删除。双重连接的

51、链表使得任一成员都能被快速插入或删除。OSTCBEventPtr是指向事件控制块的指针。OSTCBMsg是指向传给任务的消息的指针。OSTCBDly当需要把任务延时若干时钟节拍时要用到这个变量,或者需要把任务挂起一段时间以等待某事件的发生,这种等待是有超时限制的。在这种情况下,这个变量保存的是任务允许等待事件发生的最多时钟节拍数。如果这个变量为0,表示任务不延时,或者表示等待事件发生的时间没有限制。OSTCBStat是任务的状态字。当.OSTCBStat为0,任务进入就绪态。可以给.OSTCBStat赋其它的值,在文件uCOS_II.H中有关于这个值的描述。OSTCBPrio是任务优先级。高优

52、先级任务的.OSTCBPrio值小。也就是说,这个值越小,任务的优先级越高。OSTCBX,OSTCBY,OSTCBBitX和OSTCBBitY用于加速任务进入就绪态的过程或进入等待事件发生状态的过程(避免在运行中去计算这些值)。这些值是在任务建立时算好的,或者是在改变任务优先级时算出的。OSTCBInit()代码如程序清单3-2所示。程序清单3-2 OSTCBInit代码INT8U OSTCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT16U stk_size, void *pext, INT16U opt) OS_T

53、CB *ptcb; OS_ENTER_CRITICAL(); ptcb = OSTCBFreeList; (1) if (ptcb != (OS_TCB *)0) (2) OSTCBFreeList = ptcb-OSTCBNext; OS_EXIT_CRITICAL(); ptcb-OSTCBStkPtr = ptos; (3) ptcb-OSTCBPrio = (INT8U)prio; ptcb-OSTCBStat = OS_STAT_RDY; ptcb-OSTCBDly = 0;#if OS_TASK_CREATE_EXT_EN ptcb-OSTCBExtPtr = pext; ptcb

54、-OSTCBStkSize = stk_size; ptcb-OSTCBStkBottom = pbos; ptcb-OSTCBOpt = opt; ptcb-OSTCBId = id;#else pext = pext; stk_size = stk_size; pbos = pbos; opt = opt; id = id;#endif#if OS_TASK_DEL_EN ptcb-OSTCBDelReq = OS_NO_ERR;#endif ptcb-OSTCBY = prio 3; ptcb-OSTCBBitY = OSMapTblptcb-OSTCBY; ptcb-OSTCBX =

55、prio & 0x07; ptcb-OSTCBBitX = OSMapTblptcb-OSTCBX;#if OS_MBOX_EN | (OS_Q_EN & (OS_MAX_QS = 2) | OS_SEM_EN ptcb-OSTCBEventPtr = (OS_EVENT *)0;#endif#if OS_MBOX_EN | (OS_Q_EN & (OS_MAX_QS = 2) ptcb-OSTCBMsg = (void *)0;#endif OS_ENTER_CRITICAL(); (4) OSTCBPrioTblprio = ptcb; (5) ptcb-OSTCBNext = OSTCB

56、List; ptcb-OSTCBPrev = (OS_TCB *)0; if (OSTCBList != (OS_TCB *)0) OSTCBList-OSTCBPrev = ptcb; OSTCBList = ptcb; OSRdyGrp |= ptcb-OSTCBBitY; (6) OSRdyTblptcb-OSTCBY |= ptcb-OSTCBBitX; OS_EXIT_CRITICAL(); return (OS_NO_ERR); (7) else OS_EXIT_CRITICAL(); return (OS_NO_MORE_TCB); 当OSTCBInit()需要将OS_TCB插入

57、到已建立任务的OS_TCB的双向链表中时3-2(5),它就禁止中断3-2(4)。该双向链表开始于OSTCBList,而一个新任务的OS_TCB常常被插入到链表的表头。最后,该任务处于就绪状态3-2(6),并且OSTCBInit()向它的调用者OSTaskCreate()返回一个代码表明OS_TCB已经被分配和初始化了3-2(7)。现在,我可以继续讨论OSTaskCreate()(程序清单 3-1)函数了。从OSTCBInit()返回后,OSTaskCreate()要检验返回代码3-1(7),如果成功,就增加OSTaskCtr3-1(8),OSTaskCtr用于保存产生的任务数目。如果OSTCB

58、Init()返回失败,就置OSTCBPrioTblprio的入口为03-1(12)以放弃该任务的优先级。然后,OSTaskCreate()调用OSTaskCreateHook()3-1(9),OSTaskCreateHook()是用户自己定义的函数,用来扩展OSTaskCreate()的功能。例如,用户可以通过OSTaskCreateHook()函数来初始化和存储浮点寄存器、MMU寄存器的内容,或者其它与任务相关的内容。一般情况下,用户可以在内存中存储一些针对用户的应用程序的附加信息。OSTaskCreateHook()既可以在OS_CPU_C.C中定义(如果OS_CPU_HOOKS_EN置1),也可以在其它地方定义。注意,OSTaskCreate()在调用OSTaskCreateHook()时,中断是关掉的,所以用户应该使OSTaskCreateHook()函数中的代码尽量简化,因为这将直接影响中断的响应时间。OSTaskCreateHook()在被调用时会收到指向任务被建立时的OS_TCB的指针。这意味着该函数可以访问OS_TCB数据结构中的所有成员。如果OSTaskCreate()函数是在某个任务的执行过程中被调用(即OSRunning置为True3-1(10),则任务调度函数会被调用3-1(11)来判断是否新建立的任务比原来的任务有更高的优先级。如果新任务的优先级更高,内

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!