嵌入式处理器MPC8250与CF卡的接口设计
时间:06-22 11:43 阅读:2168次
*温馨提示:点击图片可以放大观看高清大图
简介:从如何设计嵌入式处理器与CF卡之间的接口、如何高效率地编制读写程序出发,介绍了嵌入式处理器与CF卡的接口设计和编程技巧。
最近几年,嵌入式处理器蓬勃发展,在通信、航空航天、医疗设备、消费类电子产品等领域一展身手。嵌入式处理器的外围设备也日新月异,例如记忆棒、USB口、CF卡等。本文从硬件和软件角度出发,介绍了CF卡在嵌入式系统中的设计和使用技巧。 由于CF卡具有携带方便、易于升级、存储量大、抗震性好等优点,应用范围越来越广。1995年10月,SanDisk、柯达、卡西欧、惠普、摩托罗拉、佳能等125家厂商发起成立了CompactFlash协会,致力于制定新一代的基于RAM和ROM技术的固态非易失的存储介质标准——CF卡标准使不同厂家开发的CF卡及其接口器件可以互相兼容。目前,CF卡标准已有1.4版本,容量从最早的2M字节到现今的1G字节。 同时,CF卡遵从ATA-IDE工业设计标准,连接装置与 PCMCIA卡相似,只不过CF卡是50引脚(PCMCIA卡68引脚),可以很容易插入无源68引脚 TypeII适配卡并完全符合PCMCIA电力和机械接口规格。另外,CF卡的兼容性佳,不仅同时支持3.3V和5V的电压,而且不同的CF卡都可以用单一的机构读写,特别是CF卡升级换代时也可以保证旧设备的兼容性。而纯电子运动的CF卡耗电量很低,仅为IBM微型硬盘的5%。
1 系统设计 图1是笔者开发的嵌入式系统框图。其中,嵌入式处理器是MPC8250,PCI1410A是连接PCI总线和CF卡的一种接口芯片。 MPC8250芯片是Motorola公司开发的一款PowerPC系列嵌入式处理器。芯片采用小巧而强大的32位超标量体系结构PowerPC 603e处理器内核,最高主频为300MHz。它集成了PCI桥、PCI仲裁器、存储器控制器、中断控制器、DMA控制器、16K字节指令高速缓存和16K字节数据高速缓存等部件。MPC8250具有三个可配置为百兆或十兆以太网的FCC口,四个可配置为串口或网口的SCC口,一个多通道HDLC接口。该芯片适用于对成本、空间、功耗和性能都有很高要求的应用领域,例如路由器/接线器、多路MODEM、网络存储应用和图像显示等系统。 PCI1410A芯片是TI公司开发的一种高性能的PCI到CF卡的控制器,支持遵循CF卡标准的各类CF卡。它符合PCI总线标准,既可以工作于PCI主设备模式,也可以工作于PCI从设备模式。 MPC8250与PCI1410A之间通过32位PCI局部总线连接,工作频率33MHz。MPC8250用作PCI主设备,PCI1410A用作PCI从设备,同时采用MPC8250内部的PCI仲裁器。 本设计选用SanDisk公司的型号为SDCFB-64-101的CF卡,64M字节容量,几何尺寸为36.4mm%26;#215;42.8mm%26;#215;3mm。PCI1410A与CF卡之间的连接遵循CF卡标准,由地址、数据、控制三组信号组成。PCI1410A提供了五个通用I/O引脚,设计中将其中一个引脚GPIO1用作LED指示。当CF卡工作时,LED会以64ms的周期闪烁。 SDRAM选用了三星公司的K4S561632A,每片容量256M比特,共四片。 图2 读写CF卡技巧示意图 2 接口编程 在CF卡工作前,必须先进行初始化,在整个系统的地址空间中确定CF卡的位置,预设置CF卡的工作模式及相关寄存器。本设计中,CF卡位于系统的0x9A000000~0x9DFFFFFF地址空间。在每次读写CF卡时,必须根据读写数据的多少和操作特性来配置相应寄存器。 2.1 CF卡初始化 本系统中,CF卡的初始化由MPC8250通过PCI总线配置PCI1410A的寄存器实现,具体步骤如下: (1)设置CF卡的基地址,即配置ExCA寄存器(偏移量:0x10)。该寄存器定义了CF卡在PCI存储器空间的基地址,即0x9A000000。 (2)配置PCI命令寄存器(偏移量:0x04),允许CPU访问PCI存储空间。 (3)配置系统控制寄存器(偏移量:0x80)。该寄存器定义了一些系统控制位,例如,是否采用PCI中断方式,是否采用内部振荡器,是否采用DMA等。本设计采用PCI中断方式,不采用内部振荡器和DMA。
(4)配置多功能引脚寄存器(偏移量:0x8C)。该寄存器配置通用引脚。本设计配置GPIO1引脚为LED指示,GPIO2引脚为PCI中断输出。 (5)配置设备控制寄存器(偏移量:0x92)。该寄存器选择中断方式,是并行PCI中断还是串行PCI中断。本设计选择了传统的并行PCI中断方式。 (6)配置ExCA电压控制寄存器(偏移量:0x802),选择Vcc为3.3V还是5V。本设计选择Vcc为3.3V。 (7)配置ExCA存储窗口0起始地址低位寄存器(偏移量:0x810),即起始地址的A19~A12位。PCI1410A具有五个存储地址翻译窗口和二个I/O地址翻译窗口,用于配置CF卡内寄存器的访问地址,将CF卡的寄存器映射到系统的存储空间或I/O空间,MPC8250访问这些寄存器就相当于访问一段存储空间或I/O空间。本设计中只使用了存储地址翻译窗口0。 (8)配置ExCA存储窗口0起始地址高位寄存器(偏移量:0x811),即起始地址的A23~A20位。 (9)配置ExCA存储窗口0结束地址低位寄存器(偏移量:0x812),即结束地址的A19~A12位。 (10)配置ExCA存储窗口0结束地址高位寄存器(偏移量:0x813),即结束地址的A23~A20位。 (11)配置ExCA存储窗口0地址比较寄存器(偏移量:0x840)。在系统访问CF卡时,如果地址的高8位与该寄存器数值相同,则允许访问,系统将该地址翻译到相应的CF卡空间;否则,拒之门外。 (12)配置ExCA存储窗口使能寄存器(偏移量:0x806)。该寄存器可以分别打开或关闭五个存储地址翻译窗口和二个I/O地址翻译窗口,因为每个窗口对应了寄存器中的一个使能位。芯片的默认值都是关闭的。在本设计中,打开存储地址翻译窗口0。切记在初始化的收官阶段打开翻译窗口使能位,以免功亏一篑。 2.2 读写CF卡技巧 由于CF卡本身的特点,CF卡由ATA控制器和Flash存储器两部分构成。系统访问Flash存储器的速度远远小于访问内存的速度。如果系统频繁访问CF卡,势必影响系统的实时性和工作效率。所以必须考虑CF卡读写程序的设计技巧。 根据存储器访问的局部性原理,CPU存取数据所访问的存储单元都趋向于聚集在一个较小的连续区域。从时间上看,如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。从空间上看,在最近将用到的信息很可能与目前正在使用的信息在空间地址上是临近的。 本系统的程序设计中,开辟了一个扇区的内存空间tempSect,用于存储最近访问过的扇区数据;并设置了两个全局变量:SaveSectorNum和SectorDirty。SaveSectorNum保存最近备份的扇区编号。SectorDirty说明备份数据是否与CF卡中的相应数据一致。如果一致,为“0”;否则为“1”。这样不但可以减少读写CF卡的次数,而且提高了访问速度,满足嵌入式操作系统的实时性要求。 同时,CF卡的物理结构也有利于以扇区为单元进行操作。因为CF卡内部的Flash存储器由若干个扇区组成,而且CF卡中设置了专门针对扇区操作的寄存器。 所以,本设计中,无论是读一段数据,还是写一段数据,都以扇区为基本单位。如果数据量在一个扇区内,并且地址范围在同一扇区,则先读取所在扇区的数据,然后按照在扇区中的偏移量获得所需数据;如果数据量大于一个扇区,或者地址范围横跨两个扇区,则按次读取扇区,获得所需数据。操作流程如图2所示。 系统初始化时,设置SaveSectorNum为“0”, tempSect中备份了0号扇区的数据;SectorDirty也为“0”,即备份数据未作更改。 当读取一个扇区的数据时,首先比较所读取的扇区号(CurrSectorNum),是否与备份数据的扇区号(SaveSectorNum)一致,如果一致,则从备份数据中读取,加快了访问速度;否则,判断备份数据是否更改,即SectorDirty是否为“1”;如果不是,则从CF卡中读取扇区号为CurrSectorNum的数据到tempSect中;否则,先把tempSect的数据写回CF卡,然后从CF卡中读取扇区号为CurrSectorNum的数据到tempSect中。最后,设置备份数据扇区号SaveSectorNum为当前数据的扇区号CurrSectorNum,设置SectorDirty为“0”,并从备份数据中读取所需数据。
当写入一个扇区的数据时,首先比较所写入的扇区号(CurrSectorNum),是否与备份数据的扇区号(SaveSectorNum)一致,如果一致,则把数据写入备份数据中,并且设置SectorDirty为“1”;否则,判断备份数据是否更改,即SectorDirty是否为“1”;如果不是,则从CF卡中读取扇区号为CurrSectorNum的数据到tempSect中;否则,先把tempSect的数据写回CF卡,然后从CF卡中读取扇区号为CurrSectorNum的数据到tempSect中。最后,设置备份数据扇区号SaveSectorNum为当前数据的扇区号CurrSectorNum,将指定数据写到备份数据中,并且设置SectorDirty为“1”。 2.3 读写数据的相关寄存器 根据CF卡标准,不能直接访问CF卡的数据区域,而需要通过访问CF卡内的相关寄存器(这些寄存器的基地址在CF卡初始化时配置,见2.1节)间接读取或者写入数据。在访问CF卡时必须对它们进行正确配置: (1)扇区数目寄存器(Sector_CNT Register) 读写操作时,保存需要传送的扇区数目。如果为0,则选择256个扇区;如果操作成功,操作结束时此寄存器为0;如果操作不成功,此寄存器包含了有待完成的扇区数目。 (2)磁头寄存器(Select_HEAD Register) 其中包含了LBA位(1比特),用于设置地址访问方式。“1”LBA_Mode为逻辑地址访问方式,“0”为柱面/磁头/扇区访问方式。本系统选择逻辑地址访问方式,则该寄存器还包含了逻辑地址的24~27位。 (3)扇区编号寄存器(Sector_NUM Register) 在采用逻辑地址访问方式时,该寄存器包含了逻辑地址的0~7位。 (4)柱面低位寄存器(Cylinder_LO Register) 在采用逻辑地址访问方式时,该寄存器包含了逻辑地址的8~15位。 (5)柱面高位寄存器(Cylinder_HI Register) 在采用逻辑地址访问方式时,该寄存器包含了逻辑地址的16~23位。 (6)状态寄存器(Status Register) 反映了CF卡的状态,其中包含了CF卡忙(Busy)位、出错位(Err)、是否准备就绪位(Rdy)等。 (7)数据寄存器(Data Register) 存放读写数据,是一个16位寄存器。 2.4 读数据 从CF卡读取一个扇区的数据,如图3所示。因为系统采用的CF卡的扇区大小为:SectorSize = 512字节,假设读写数据的地址为Addr,则该地址所在的扇区号为: Sector = Addr % SectorSize。 首先配置寄存器,设置读取的扇区数目、相应地址和访问模式;然后发送读命令(0x20),等待CF卡空闲且准备就绪,再从数据寄存器中连续读取一个扇区的数据;完成读取后,等待CF卡空闲;程序返回。 2.5 写数据 将数据写入CF卡的操作与从CF卡读取数据的操作类似,如图4所示。首先配置寄存器,设置写入的扇区数目、相应地址和访问模式;然后发送写命令(0x30),等待CF卡空闲并且处于准备状态,连续向数据寄存器写入一个扇区的数据;完成写入后,等待CF卡空闲,程序返回。 本设计采用的操作系统是μC/OS——一个源代码完全公开的嵌入式操作系统。所有读写CF卡的函数都用C语言编制,并能在系统中有效工作。