毕业设计(论文)基于ARM的GPS定位信息显示器的软件设计_第1页
毕业设计(论文)基于ARM的GPS定位信息显示器的软件设计_第2页
毕业设计(论文)基于ARM的GPS定位信息显示器的软件设计_第3页
毕业设计(论文)基于ARM的GPS定位信息显示器的软件设计_第4页
毕业设计(论文)基于ARM的GPS定位信息显示器的软件设计_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

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

文档简介

1、摘要随着计算机技术,微电子技术和网络技术的迅速发展,嵌入式系统技术是电子产品设计领域最为热门的技术之一。在消费电子、网络通信、工业控制等诸多领域得到了广泛的应用。arm处理器是目前公认的领先的32位嵌入式rsic微处理器,已成为许多行业嵌入式解决方案的risc标准。arm技术以低功耗,低成本、体积小等诸多优点在嵌入式领域获得更广泛的应用。gps是以卫星为基础的无线导航定位系统。它具有全能性(陆地、海洋、航空和航天)、全球性、全天候、连续性和实时性的导航、定位和定时的功能,能为用户提供精密的三维坐标、速度和时间。本设计将阐述lpc2292的启动程序、串口uart0通讯程序、i2c通讯程序和gps

2、数据解码程序,重点介绍lpc2292串口uart0、i2c部件和nmea-0813协议,在lcd显示方面介绍如何使用zlg/gui编写菜单界面, 本软件能正确的对gps信息进行解码,并在液晶上显示。关键词: lpc2292 、 gps接收器 、 i2c 、 nmea-0813协议 abstractwith the development of the computer technology ,microelectronics and network technology, embedded system is one of the most popular technology of the

3、field of electronic product design.embedded system is adopted in the fields of consumer electronics, network communication, industrial control and so on. arm processor is a kind of advance 32-bit microprocessor embedded risc, it have becomed embedded risc stardard of solution for many industries. ar

4、m technology have low-power, low-cost, small size and many other advantages, so it applied in the field of embedded system widely.gps is a wireless navigation and positioning system based on satellite.it has the function of omnipotent (terrestrial, marine, aviation and aerospace), a global, all-weat

5、her, continuity and attachment of navigation, positioning and timing,it can provide for the customer sophisticated three-dimensional coordinates, speed and time.this article expo und that how to program for 2292bootloader、serial uart0 communi cation、i2c communication .and gps data decode,and introdu

6、ce lpc 2292 emphasis on serial uart0 、i2c and nmea-0813 protocol,and introduce how to use zlg/gui program menu interface in the part of lcd display. this software can decode gps data accuracy and display on the lcd.keyword: lpc2292 、 gps receiver 、 i2c 、 nmea-0813 protocol 目录绪论12 总体方案设计22.1 设计任务22.2

7、 硬件设计22.3 软件设计33 各模块程序设计53.1 bootloader代码53.1.1 初始化中断向量63.1.2 初始化外部总线控制器73.1.3 堆栈初始化83.1.4 目标板初始化93.2移殖cos-到lpc2292123.2.1 编写os_cup.h133.2.2 os_cpu_c.c文件153.2.3 os_cpu_a.s文件153.2.4 中断及时钟节拍173.3 信息解码程序设计183.3.1 nmea-0183的协议标准183.3.2 gps数据结构的定义203.3.3 gps信息解码程序设计233.4 串口驱动程序233.4.1 串口结构图233.4.2 串口的初始化

8、243.4.3 串口接收数据程序设计253.5 键盘处理程序273.5.1 i2c总线273.5.2 i2c总线速度的配置343.5.3 zlg7290343.6 液晶显示程序的设计364 软件的调试384.1 软件调试流程384.2 调试结果38结束语39致谢40参考文献41附录42绪论gps卫星导航定位技术是现代信息通信领域中一门新兴的技术。gps系统的空间部分由24颗卫星组成,均匀分布在6个轨道面上,地面高度为20200公里,轨道倾角为55度,扁心率约为0,周期约为12小时,卫星向地面发射两个波段的载波信号,载波信号频率分别为1575.442兆赫兹(l1波段)和1227.6兆赫兹(l2

9、波段),卫星上安装了精度很高的原子钟,以确保频率的稳定性,在载波上调制有表示卫星位置的广播星历,用于测距的c/a码和p码,以及其它系统信息,能在全球范围内向任意多用户提供高精度的、全天候的、连续的、实时的三维测速、三维定位和授时。gps系统的控制部分由设在美国本土的5个监控站组成,这些监控站不间断地对gps卫星进行观测,并将计算和预报的信息由注入站对卫星信息更新。gps系统的用户是非常隐蔽的,它是一种单程系统,用户只接收而不必发射信号,因此用户的数量也是不受限制的。目前,中国卫星导航技术应用领域十分广阔,传统测量应用及军工相关应用的比例在逐年下降,应用已渗透到许多崭新的行业。通信行业用gps做

10、时间同步测控;电力、有线电视、城市地下管道采用gps布设线路;交通、运输部门用gps等相关集成技术营建its系统和监控系统;公安、银行、医疗、消防等用gps营建紧急救援或报警系统;汽车、船舶用gps导航;gis数据提供商用gps采集地理信息相关数据,并提供位置信息相关服务(lbs);广播电视行业用gps与罗盘制造卫星电视定向接收天线;电子商务领域,gps甚至应用于crm客户管理和物流配送体系中;而电脑制造商、通讯设备商正在推动通讯、电脑、gps一体化的各类移动信息终端应用。现实的应用已经使卫星导航技术从专业化领域走向了大众化应用的广阔前景,这也使得卫星导航技术逐渐成为通信、互联网之后的第三个i

11、t新增长点。中国卫星导航产品与服务一直呈现强劲增长的势头。据有关部门统计,gps接收机相关产品的拥有量8万台左右,航海型约有5万台左右,应用数量最多;车载型以每年200%的速度递增,发展最快;手持型各类个人消费终端产品形态极为丰富,最具诱惑力。本设计主要研究对基于nmea-0813协议的gps信息解码程序的设计,程序可以对rmc(推荐定位信息)、gga(固定数据输出信息)、gsa(当前卫星信息)进行精确的解码,并能在液晶显示器显示经度、纬度、日期、时间等信息。2 总体方案设计2.1 设计任务本软件设计的所需完成的任务是:(1) 通过编写gps信息解码程序,能对gps信息进行正确的解码;(2)

12、通过移值zlg/gui,设计菜单操作界面,方便用户操作,并显示详细的gps信息。2.2 硬件设计本设计要求微处理器能提供串口接收gps模块输出的信息,并有较强的运算能力及高的处理速度使得菜单界面显示效果好。目前,arm所提供的16/32位嵌入式risc内核主要有以下几个系列产品:arm7、arm9、arm10e、arm11和securcore、strongarm和xscale等。arm7tmdi属于低端的arm处理器,其最高主频可达130mips(million instructions per second),高速的运算能力能胜任绝大多数复杂的应用。本次设计采用lpc2292作为微处理器,其

13、最高主频为60 mh z,足以胜任本次设计任务,lpc2292有256kb片内flash,为本次设计提供了足够的程序存储空间,可以不用扩展外部flash。虽然lpc2292有16kb的片内ram,但是仍然不够用,因为本设计所移植的ucos_ii操作系统和zlg/gui共生成了7kb多的data,必须为每一个任务分配足够的堆栈空间和声明存放gps信息的数组,加上定义必要的变量将增加大约6kb的data,使16kb的ram剩余不多。考虑到以后能容易的添加新的功能,本设计采用外部ram储存程序变量,具体芯片选用高速访问时间达10ns、高性能和低功耗的is61lv25616al,该芯片是美国issi公

14、司生产的sram(静态ram),存储容量是512kb,这为以后扩展功能提供极大的发挥余地。本设计采用zlg7290作为键盘接口,zlg7290是标准的i2c接口器件,只使用三个lpc2292的i/o口,其中有两个是i2c引脚sda、scl,另外一个引脚是外部中断eint3,这样就可以节省i/o口又可以扩展多达64个引脚zlg7290可以自动消除抖动,其中有8只可以作为功能键使用。另外zlg7290内部还设置有连击计数器,能够使某键按下后不松手而连续有效。在液晶方面可以选用点阵图形的单色液晶,也可以选用stn或者更高级别的液晶,但价格昂贵。本设计采用smg240128a作为显示器,就可以满足设计

15、要求。本设计的总体硬件框图如图2.1所示。lpc2292 uart gps model zlg7290 smg240128 is61lv25616al 电源 key 图2.1 总体硬件框图2.3 软件设计本设计采用cos-实时操作系统实现,该操作系统的优点是提高处理事件的实时性。本设计共建立3个任务,分别为taska、taskb、taskc。其中taska为起始任务,其优先级最高,在taska中建立taskb、taskc。taskb是显示gps信息任务,taskc是键盘检测任务。taskb获取键盘的方法是,先建立邮箱havenewkey,并等待邮箱havenewkey,taskc检测到按键按下

16、时发出邮箱havenewkey,之后当执行任务taskb时通过邮箱havenewkey获取按键值。主程序执行过程如图2.2所示。程序由7部分组成:bootloader、gps信息解码程序、串口中断服务程序、读按键值程序、zlg/gui、cos-和主程序,下面将阐述其中几部分程序的设计方法。启动初始化显示开机界面键盘检测启动接收gps信息使能串口中断对接收到的信息进行解码并显示信息等待邮箱(20个时钟节拍)havenewkey退出接收信息xingpsxinxyn显示gps简介yyn建立任务taska任务调度在taska中建立任务taskb、taskc, 延时60个时钟节拍运行任务taskb无限期

17、等待邮箱havenewkey无限期等待邮箱havenewkey运行任务taskc按键有效发出邮箱havenewkeyn延时6个时钟节拍图2.2 主程序流程图3 各模块程序设计3.1 bootloader代码bootloader代码(启动代码)是嵌入式系统中应用程序的开头部分,它与应用程序一起固化在rom中,并首先在系统上运行。bootloader代码是嵌入式程序的重要组成部分,好的bootloader代码是系统能够正常工作的前提。本设计的启动代码的整个流程图如图3.1所示。设置存储器控制寄存器设置系统各部分时钟 设置存储器加速模块 进入主程序 初始化各模式堆栈 初始化中断向量 配置外部总线 图

18、3.1 启动代码流程图3.1.1 初始化中断向量arm体系中共包含7个异常中断,异常的类型及向量地址见表3.1。表3.1 异常的类型及向量地址异常中断类型异常中断模式向量地址复位管理模式0x00000000未定义指令未定义模式0x00000004软件中断(swi)管理模式0x00000008指令预取中止中止模式0x0000000c数据访问中止中止模式0x00000010保留0x00000014外部中断请求irqirq模式0x00000018快速中断请求fiqfiq模式0x0000001c初始化中断向量是设置中断向量表,该中断向量表给出了arm芯片出现异常时转去执行的程序地址,如当arm芯片复位

19、时,产生复位中断,进入管理模式,执行地址为0x00000000处的代码。初始化中断向量程序代码如下:code32 area vectors,code,readonly entry;中断向量表reset ldr pc, resetaddr ldr pc, undefinedaddr ldr pc, swi_addr ldr pc, prefetchaddr ldr pc, dataabortaddr dcd 0xb9205f80 ldr pc, pc, #-0xff0 ldr pc, fiq_addrresetaddr dcd resetinitundefinedaddr dcd undefin

20、edswi_addr dcd softwareinterruptprefetchaddr dcd prefetchabortdataabortaddr dcd dataabortnouse dcd 0irq_addr dcd 0fiq_addr dcd fiq_handler;未定义指令undefined b undefined;取指令中止prefetchabort b prefetchabort;取数据中止dataabort b dataabort;快速中断fiq_handler stmfd sp!, r0-r3, lr bl fiq_exception ldmfd sp!, r0-r3,

21、lr subs pc, lr, #4area是伪操作,定义了名为vectors的代码段,entry是至关重要的伪操作,作用是指定程序的入口点,即是arm执行程序的起始点。从上面的代码可以看出若发生取数据中止、指令预取中止、未定义指令异常时,程序将进入死循环,这有助于用户调试程序,如执行用户代码:k+=tabtemp,若在执行该行程序之前,未对tabtemp赋值,则程序将进入取数据中止死循环,这使得用户发现程序错误从而矫正错误。当发生irq异常,cpu跳转至异常向量地址为0x00000018处执行指令ldr pc,pc,#-0x0ff0,此时程序计数器pc中内容为0x00000020,0x000

22、00020减去0x00000ff0为0xfffff030,这是向量中断控制器(vic)的向量地址寄存器vicvectaddr的地址,这个寄存器保存当前将要服务的irq中断服务程序的入口,用这一条指令就可以直接跳转到需要的中断服务程序中。保留的异常向量“dcd 0xb9205f80”位置填充数据0xb9205f8是为了使向量表中所有的数据32位累加和为0。3.1.2 初始化外部总线控制器正确的配置外部存储器控制器是保证arm运行良好的前提,lpc2292 含有外部总线控制器,支持静态存储器映射器件,包括ram、rom、flash、burst rom 和一些外部i/o器件。该模块可同时支持多达4个

23、单独配置的存储器组。初始化外部存储器控制器bcfg时,主要设置该寄存器的几个域:bm(27),若使用的是burst rom(突发数据传输仅读记忆体),则设置bm为1,否则设置为0;对不同宽度的存储器,设置mw(2928),设为00表示使用8位的存储器,设为01表示使用16位的存储器,设为10表示使用32位的存储器;若是带字节选择输入的16/32位宽度的器件,需要设置rble(10)为1,然后设置总线切换的空闲周期idcy(30),读访问长度wst1(95),写访问长度wst2。以下为配置外部存储器控制器的代码。ldr r0, =bcfg0 ldr r1, =(128)+(0x0211)+(11

24、0)+(0x025)+(1);str r1, r0;ldr r0, =bcfg1 ldr r1, =(128)+(0x411)+(110)+(0x45)+(0x01);str r1, r0;ldr r0, =bcfg2;ldr r1, =(028)+(0x611)+(110)+(0x65)+(0x01);str r1, r0ldr r0, =bcfg3; 设置bcfg3寄存器 ldr r1,= (128)+(0x511)+(110)+(0x55)+(0x01); str r1, r0本设计分别把is61lv25616al、sst39vf1601分配到bank0、bank1,is61lv2561

25、6al、sst39vf1601都是16位的外部存储器,因此mw(2928)设为1,is61lv25616al高速访问时间分别为10ns、90ns,以上的程序把对这两个外部存储器的读写配置成最快速度。3.1.3 堆栈初始化每个异常模式都有自身堆栈空间,异常处理程序通常将其它要使用的寄存器保存到这个堆栈。以下为初始化堆栈的代码。initstack mov r0, lr;设置中断模式堆栈 msr cpsr_c, #0xd2 ldr sp, stackirq;设置快速中断模式堆栈 msr cpsr_c, #0xd1 ldr sp, stackfiq;设置中止模式堆栈 msr cpsr_c, #0xd7

26、 ldr sp, stackabt;设置未定义模式堆栈 msr cpsr_c, #0xdb ldr sp, stackund;设置系统模式堆栈 msr cpsr_c, #0xdf ldr sp, =stackusr mov pc, r0stackirq dcd irqstackspace + (irq_stack_legth - 1)* 4stackfiq dcd fiqstackspace + (fiq_stack_legth - 1)* 4stackabt dcd abtstackspace + (abt_stack_legth - 1)* 4stackund dcd undtstacks

27、pace + (und_stack_legth - 1)* 4area mystacks, data, noinit, align=2irqstackspace space irq_stack_legth * 4 ;中断模式堆栈空间fiqstackspace space fiq_stack_legth * 4 ;快速中断模式堆栈空间abtstackspace space abt_stack_legth * 4 ;中止义模式堆栈空间undtstackspace space und_stack_legth * 4 ;未定义模式堆栈msr为写状态寄存器指令,该指令可以直接设置状态寄存器cpsr或sp

28、sr,上述代码的msr指令都是设置cpsr的控制域psr7:0,接着指令ldr是设置各个模式的专用的堆栈指针sp的地址。用伪操作area声明名为mystatus的数据段,数据伪操作space为各个堆栈分配内存单元,并用0初始化内存单元,从程序中可以看出中止模式、未定义模式堆栈空间都被初始化为0,是因为在这些异常模式下都是执行一个死循环不需要保存数据。由于cpu要进行模式切换即由管理模式切换到系统模式,不能由系统模式的lr正确返回子程序,所以在初始化堆栈程序的入口处保存链接寄存器lr(模式自身的lr(r14)用于保存子程序返回地址)到r0,同时用r0返回子程序。3.1.4 目标板初始化根据目标板

29、的外围电路设置存储器映射控制寄存器memmap、分频器寄存器vpb、pll倍频值寄存器pllcfg4:0、mam定时寄存器。以下为初始化目标板代码。#ifdef _debug memmap = 0x3; /remap#endif#ifdef _out_chip memmap = 0x3; /remap#endif#ifdef _in_chip memmap = 0x1; /remap#endif/* 设置系统各部分时钟 */ pllcon = 1;#if (fpclk / (fcclk / 4) = 1 /fcclk=4倍的fpclk vpbdiv = 0;#endif#if (fpclk /

30、 (fcclk / 4) = 2/fcclk=2倍的fpclk vpbdiv = 2;#endif#if (fpclk / (fcclk / 4) = 4/fcclk=1倍的fpclk vpbdiv = 1;#endif#if (fcco / fcclk) = 2 pllcfg = (fcclk / fosc) - 1) | (0 5);#endif#if (fcco / fcclk) = 4 pllcfg = (fcclk / fosc) - 1) | (1 5);#endif#if (fcco / fcclk) = 8 pllcfg = (fcclk / fosc) - 1) | (2 5

31、);#endif#if (fcco / fcclk) = 16 pllcfg = (fcclk / fosc) - 1) | (3 5);#endif pllfeed = 0xaa; pllfeed = 0x55; while(pllstat & (1 10) = 0); pllcon = 3; pllfeed = 0xaa; pllfeed = 0x55; mamcr = 0;#if fcclk 20000000 mamtim = 1;#else#if fcclk 40000000 mamtim = 2;#else mamtim = 3;#endif#endifmamcr = 2;存储器映射

32、控制寄存器的配置是根据用户使用何种方式启动arm,在调试前若选择reloutchip则编译器会执行#ifdef _out_chip memmap = 0x3; /remap#endif把memap设置为0x3,即选择用户外部存储器模式,从0x80000000处开始执行程序,这样0x80000000-0x8000003c异常向量表便映射0x00000000 -0x00 00003c。同样的,若选择relinchip则编译器会执行#ifdef _in_chip memmap = 0x1; /remap#endif选择用户flash模式,arm直接从0x00000000执行程序。在本设计中使用11.

33、0592mhz晶振,倍增器值m=4,所以处理器时钟(fcclk)为44.2368mhz。为了使电流控制振荡器频率(fcco)满足156-320mhz,选择分频器的值p=2,使得fcco=fcclk2p=176.9472mhz。取vpb分频器的分频值为1/4,所以外设时钟(fpclk)= fcclk/4=11.0592mhz,为了使pllcon和pllcfg寄存器的更改生效,必须将正确的馈送序列写入pllfeed寄存器。馈送序列是将值0xaa 写入pllfeed,接着将值0x55写入pllfeed。while(pllstat & (1 10) = 0);是等待pll处于锁定状态,mam定时寄存器

34、决定使用多少个cclk周期访问flash存储器。这样可调整mam时序使其匹配处理器操作频率,在本设置所使用的处理器时钟较快,把mamtim配置为3,即使用3个处理器时钟访问外部flash。经过了初始化中断向量表、配置外部总线、初始化各模式堆栈、设置系统各部分时钟、设置存储加速模块arm后,arm将进入用户主程序,执行用户代码。3.2 移殖cos-到lpc2292嵌入实时操作系统cos-是一种占先式多任务操作系统。可固化、可裁减、移植性好,具有良好的可靠性和稳定性。它支持64个任务,具有信号量、消息邮箱、消息队列等多种任务间通信机制,图3.2说明了c/os-的结构以及它与硬件的关系。applit

35、ion softwarecos-(processer indentent code)os_core.c os_time.cos_flag.c ucos_ii.hos_mbox.cos_mem.cos_mutex.cos_q.cos_sem.cos_task.ccos- configuration(apptication sepcific)os_cpu.hincludes.hcos- port (processer specific code) os_cpu.h、os_cpu_a.asm、os_cpu_c.ccputimersoftwarehardwarehardware图3.2 c/os-的结

36、构以及它与硬件的关系cos-ii中要移植的部分见表3.2所示。移植cos-ii到一个新的体系机构上一般需要3个文件:os_cpu.h(c语言头文件)、os_cpu_c.c(c程序源文件)及os_cpu_a.asm(汇编程序源文件)。由表3.2可以看出,移植cos-ii需要在os_cpu.h包含几个类型的定义和几个常数的定义;在os_cpu_c.c和os_cpu_a.asm中包含几个函数的定义和时钟节拍中断服务程序的代码。实际上,还有一个includes.h文件需要关注,因为每一个应用都包含独特的includes.h文件。 表3.2 cos-ii中要移植的部分移殖内容类型所属文件描述boolea

37、n、int8u int8s、int16u int16s、int32u int32s 、fp32 、fp64数据类型os_cpu.h与编译器无关的数据类型os_stk数据类型os_cpu.h堆栈数据类型os_enter_critical()、os_exit_critical()宏os_cpu.h开关中断的代码os_stk_growth常量os_cpu.h定义堆栈增长方向os_task_sw函数os_cpu.h任务切换时执行的代码ostaskstkinit函数os_cpu_c.c任务堆栈初始化函数ostaskstkinit()ostaskcreatehook()ostaskdelhook()ost

38、askswhook()ostaskstathook()ostimetickhook()ostimeidlehook()函数os_cpu_c.ccos-ii在执行某些操作调用的用户函数,一般为空osstarthighrdy()函数os_cpu_a.asm进入多任务环境时运行优先级最高的任务osintctxsw()函数os_cpu_a.asm中断级的任务切换函数ostickisr()中断服务函数os_cpu_a.asm时钟节拍中断服务程序根据j.labrosse对cos-ii移植的要求,本移植也包括os_cup.h、os_cpu_c.c和os_cpu_a.s三个文件。将os_cup_a.asm更名

39、为os_cpu_a.s是遵照ads 编译器的惯例。实际上,还有一个文件很重要,就是irq.inc,它定义了一个汇编宏,是cos-ii为arm7通用的中断服务程序的汇编与函数接口代码。时钟节拍中断服务程序也没有移植,因为其与芯片和应用都强烈相关,需要用户自己编写,不过可以通过irq.s简化用户代码的编写。3.2.1 编写os_cup.h(1)数据类型定义 数据类型的修改与所使用的编译器相关,不同的编译器使用不同的字节长度表示同一数据类型。根据ads编译器的要求,这些代码定义如下: typedef unsigned char boolean; /* 布尔变量 */typedef unsigned

40、char int8u; /* 无符号8位整型变量 */typedef signed char int8s; /* 有符号8位整型变量 */typedef unsigned short int16u; /* 无符号16位整型变量 */typedef signed short int16s; /* 有符号16位整型变量 */typedef unsigned int int32u; /* 无符号32位整型变量 */typedef signed int int32s; /* 有符号32位整型变量 */typedef float fp32; /* 单精度浮点数(32位长度)*/typedef doubl

41、e fp64; /* 双精度浮点数(64位长度)*/typedef int32u os_stk; /* 堆栈是32位宽度 */(2)使用软件中断swi作底层接口 为了使底层接口函数与处理器状态无关,同时在任务调用相应的函数不需要知道函数的位置,本移植使用软件中断指令swi作为底层接口,使用不同的功能号区分不同的函数。软件中断功能号如表3.3所示 表3.3 软中断功能号功能号接口函数 简介0x00void os_task_sw(void);任务级任务切换函数0x01void _osstarthighrdy(void);运行优先级最高的任务0x02void os_enter_critical(vo

42、id)关中断0x03void os_exit_critical(void);开中断0x80void changetosysmode(void);任务切换到系统模式0x81void changetousrmode(void); 任务切换到用户模式 0x82void taskisarm(int8u prio); 任务代码是arm代码 0x83void taskisthumb(int8u prio); 任务代码是thumb代码 底层接口函数声明如下:_swi(0x00) void os_task_sw(void); _swi(0x01) void _osstarthighrdy(void); _sw

43、i(0x02) void os_enter_critical(void); _swi(0x03) void os_exit_critical(void); _swi(0x80) void changetosysmode(void); _swi(0x81) void changetousrmode(void); _swi(0x82) void taskisarm(int8u prio); _swi(0x83) void taskisthumb(int8u prio); 用软件中断作为操作系统的底层接口就需要在c语言中使用swi指令。在ads中,有一个关键字_swi,用它声明一个不存在的函数,调用

44、这个函数就在调用这个函数的地方插入一条swi指令,并且可以指定功能号。(3) 定义堆栈增长方向 虽然arm处理器可以支持堆栈向上增长,也可以支持堆栈向下增长,但是ads的c语言编译器仅支持一种方式,即从上往下增长。所以定义如下: #define os_stk_growth 13.2.2 os_cpu_c.c文件(1) ostaskstkinit()ostaskcreate()和ostaskcreateext()通过调用ostaskstkint()来初始化任务的堆栈结构。(2) 软件中断异常swi服务程序c语言部分函数原型为void swi_exception(int swi_num,int *

45、regs);参数swi_num为功能号,而regs为指向堆栈中保存寄存器的值的位置。程序通过一个switch语句把各个功能分割开,各个功能相对独立。(3) os_enter_critical()和os_exit_critical()cos-ii使用宏os_enter_critical()和os_exit_critical()分别关中断和开中断。在arm处理器核中关中断和开中断时,通过改变程序状态寄存器cpsr中的相应位来实现。由于使用了软件中断,程序状态寄存器cpsr保存到程序状态保存寄存器spsr中,软件中断退出时会将spsr恢复到cpsr中,所以程序只要改变程序状态保存寄存器spsr中的相

46、应的控制位就可以了。3.2.3 os_cpu_a.s文件(1) softwareinterrupt()这是软件中断的汇编接口,当发生软件中断时,程序通过异常向量表跳转到软中断的汇编与c接口程序softwareinterrupt处。软件中断代码如下:ldr sp, stacksvc ; 重新设置堆栈指针stmfd sp!, r0-r3, r12, lrmov r1, sp ; r1指向参数存储位置mrs r3, spsrtst r3, #t_bit ; 中断前是否是thumb状态ldrneh r0, lr,#-2 ; 是: 取得thumb状态swi号bicne r0, r0, #0xff00ld

47、req r0, lr,#-4 ; 否: 取得arm状态swi号biceq r0, r0, #0xff000000; r0 = swi号,r1指向参数存储位置cmp r0, #1ldrlo pc, =osintctxswldreq pc, =_osstarthighrdy ; swi 0x01为第一次任务切换 bl swi_exceptionldmfd sp!, r0-r3, r12, pcstacksvc dcd (svcstackspace + svc_stack_legth * 4 - 4)因为执行任务切换时堆栈指针会指向用户的堆栈,这样下一次进入管理模式就会破坏用户堆栈,从而导致程序执行

48、不正确。所以程序在一开始设置堆栈指针。软中断指令使处理器进入管理模式,而用户程序处于系统用户模式,其它异常也有自己的处理器模式,都有各自的堆栈指针,不会因为给堆栈指针赋值而破坏其它处理器模式的堆栈而影响其它程序的执行。返回的地址已经存储在连接寄存器lr中而不是存储在堆栈中。由于进入管理模式自动关中断,所以这段程序不会被其它程序同时调用,设置的堆栈指针指向的位置肯定是空闲位置,后一次调用不会影响前一次调用。这样就可以保证“ldr sp, stacksvc”进行正确的堆栈指针设置。(2) osctxsw()任务级的任务切换函数,当任务被阻塞而主动请求cpu调度时被执行,由于此时的任务切换在非异常模

49、式下进行,因此有别于中断级别的任务切换。它的工作是先将当前的任务的cpu现场保存到该任务堆栈中。然后获得最高优先级任务的堆栈指针,从该堆栈中恢复此任务的cpu现场,使之继续执行。这样就完成一次任务的切换。(3) osintctxsw()中断级的任务切换,在时钟中断isr中发现有高优先级任务等待时钟信号的到来,则在中断退出后并不是返回被中断的任务,而是直接调度就绪的高优先级任务执行(函数osintexit()被用来在isr使得更高优先级的任务处于就绪态)。从而能够尽快让高优先级的任务得到响应,保证系统的实时性能。其基本原理与任务的切换相同。但是由于进入中断时已经保存了被中断的cpu现场,因此不用

50、做类似的操作,只需对堆栈指针做相应调整。(4) osstarthighrdy()c/os-启动多任务环境的函数叫做osstart()。用户在调用osstart()之前,必须已经建立了一个或更多任务。osstart()最终调用osstarthighrdy()函数运行多任务启动前优先级最高的任务。由软中断的汇编接口swi_exception()与c接口程序softwareinterrupt()可知,这是调用软中断的1号功能。这是因为arm处理器核具有两个指令集,在执行thumb指令的状态时不是所有寄存器都可见,而且任务可能不在特权模式。为了兼容任意一种模式,本移植使用软中断指令swi使处理器进入管

51、理模式和arm指令状态,并使用功能1实现osstarthighrdy的功能。c/os-中调用函数osstarthighrdy()之前,ostcbhighrdy指向的是优先级最高的任务的任务控制块。_osstarthighrdy代码如下: msr cpsr_c, #(noint | sys32mode) ldr r4, =osrunning mov r5, #1 strb r5, r4 bl ostaskswhook ldr r6, =ostcbhighrdy ldr r6, r6 b osintctxsw_1在c/os-中,需要用户提供周期性信号源,用于实现时间延时和确认超时。必须在多任务系统启动以后再开启时钟节拍器,也就是在调用osstart()之后。换句话说,在调用osstart()之后做的第一件事是初始化定时器中断。通常,容易犯的错误是将允许时钟节拍器中断放在系统初始化函数osinit()之后

温馨提示

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

评论

0/150

提交评论