已阅读5页,还剩31页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
杭州电子科技大学嵌入式系统课程设计报告学号 142060105 姓名 汪大卫 班级 14级研究生(4)班 指导教师: 余善恩、蒋鹏 2015年6月基于 ARM和C/OS-II 实时操作系统的嵌入式数字温度计的设计一、 嵌入式数字温度计硬件实现温度计是测量物体冷热程度的工业自动化仪表。它将温度传感器产生的电阻信号转化为温度显示在仪表上。所以一般温度测量仪都有检测和显示两个部分:温度传感器热电阻是检测部分,而与之相配的指示和记录仪表是显示部分。温度传感器可根据所需精度和温度范围选用标准铂电阻温度计,精密铂电阻温度计,工业铂热电阻和工业铜热电阻等。 数字温度计可以广泛应用于标准计量实验室,科研院所,大专院校及工业现场,既可作为温度标准,也可用于温度的精密测量。 采用 AT91M55800A 微处理器开发温度测量仪,其系统框图如图3.1所示。主要包括以下几个方面的内容: 1存储器系统 2系统接口 3用户接口显示 LCD与键盘,A/D图 1.1 基于ARM微处理器的嵌入式硬件平台体系结构1.1 存储器接口 外部总线接口EBI用于产生访问片外存储器和外部器件的信号。EBI可寻址 64KB的空间,具有8个片选线和24条地址线。地址线的高 4 位与片选线是复用的。16 位的数据总线经过配置可以与 8 位或16 位外部器件接口。独立的读写控制线允许 AT91 微控制器与存储器以及外部器件直接接口。EBI支持不同的访问协议,可以对存储器实行单周期访问。EBI的主要特点有: 外部存储器映射 多达 8个片选线(NCS0NCS3,CS4CS7) 816位数据总线 字节写或字节选择控制线 引到存储器的重映射 两种不同的读协议 可编程的等待周期产生器 外部等待请求 可编程的数据线浮空时间外围地址由相应的片选寄存器状态决定。在使用它们之前,应先对他们进行重映射。表 1.1 显示了一些外围进行重映射之后的地址分配。表1.1 地址重映射之后地址分配外围片选信号片选寄存器寄存器状态举例地址空间FlashNCS0EBI_CSR00x010025290x010000000x011fffffSRAMNCS1EBI_CSR10x020031210x020000000x0207ffffLCDNCS2EBI_CSR20x0300232e0x030000000x03000001片选寄存器为 8 个 32 位寄存器(EBI_CSR0EBI_CSR7)。这些寄存器的基地址是 0xFFE00000。 Flash 的片选信号为 NCS0,所以它对应的片选寄存器为EBI_CSR0。高 8 位设为 0x01,即基地址为 0x01000000。由于开发板上有 2MB的 Flash,所以地址空间为0x010000000x011FFFFF。 SRAM 的 基 地 址 设 置 为 0x02000000 , 所 以 地 址 空 间 为0x020000000x0207ffff(512KB)。 LCD的基地址由 NCS2 控制。基地址为0x03000000,地址空间为0x030000000x03000001。 下面介绍Flash存储器接口。 Flash存储器作为一种安全、快速的存储体,具有体积小、容量大、成本低、掉电数据不丢失等一系列优点。目前已经逐步取代其它半导体存储元件,成为嵌入式系统中主要数据和程序载体。T49BV1614是 ATMEL 公司生产的16兆位 Flash存储器,主要作用是固化程序和保存历史数据,也就是开机后执行闪存的程序,并在程序执行的过程中实时地保存或修改其内部的数据单元。下面首先介绍AT49BV1614 的特点和操作。 AT49BV1614是采用2.7V3.3V 电源供电的可编程只读存储器,是一种电可擦除与重新编程的器件。该器件由8个独立的8K字节块,2 个 32K 字节块,30 个 64K 字节块,具有 40 个扇区的 16Mbit 的存储器。访问速度为 90ns。片内的状态机编程和擦除器件、嵌入式字节编程与区段/芯片擦除功能是全自动的,引脚描述如下。 A0A19:地址线。 I/O0I/O14:数据输入/输出。在读周期输出数据; I/O15(A-1):I/O15 时是数据输入输出端,字模式;A-1时是低8 位输入端,字节模式; CE:输入,芯片使能,低电平时选中该器件。 OE:输入,输出使能,低电平时打开数据输出缓冲区,允许读操作。 WE:输入,写使能,低电平时允许写操作。 BYTE:输入,选择字节或字模式。 VCCQ为 3.3V电源。Vss为地。 下面以命令表的编程命令为例。简要介绍字节编程。表 1.2 所列命令是一个6总线周期指令。表 1.2 软件命令简表命令第一周期第二周期第三周期第四周期第五周期第六周期读地址数据芯片擦除5555AA2AAA555555805555AA2AAA55555510扇区擦除5555AA2AAA555555805555AA2AAA55地址30字节/字5555AA2AAA55555580地址数据单脉冲地址数据扇区 锁定5555AA2AAA555555805555AA2AAA55地址40对于芯片擦除功能,自动地提供编程和电擦除之前,校验所有存储单元所需的电压和时序,然后自动擦除并校验单元界限。利用数据轮询(datapolling)特性,可以监视自动芯片擦除操作期间器件的状态,以检验操作是否完成。程序如下:const FlashDef *flash_identify ( flash_word *load_addr ) flash_word manuf_code ; flash_word device_code ; const FlashDef *flash_pt ; flash_word *base_addr ; int exit = FALSE ; flash_pt = FlashTable ; while ( exit = FALSE ) base_addr = (flash_word *) (int)load_addr & (flash_pt-flash_mask) ; /LCD_printf16 (int)base_addr,3,1) ; LCD_printf16 ( flash_pt-flash_name ,5,1) ; *(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1; *(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2; *(base_addr + FLASH_SEQ_ADD1) = ID_IN_CODE; /* Read Manufacturer and device code from the device manuf_code = *base_addr ; device_code = *(base_addr + 1) ; /* Exit Software Product Identification Mode *(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1; *(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2; *(base_addr + FLASH_SEQ_ADD1) = ID_OUT_CODE; /* If both manufacturer and device codes corresponds if ( flash_pt-flash_id = device_code ) & ( flash_pt-flash_manuf_id = manuf_code ) exit = TRUE ; else /* Next Flash, If end of table if ( +flash_pt = FlashTable + NB_FLASH_SUPPORTED ) /* Return 0, Display Error and Exit loop flash_pt = (const FlashDef *)0 ; LCD_printf16 ( &manuf_code,7,1 );/device_code exit = TRUE ; return ( flash_pt ) ; 当上述程序所得结果是 00C0H(AT49BV1614 代码)时,才可以对FLASH进行擦除或编程。 在对 Flash 编程之前,应对 Flash 进行擦除,使其每个数据位都恢复为 1 状态,即全 FF 状态。对 Flash 的擦除操作需要 6 个总线周期。下面是简要的程序代码: int erase_sector ( flash_word *base_addr,flash_word *sector_addr, int size,int sector_id ) int trial = 0 ; /* While flash is not erased or too much erasing performed while ( check_sector_erased ( sector_addr, size, sector_id ) = FALSE ) & ( trial+ NB_TRIAL_ERASE ) / printf ( Erasing Sector %dn, sector_id ) ; *(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1; *(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2; *(base_addr + FLASH_SEQ_ADD1) = ERASE_SECTOR_CODE1; *(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1; *(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2; *sector_addr = ERASE_SECTOR_CODE2 ; if ( wait_flash_ready ( sector_addr,(flash_word)0xFFFF ) = FALSE ) LCD_printf16 ( Timeout while erasingn,4,1 ) ; return ( TRUE ) ; 程序擦除完毕后,就可以对 FLASH 进行编程了。时序遵循表2,以下是其源代码。 int write_flash ( flash_word *base_addr, flash_word *load_addr, flash_word data ) flash_word read_data ; *(base_addr + FLASH_SEQ_ADD1) = FLASH_CODE1 ; *(base_addr + FLASH_SEQ_ADD2) = FLASH_CODE2 ; *(base_addr + FLASH_SEQ_ADD1) = WRITE_CODE ; *load_addr = data ; if ( wait_flash_ready ( load_addr, data ) != TRUE ) LCD_printf16 ( Timeout while programmingn,7,1 ) ; return ( FALSE ) ; if ( read_data = *load_addr ) != data ) LCD_printf16 ( Program Errorn ,7,10) ; / printf ( Address 0x%08x / Data 0x%04x / 0x%04x n, / (int)load_addr, data, read_data ) ; return ( FALSE ); return ( TRUE ) ; 1.2 系统接口 1.2.1 JTAG 接口 JTAG(Joint Test Action Group)是 1985 年制定的检测 PCB和 IC 芯片的一个标准,1990 年被修改后成为 IEEE 的一个标准,即IEEE1149.1-1999。通过这个标准,可对具有 JTAG 口芯片的硬件电路进行边界扫描和故障检测,JTAG 连接图如图 3.2。 具有JTAG 口的芯片都有如下 JTAG 引脚定义: TCK测试时钟输入; TDI测试数据输入,数据通过TDI 输入JTAG; TDO测试数据输出,数据通过TDO 从JTAG口输出; TMS测试模式选择,TMS用来设置 JTAG 口处于某种特定的测试模式; 可选引脚TSRT 测试复位,输入引脚,低电平有效。图1.2 JTAG 连接图JTAG仿真器比较便宜,连接比较方便。它可以通过现有的 JTAG边界扫描与 ARM CPU 核进行通信,属于完全非插入式(不占用片上资源)调试。它无需目标存储器,不占用目标系统的任何端口,而这些是普通的驻留监控软件所必需的。另外,JTAG 调试的目标程序是目标板上执行,仿真更接近于目标硬件,因此,仿真结果与真实的运行环境更为接近,所以逐渐成为目前采用最多的一种调试方式。1.2.2 USART 接口 目前 RS232 是 PC 机与通信工业中应用最广泛的一种串行接口。RS232被定义为一种在低速率串行通信中增加通信距离的单端标准。RS-232 遵循S-232-C标准,美国电子工业协会(Electronic Industries Association,EIA)把RS-232-C定义为:“在数据终端设备和数据通信设备之间使用串行二进制数据交换的接口”。RS-232-C 通信端口一般包括 UART、EIA 驱动程序接口程序。在实际应用中,利用RS232C的通信通常只使用其中的3根线,即RXD、TXD和 GND。 AT91M55800A 微控制器集成了三个完全相同的全双工通用同步/异步收发器(USART)。每个USART都具有自己的波特率发生器和两个专用的数据控制器 PDC 通道。USART 接到 APB 并与外围数据控制器PDC连接。数据格式包括 1个起始位、高达8 个数据位,1个可选的可编程奇偶位,以及最多 2 个停止位。此外,每个 USART 还具有接收超时寄存器,在带 PDC 工作时方便了可变长度数据帧的接收;还有1 个时间确保寄存器以方便与慢速远端设备的连接。USART的主要特点为: 可编程的波特率发生器。 奇偶、帧和过速检测。 线上 Break信号的产生和检测。 自动回送,本地环路和远程环路模式。 多机模式:地址检测和产生。 中断产生。 两个 PDC通道。 5,6,7,8和9位字符长度。 串行口USART的结构如图 1.3所示:图1.3 USART方框图每个口具有如表1.3所列的外部信号:表1.3 USART 通道的外部信号名称描述SCKUSART串行时钟可配置为输入或输出;如果选择了外部时钟SCK为输入;如果没有选择外部时钟,且时钟输出使能,则SCK为输出。TXD串行数据发送端,输出。RXD串行数据接收端,输入。开发板上的串行口使用的是 AT91M55800A 上的UART 接口,通过电平转换芯片(如 Max232),把3.3V 的逻辑电平转换为RS232C的逻辑电平,进行传输。词串行接口使用了 RS232C的 3根线进行通信。接口为 D型的 9针阳性的插头,其各个管脚的定义如表 1.4。 表 1.4 RS232管脚定义管脚号定义英文缩写方向2数据接收RXD输入3数据发送TXD输出5地线GND按照上述管脚定义,嵌入式开发板和PC 机的通信电缆可以按照如图 1.4所示的方式连接。图 1.4 嵌入式开发板和PC机的通信1.3 人机交互接口 为了使嵌入式系统具有友好的人机接口,需要给嵌入式系统配置显示装置,LCD 显示器.另外,要进行人机交互,还得有输入装置,使用户可以对嵌入式控制器发出命令,或输入必要的控制参数等。1.3.1 LCD 显示模块 LCD通常有两种方式,一种是带有驱动芯片的 LCD模块,基本上属于半成品,因此,一般选用这样的显示模块。从系统结构来讲,由于显示器模块中已经有显示存储器。现存中的每一个单元对应LCD上的一个点,只要显存中的内容改变,显示结果中的内容改变,显示结果进行刷新。于是便存在两种刷新方式:(1)直接根据系统要求对现存进行修改。这里存在两种情况,一种是只须作局部修改,不需要判断覆盖等问题;另一种是有覆盖问题,计算起来比较复杂,而且每做一点小的屏幕改变就进行刷新,将增加系统负担。(2)专门开辟显示内存,在需要刷新的时候由程序进行显示更新。这样,不但可以减轻总线负荷,而且也比较合理,在有需要的时候进行统一的显示更新,界面可以比较美观,不至于因为无法预料的刷新动作导致显示界面闪烁。采用前后台双重显示缓存的显示模块结构图如图1.5所示:图 1.5 前后台双重显示缓存的显示模块结构1.3.2 键盘模块 键盘是标准的输入设备,嵌入式设备具有强大的功能,所以有能力处理用户所输入的信息,并结合各具特色的嵌入式应用软件,可以将嵌入式控制器的功能发挥至更大。实现键盘有两种方案:一是采用现有的一些芯片实现键盘扫描;在就是用软件实现键盘扫描。作为嵌入式系统设计人员,总是会关心产品成本。目前有很多芯片可以用来实现键盘扫描。键盘扫描的软件实现方法有助于缩减一个系统的重复开发成本,只需要很少的 CPU 开销。嵌入式控制器的功能很强,可以充分利用这一资源。所以,就用矩阵键盘扫描的方法来实现软键盘。矩阵键盘扫描算法如图 1.6。图 1.6 矩阵键盘在初始化阶段,所有的行(输出端口)被强行设置为低电平,在没有任何键按下时,所有的列(输入端口)将读到高电平。任何键的闭合将造成其中的一列变为低电平。为了查看是否有一个键已经被按下,微处理器仅需要查看任一列的值是否变成低电平。一旦微处理器检测到有键被按下,就需要找出是哪一个键。过程很简单,微处理器只需在其中一列上输出一个低电平。如果它在输入端口上发现一个 0 值,该微处理器就知道在所选择行上产生了键的闭合。相反,如果输入端口全是高电平,则被按下的键就不在那一行,微处理器将选择下一行,并重复该过程直到它发现了该行为止。一旦该行被识别出来,则被按下键的具体列可以通过锁定输入端口上唯一的低电位来确定。微处理器执行这些步骤所需要的时间与最小的状态闭合时间相比是非常短的,因此它假设该键在这个时间间隔中将维持按下的状态。例如,当发现某列变为低电平时,此时,微处理器仅在某一行上输出低电平再查看列的状态,如果此时在输入端口上发现了一个0,则就可以断定此行上的键被按下了;反之,如果输入端口上全为1,则就不是这一行上按下了建。根据第一步和第二步中得到的值,便可以得到相应的扫描码。下面是 44键矩阵扫描程序的源代码。按照以上思路,编写键盘扫描函数,如下:U16 GetScanKey() U16 key; U16 i,temp,mask; for(i=0x1;i0x10;i=1) mask=0x0f&(i); at91_pio_write (&PIOB_DESC,mask, PIO_SET_OUT ) ;/*set high */ at91_pio_write (&PIOB_DESC,i, PIO_CLEAR_OUT ) ;/* set low */ key12; return key; 此 函 数 分 四 次 向 I/O 口 送 出 二 进 制 数 据1110,1101,1011,0111,然后依次从 I/O 口中读取数据。每次扫描读到的数据都存放在变量 key中。这样就得到了键盘扫描码 key。可见,key中可以包含44键矩阵的所有的键盘组合。1.3.3 A/D 数据采集 1. CS553X概述图1.7 CS553X 系列 ADC内部结构图CS553X可提供2通道(CS5531/32)或4通道(CS5533/34),它们均包 含 一 个 低 噪声载波稳定可变增益测量放大器(PGIA)(6nV/Hz0.1Hz),可选增益为1X,2X,4X,8X,16X,32X,64X。ADC内部还有一个 4 阶的 调制器,一个数字滤波器,它能提供 10种可供选择的字输出速率:7.5Hz、15Hz、30Hz、60Hz、120Hz、240Hz、480Hz、960Hz、1.92KHz、3.84KHz(XIN4.9152MHz)。图 1.7 中描述了 CS553X 系列 ADC 的结构。在芯片的前端有一个多路复用器、一个但增益的 coarse/fine 电荷输入缓冲器和一个载波稳定可变增益放大器。单增益放大器设计为轨轨信号输入,其共模信号范围为VAVA+,用于模数转换的增益为1X的情况,可变增益放大器用于模数转换的增益被设定为大于 1X的情况。 为减轻ADC 与微处理器(MCU)之间的通讯负担,它还有一个与SPITM和MicrowireTM兼容的三线串行接口,在串行时钟口(SCLK)处有一个施密特触发器。电源配置方案: VA+=+5V; VA-=0V; VD+=+3V to +5V VA+=+2.5V; VA-=-2.5V; VD+=+3V to +5V VA+=+3V; VA-=3V; VD+=+3V 高动态范围、可编程输出速率和灵活的电源模式等特点,使得CS553X系列 ACD成为用于称重仪和过程控制的理想部件。 1寄存器介绍 CS553XADC有一个片内控制器,含有大量用户可访问的寄存器,用以保存偏移量、增益校验结果、指令、数据,设置操作模式。图1.8中是芯片内部寄存器的结构框图。图1.8 CS5531/32/33/34寄存器结构图偏移寄存器(Offset Registers)增益寄存器(Gain Registers):每通道对应一组,用于保存校验结果。寄存器中的内容可以读写,用户可以把数据卸载到外部EEPROM保存,也可以通过改变寄存器中的内容修改偏移量和增益; 配置寄存器(Configuration Registers):用于设置芯片,包括电压、复位、短路模拟输入、参考电压选择、诊断测试位使能等; 通道寄存器(Channel Setup Registers):用于保存预装载转换指令,每个设置寄存器为 32 位,可保存 2 个 16 位的设置转换指令。 在芯片上电后,这些寄存器可以由用户微控制器用转换指令初始化,之后可以根据设置的工作模式进行单次或连续模数转换以及转换器校验。 由于选用的 49152MHz 晶振在启动时有 20ms 的延迟,在启动处理器后应将 ADC的初始化代码延迟20ms。芯片不具有上电复位功能,初始化ADC 必须用软件复位,通过串口发送15个 SYNC1(0xFFh)命令字节1 个 SYNC0(0xFFh)命令字节可复位串口为命令模式。然后在配置寄存器中设置复位系统位(RS),从而复位系统。复位后,系统复位有效位(RV)自动置位,可通过读取该位判断复位是否成功。当系统复位后 RS 位自动归零,ADC 返回到命令模式,等待有效的输入。初始化电压参考模式,根据参考电压VREF和 VREF之间的大小设置寄存器的 VRS 位,然后初始化通道设置寄存器(CSRs)以决定执行校验还是转换,当 CSRs被初始化后,在校验变换器时,用户有三种校验选择: 1)不校验,使用缺省配置; 2)执行系统校验或自校验; 3)上载先前的校验结果到偏移或增益寄存器。 校验用于设置 ADC的转移函数为0 或斜率,ADC复位后,不校验也能够工作并进行测量模拟量,这样转换器将利用芯片的初始值计算输出字,芯片内部电路的原始错误将被保留。 为了转换精度更加精确,偏移和增益校验都应该进行。 3.硬件设计 因为CS5532能够直接处理mv 级的小信号,而且有一个与SPI TM和Microwire TM 兼容的三线串行接口,因此与AT91M55800A的接口非常简单,如图1.9所示:图1.9 CS5532使用原理图ARM 微处理器的 I/O 口控制 CS;SDI、SDO 来写入和读出数据;HS0.1提供时钟信号。电源方案选择 VA+5V,VA5V,VREF2.5V,VREF-=0V。 1.4 小结本节主要讲述了嵌入式数字温度计的硬件实现。介绍了 FLASH(AT49BV1614),SRAM(ISSI25616),JTAG,USART,LCD(SED1335),键盘等,并给出了相应的原理图和部分源代码。二、嵌入式数字温度计的软件实现2.1 启动代码(Bootloader) 基于ARM是复杂的片上系统(SoC),这种复杂系统里的多数硬件模块都是可配置的,需要由软件来设置其需要的工作状态。因此在用户的应用程序启动之前,需要有专门的一段启动代码来完成对系统的初始化。由于这类代码直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言写的。启动代码就是完成各种初始化工作,并引导进入 C程序。 启动代码一般随具体的目标系统和开发系统有所区别,通常包括以下部分: 定义入口点 设置中断/异常向量 初始化存储系统(包括地址重映射) 初始化堆栈指针寄存器 初始化中断中用到的变量 开中断 必要时改变处理器的模式 必要时改变处理器的状态 初始化C程序用到的存储区 进入 C程序 1中断向量表 ARM 中断向量表必须放置在从 0 地址开始,连续 84 字节的空间内。每当有中断或者异常发生的时候,PC就会跳转到020H 之间相应的地址去取程序代码执行。AT91M55800A 中断向量表如图2.1 所示。图 2.1 中断向量表2初始化存储系统 ARM具有非常灵活的存储器地址分配特性,就是启动ROM的地址重映射(remap)。系统在上电之后,紧接着就从地址0开始取得第一条指令的代码执行,所以地址0必须在上电的时候就存在可执行的正确代码,也就是地址0的地方应该是ROM区,至少在上电之后的一小段时间内应该是ROM区。对于ARM 而言,中断和异常的入口地址是020H。但是因为ROM的访问速度相对较慢,每次中断发生后,都要从读取ROM上面的向量表开始,影响了中断速度。因此,ARM处理器提供一种非常灵活的地址重映射方法,把0地址重新指向到RAM中去,即启动地址重映射(remap)。 为保证重映射之后提供正确的中断入口地址,在重映射之前就必须把中断和异常向量表拷贝到内部RAM中。其程序实现如下: mov r8,#RAM_BASE_BOOT/RAM_BASE_BOOT 是重映射前内部RAM区地址add r9, pc,#-(8+.-VectorTable) /VectorTale是异常向量表入口 ldmia r9!, r0-r7 /读 8 个异常向量 stmia r8!, r0-r7 /保存 8 个异常向量到 RAM区 ldmia r9!, r0-r4 /读 5 个异常处理程序绝对地址 stmia r8!, r0-r4 /保存 5 个异常处理程序绝对地址到RAM区 AT91M55800A 提供了一个 REMAP 命令来实现重映射。上电复位的时候,0 地址的地方映射到 NCS0 所接的外围器件,内部 RAM映射到0x300000处。当把 EBI 的重映射控制寄存器的重映射命令位(EBI_RCR的RCB 位)置1之后,内部RAM就映射到 0的位置,NCS0 所接的外围器件映射到 0x01000000 处。如果这个时候中断和异常向量表已经被复制了,则上电复位的一段时间内,CPU 可以在0 地址取到可执行的有效的指令代码,然后在应用程序执行时能够以更快的速度响应中断和异常,并且可以通过指令的执行动态地进行改动。程序实现为: sub r10, pc,#(8+.-InitTableEBI) /InitTableEBI 是片选寄存器和重映射寄存器入口 ldr r12, PtInitRemap /PtInitRemap 是重映射后跳转地址 ldmia r10!, r0-r9,r11 /加载片选寄存器和重映射寄存器 stmia r11!, r0-r9 /进行重映射并进行寄存器配置 mov pc, r12 /跳转并停止流水线 DCD InitRemap /重映射之后跳转目的地址 InitRemap 进行重映射之后地址分配如图 2.2和图2.3 所示。图2.2 重映射之后地址分配图2.3 重映射之后地址映射3 初始化堆栈、中断寄存器ARM 处理器具有 7 种处理器模式:用户模式、FIQ 模式、IRQ模式、管理模式、中止模式、未定义模式和系统模式。除用户模式外的其他模式称为特权模式。特权模式是为了响应中断或异常,或访问系统保护的资源。特权模式可以自由地访问系统资源和改变模式。 每一种模式都有独立的堆栈指针寄存器(SP),因此对使用到的模式都要定义堆栈地址给堆栈指针寄存器 SP。改变状态寄存器(CPSR)内的状态位,使处理器切换到不同模式,然后给 SP赋值,就可以实现堆栈的初始化。堆栈的大小根据需要而定。例如 FIQ 模式堆栈的初始化程序如下: ldr r0, =TOP_EXCEPTION_STACK /设置栈顶 msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /切换到 FIQ mov r13, r0 /进行堆栈初始化 sub r0, r0, #FIQ_STACK_SIZE /得到栈底地址 4 初始化中断寄存器图2.4 初始化中断寄存器AT91M55800A 内部有一个 8 优先级、可单独屏蔽的向量中断控制器,称为先进中断控制器 AIC(Advanced Interrupt Controller)。AIC采用硬件中断向量化。硬件中断向量化使中断处理入口所需的指令 减少到只有一条。当产生中断时,中断处理例程必须尽快读取中断向量寄存器 AIC_IRQ 的值。中断向量寄存器 AIC_IRQ 里存放当前中断所对应的中断源向量寄存器 AIC_SVR的值。每个中断源都有自己的中断源向量寄存器 AIC_SVR。所以,在系统初始化时,必须将各个中断处理入口地址保存到对应的中断源向量寄存器 AIC_SVR之中。如图 2.4所示。 5 初始化存储区并进入 C 主程序 存储区的初始化主要是将 ROM 里带初始值的变量拷贝到 RAM中,接着就对只定义了变量名的全局变量进行零初始化操作。这样,当所有的系统初始化工作完成以后,就可以进入主应用程序。IMPORT main ldr r0, =main bx r0 END AT91M55800A把外部复位信号作为一个中断来处理,在系统上电复位的瞬间,程序就按以上顺序开始运行。2.2 uC/OSII 实时操作系统在 AT91M55800A 微处理器上的移植 所谓移植,就是使一个实时内核能在其他的微处理器或微控制器上运行。因为大部分 UC/OS-II 的代码是用 C 语言编写的,因此uC/OS-II 的可移植性强。然而,仍需要 C 语言和汇编语言编写一些与处理器硬件相关的代码,这是因为实现 UC/OS-II 读/写处理器寄存器时只能通过汇编语言来实现。 要移植 uCOSII,处理器必须满足以下要求: 处理器的C 编译器能产生可重入代码。 用C 语言就可以打开和关闭中断。 处理器支持中断,并且能产生定时中断。 处理器支持能够容纳一定量数据的硬件堆栈。 处理器有将堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。 AT91M55800A 满足以上条件,可以进行 uCOSII 的移植。而且Embest IDE for ARM 编译器支持C 语言和汇编语言开发,所以在此编译器的基础上进行了 uCOSII的移植。图2.5 uCOSII硬件和软件体系结构图2.5 中说明了uCOSII的结构以及它与硬件的关系。应用程序处于整个系统的顶层,每个任务都可以认为自己独占了CPU,因而可以设计成为一个无限的循环。uCOSII 处理器无关的代码提供了 uCOSII的体系服务,应用程序可以使用这些函数进行内存管理、任务间通信及创建、删除任务等。 移植工作包括以下几个内容: 设置处理器与编译器的相关代码(OS_CPU.H); (1) 数据类型(与编译器有关): 在不同的处理器中有不同的字长,所以必须定义一系列数据类型以确保一致的正确性。另外,在 uCOSII 中,不适用 C 的short,int 和 long 等数据类型,这些都是和编译器相关的。所以定义了如下数据类型。typedef unsigned char BOOLEAN; typedef unsigned char INT8U; /*无符号 8 位整数*/ typedef signed char INT8S; /*有符号 8 位整数*/ typedef unsigned short INT16U; /*无符号16位整数*/ typedef signed short INT16S; /*有符号 16位整数*/ typedef unsigned long INT32U; /*无符号 32位整数*/ typedef signed long INT32S; /*有符号 32位整数*/ typedef float FP32; /*单精度浮点数*/ typedef double FP64; /*双精度浮点数*/ typedef unsigned int OS_STK; /*堆栈入口宽度为16位 */(2) 与处理器相关的代码 uCOSII 需要先禁止中断访问代码的临界区,并且在访问完毕后重新允许中断。uCOSII 定义了两个宏来禁止和允许中断。 #define OS_ENTER_CRITICAL() ARMDisableInt() /*关闭中断*/ #define OS_EXIT_CRITICAL() ARMEnableInt() /*开启中断*/ #define OS_STK_GROWTH 1 /*堆栈由高地址向低地址增长*/ ARMDisableInt: mrs r12, CPSR /* 得到当前 CPU模式 */ orr r12, r12, #I_BIT /* 设置中断禁止位 */ msr CPSR_c, r12 bx lr ARMEnableInt: mrs r12, CPSR /* 将当前模式存入R12 */ bic r12, r12, #I_BIT /* 使能中断 */ msr CPSR_c, r12 bx lr 用 C语言编写六个操作系统相关的函数(OS_CPU.C); ( 1 ) void *OSTaskStkInit (void (*task)(void *pd),void *pdata,void *ptos,INT16U opt) 该函数对任务堆栈进行初始化,被 OSTaskCreate()函数和OSTaskCreateExt()函数所调用。该任务返回任务堆栈初始化后的指针值。程序如下: void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt) unsigned int *stk ; opt= opt; /* 因为“opt”变量没有用,防止编译器产生警告 */ stk= (unsigned int *)ptos; /* 装载堆栈指针*/ /* 为新任务建立上下文*/ *-stk = (unsigned int)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年计算机业务考试题及答案
- 2025年金融监管常识题库及答案
- 拆除工程中的土建工程配合方案
- 2025年河南会考信息真题及答案
- 2025海南事业编职测资料分析卷
- 担保合同(质押担保物权登记版)
- 2025年皮革、毛皮、羽绒制品项目建议书
- 2025年抗滴虫病药合作协议书
- 2025年脲醛塑料项目发展计划
- 2025年诺基亚面试题目及答案
- GB/T 19494.2-2023煤炭机械化采样第2部分:煤样的制备
- 《莫言最全介绍》课件
- 政务信息写作(方法大全-案例详实-个人心得)
- Unit 3 Extended reading 课件 高中英语牛津译林版(2020)选修第一册
- 边坡稳定性计算书
- 设施蔬菜优质高效栽培技术课件
- 中国现代文学史8巴金课件
- 2022年三级中医医院评审标准
- 专家咨询费发放表模板
- 无可逆永久吸味剂原理及应用
- 信号与系统课件10-采样定理
评论
0/150
提交评论