1、2012.4.24基于SOPC的SD卡读写及uClinux操作系统移植摘要随着微电子技术的迅猛发展, FPGA产品的逻辑单元越来越多,性能越来越高,单位成本和功耗向越来越低的方向发展,使得可编程片上系统SOPC(System On Programmable Chip)设计成为必然趋势。美国Altera公司开发的基于SOPC技术的Nios II 嵌入式处理器,使设计者可以非常方便地使用SOPC Builder系统开发工具设计构造以处理器为基础的系统,针对自己的要求配置Nios II软核、Avalon总线及外围接口系统。应用与Nios II相关的集成开发平台和辅助开发工具,加快了Nios系统的设计
2、与验证环节的开发速度,对于嵌入式系统的产品开发和应用,具有广泛的价值和积极的意义。本文从软件和硬件两方面实现了SOPC 系统开发过程的相关模块。系统硬件控制平台的研究主要包括:基于NiosII 软核处理器的SOPC 系统模块的结构,具体系统模块主要包括CPU、SDRAM、UART、定时器及SD相关接口等,同时还包括片外模块,主要有SDRAM_PLL模块和延时模块;系统软件运行平台的研究主要包括:SD卡读写的驱动程序,在SD卡上进行的FAT32文件系统的构建,以及相关的中断控制函数,用于对SD卡中文件进行读写、选择确认等操作,同时还包括了uClinux 操作系统的移植,以及在uClinux操作系
3、统下简单的程序测试。关键字:SOPC;SD卡;uClinux; Abstract Electronic systems integration is increasing of Integrated circuit components with the Bureau of the rapid development of microelectronic technology,The rapid development of microdlectronic technology and the high integration IC,makes the chip more complexity
4、 with lower cost ever than befor.While FPGA is being developed in the direction which contents more and more logic elements,whth high performance,low cost and low power.So,SOPC technology becomes all inevitable trend.The Card SD with small size hiigh storage capacity.rewritable,low prices,as well as
5、 non-volatile and other characteristics have been widely used in mobile phones,digital cameras,MP3 players and other fields.Nios II microprocessor which is developed by Altera inc.based on SOPC technology is is a variable structure,the generalpurpose 32一bit RISC embedded processors.Designers Can eas
6、ily use SOPC Builde system development tool designed to construct processor-basedSystems,its own request for Nios II soft-core configuration,Avalon and the external bus interface system.Reflects the user-oriented,technology-oriented applications SOPC design,application and related Nios II integrated
7、 development platform for development tools and support to speed up the Nios system design and verification aspects of the development speed for embedded systems product development And the application of a wide range of values and positive.In this paper,particularly introduces a hardwaresoftware me
8、thodology which is based O Nios II,aombined with the characteristics of the experimental platform of resources,Construction on the Nios II softcore processor SD card operating system to read and write,achieves the operation of the SD card reading and writingKey Words:SOPC;SD Card;uClinux;目 录第1章 绪 论
9、. . . . . . . . . . . . . . . . . . . . . . . . . .11.1 课题研究背景1.2 论文的组织结构第2章 系统硬件设计部分. . . . . . . . . . . . . . . . . . . . . .2第一章 绪论1.1 SOPC系统介绍1.1.1 SOPC的概念SOC的设计以IP核为基础,以分层次的硬件描述语言为系统功能和结构的主要描述手段,并需要借助EAD工具。SOC从整个系统的角度出发,把处理机制、模型算法、芯片结构直到器件的设计紧密结合起来,在单个(或少数几个)芯片上实现整个系统的功能。1.1.2 与ASIC的SOC解决方案相比,
10、SOPC系统及其开发技术具有更多的特色和构成途径,目前SOPC系统有三种实现途径:(1) 基于FPGA嵌入口硬核的SOPC系统基于FPGA嵌入IP硬核的SOPC系统是指在FPGA中预先植入处理器。目前最常用的嵌入式处理器大多是采用ARM32位知识产权处理器的器件。为了达到通用性,必须为常规的嵌入式处理器集成诸多通用和专用的接口,但这样无疑会增加芯片的成本和功耗。将ARM或其它处理器以硬核的方式植入到FPGA中,利用FPGA的可编程逻辑资源,按照系统功能需求来添加接口功能模块,既能实现目标系统功能,又能降低系统的成本和功耗。这样FPGA灵活的硬件设计与处理器的强大软件功能有机的结合在一起,高效的
11、实现SOPC系统。(2) 基于FPGA嵌入IP软核的SOPC系统目前采用嵌入软核的SOPC系统最有代表性的软核处理器就是Altera公司的Nios II核、Xilinx公司的MicroBlaze核。尤其是Nios核,具有更高性价比,用户可根据设计要求,利用Ouartus II和SOPC Builder,对Nios II及其外围系统进行构建,使该嵌入式系统在硬件结构、功能特点、资源占用等方面全面满足用户系统设计的要求。只要FPGA的资源允许,Nios核在同一FPGA中被植入的数量没有限制;此外,可植入Nios核的Altera FPGA的系列几乎没有限制。采用嵌入IP软核的SOPC系统成功的解决了
12、将IP硬核直接嵌入FPGA所带来的不因知识产权费用导致器件价格的偏高;硬核的预先植入致使处理器结构的不可更改;无法通过裁减处理器硬件资源来降低成本;只有在特定的FPGA中使用硬核嵌入式系统等等。(3)基于HardCopy技术的SOPC系统通过强化SOPC工具的设计能力,在保持FPGA开发优势的前提下,引入ASIC的开发流程,从面对ASIC市场形成直接竞争,这就是Altera公司推出的HardCopy技术。HardCopy就是利用原有的FPGA开发工具,将成功实现于FPGA上的SOPC系统通过特定的技术直接向ASIC转化,HardCopy技术是一种全新的SOC级ASIC设计解决方案,即是将专用的
13、硅片设计和FPGA向专用集成电路自动迁移过程结合在一起的技术。首先利用Quartus II将系统模型成功实现于HardCopy FPAG上,然后帮助设计者把可编程解决方案无缝地迁移到低成本的ASIC上。这样HardCopy技术就把大容量FPGA的灵活性和ASIC的市场优势结合起来,实现对于有较大批量需求并对成本敏感的电子产品上,从而避开了直接设计ASIC的复杂,解决了传统ASIC设计中普遍存在的开发周期长、开发流程复杂、产品上市慢、一次性成功率低、设计软件工具繁多且昂贵等问题。(4)三种SOC方案的比较 表 1.1 三种方案比较 指标 基于ASICR的SOC 基于FPGA的SOC 基于Hard
14、Copy的SOC单片成本 低 较高 较低开发周期 长(20周) 短(10周) 较短(20周)开发成本 设计工程成本高 设计工程成本低 设计工程成本低 掩膜成本高 无掩膜 掩膜成本低 软件工具成本高 软件工具成本低 软件工具成本低一次投片情况 一次投片成功率低 可现场配置 一次投片成功率高集成技术 0.25um90um 0.25um90um 0.25um90um可重构性 不可重构 可重构 不可重构 1.1.3 掌握SOPC技术所需的基本技能基于SOPC的结构特点,SOPC系统开发对于设计者的知识范围有了更高的要求。除了必须了解基本的EDA软件,硬件描述语言和FPGA器件相关知识外,还必须熟悉计算
15、机组成与接口,汇编语言和C语言,DSP算法,数字通信,嵌入式系统开发,嵌入式操作系统,片上系统构建与测试等知识。1.2研究的目的与意义Altera公司开发的Nios II是基于SOPC技术的32位嵌入式处理器软核。与同类型产品相比,更能体现SOPC技术思想。其作为一种新技术,在国外已经有了比较广泛的应用,但是在国内使用Nios II处理器进行嵌入式设计的开发者很少,还处于起步阶段,没有得到广泛的关注和大规模应用,对于Nios II应用开发和研究还有大量工作需要我们去做。本课题从新技术学习应用和实验开发的角度入手,自主完成系统的硬件设计,在此硬件平台上从事基于Nios II的SOPC技术的研究与
16、应用,进行操作系统的移植,熟练掌握了其工作原理和系统知识,并在此基础上设计了基于Nios II的SD卡的读写驱动实现,通过具体的应用,论述其实用性及优势所在,这正是本课题的目的和论文的写作意义所在。1.3论文组织结构根据课题的任务要求,本文内容作如下安排:第一章: 介绍嵌入式SOPC相关概念及本论文研究的目的及意义;第二章: 介绍了与本实验相关的一些概念,主要包括SD卡的介绍、FAT32文件系统的介绍以及uCLinux操作系统的介绍等。第三章: 本章主要是系统的硬件设计部分,主要包括NiosII 软核处理器模块、SDRAM_PLL模块、延时等模块的介绍,以及它们之间的构建结构。第四章: 系统软
17、件方面的介绍。主要包括SD卡读写实验的相关介绍和uClinux操作系统移植两部分。第五章: 本实验的测试部分,包括SD卡读写测试和操作系统移植测试两部分。第二章 基本概念介绍2.1 SD卡介绍2.1.1 SD卡简介SD卡是基于flash的存储卡,SD卡的通信协议包括SD和SPI两类。SPI模式下,主机使用SPI总线访问卡。当今大部分微处理器本身都带有硬件SPI接口,使用微处理器的SPI接口访问SD卡很方便。微处理器在卡上电后的第一个复位命令就可以设置SPI模式,但在卡上电期间,其通信模式不能改为SD模式。2.1.2 SD卡特征 SD卡的形状如图2.1所示,引脚如表2.1所示。 图2.1 SD卡
18、形状 表2.1 SD卡的引脚定义 引脚 名称 类型 描述1 CD/DAT3 I/O/PP 卡的检查/数据线位32 CMD PP 命令/响应3 Vss1 S 电源地4 VDD S 电源5 CLK I 时钟6 Vss2 S 电源地7 DAT0 I/O/PP 数据线位08 DAT1 I/O/PP 数据线位19 DAT2 I/O/PP 数据线位2 SD卡设备总体架构,如图2.2: 图2.2 SD卡设备总体架构图2.2 FAT文件系统介绍2.2.1 文件系统简介文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。Windows 系列操作系统对磁盘文件的管理主要有FAT
19、 类文件系统和NTFS 文件系统两大类。FAT32 文件系统是微软FAT 类文件系统中的最高版本,是现今WINDOWS 下最常用的硬盘文件系统。2.2.2 磁盘空间的划分对于使用FAT32 文件系统的每个逻辑盘内部空间又可划分为三部分,依次是引导区(BOOT 区) 、文件分配表区(FAT 区) 、数据区(DA2TA 区) 。引导区和文件分配表区又合称为系统区,占据整个逻辑盘前端很小的空间,存放有关管理信息。数据区才是逻辑盘用来存放文件内容的。该区域以簇为分配单位来使用。2.2.3 FAT16 和FAT32比较 表2.2 FAT16、FAT32一簇的大小(扇区数/字节数) 卷容量(粗略值) FA
20、T16 FAT32 128M255M 4KB 4KB 266M511M 8KB 4KB 512M1023M 16KB 4KB 1G2G 32KB 4KB 2G8G 不采用 4KB 8G16G 不采用 8KB 1632G 不采用 16KB 32G以上 不采用 32KB2.3 uClinux相关介绍uclinux表示micro-control linux.即“微控制器领域中的Linux系统”,是Lineo公司的主打产品,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标处理器没有存储管理单元MMU(Memory Management Unit)的嵌入式系统而设计的。它已经被
21、成功地移植到了很多平台上。由于没有MMU,其多任务的实现需要一定技巧。2.3.1 uClinux的内核加载方式uClinux内核有两种可选的运行方式:可以在flash上直接运行,也可以加载到内存中运行。把内核的压缩文件存放在flash上,系统启动时读取压缩文件在内存里解压,然后开始执行,这种方式相对复杂一些,但是运行速度可能更快。2.3.2 Clinux 的文件系统uClinux 系统采用ROMFS 文件系统,这种文件系统相对于一般的ext2 文件系统要求更少的空间。空间的节约来自于两个方面:首先内核支持ROMFS 文件系统比支持ext2 文件系统需要更少的代码;其次ROMFS 文件系统相对简
22、单,在建立文件系统超级块(superblock 需要更少的存储空间)。ROMFS 文件系统不支持动态擦写保存,对于系统需要动态保存的数据采用虚拟RAM 盘的方法进行处理(RAM 盘将采用ext2 文件系统)。2.3.2 存储器保护没有存储器保护,显然,在这样的系统上运行的代码必须仔细编程,并深入测试来确保健壮性和安全。对于嵌入式Clinux 系统而言,由于要运行的程序往往在出厂前已经固化,不存在危害系统安全的程序侵入的隐患,因此只要应用程序经过较完整的测试,仍可以控制出现问题的概率。第三章 系统硬件结构设计3.1 基于SOPC的系统硬件的实现3.1.1 NiosII 软件核处理器及控制模块利用
23、Quartus II 9.0 和SOPC Builder9.0 创建NiosII 嵌入式系统模块,具体步骤如下:(1)创建CPU。在SOPC Builder中,设置时钟频率为50MHz。然后添加CPU,选择标准处理器内核,这里给我们提供了三种类型的软核:Nios II/e占用资源最少,600-800LEs,功能也最简单,速度最慢;Nios II/s占资源比前者多一些,功能也多了,速度也快一些;Nios II/f占资源最多,功能也最多,速度最快。选择的时候要根据需求和芯片资源来决定。在这里,由于移植uClinux操作系统,CPU要求为Nios II/f,所以本设计选用Nios II/f类型,功能
24、和速度都可以得到满足。图3.1中的Reset Vector是复位后启动时的Memory类型和偏移量, Exception Vector是异常情况时的Memory类型和偏移量,需要SDRAM设置好以后才能修改,之后Reset Vector和 Exception Vector都设为SDRAM。接下来指令Cache 设置为4Kbytes,数据Cache 设置为None。在选择JTAG 调试模块时,选择level 1。 图3.1 CPU的配置(2)添加SDRAM。8Mbytes的SDRAM:数据宽度16Bits,1 个片选,4个Bank,地址为ROW=12,COLUM=8,CAS latency cy
25、cles :选为3。如图3.2: 图3.2 SDRAM的配置(3)添加sysid。SystemID peripheral,即系统标识,类似校验和,它是SOPC中的一个简单只读组件,Nios II处理器系统利用它来检验软件程序和配置与FPGA中的硬件电路是否一致。当在下载程序之前或者重启之后,都会对它进行检验,以防止Quartus和NIOS程序版本不一致的错误发生。(4)添加jtag_uart。jtag_uart即JTAG通用异步通信总线,用于实现PC和Nios II系统间的串行通信接口,Altera的JTAG UART核具Avalon总线接口,也用于NiosII系统的仿真调试,它用于字符的输入
26、输出,在Nios II的开发调试过程中扮演了重要的角色。这里我们采用默认配置,如图3.3: 图3.3(5)添加SD卡控制线。SD卡有两种模式:SD模式和SPI模式,开发板上的读写方式为SPI方式,共需4根线:sd_dat 、sd_dat3、sd_clk,、sd_cmd,分别对应SPI总线的MISO、MOSI 、SCK 、CS 4根线。其中sd_dat为PIO输入,其余三根为PIO输出,此设计采用模拟SPI时序进行读写SD卡。如图3.4: 图3.4(6)添加Character LCD控制模块。本设计采用的是 1602字符设备,添加字符设备IP核可以轻松实现对LCD的显示。同时添加两个PIO核:l
27、cd_on和lcd_blon,都设为1位输出模式,分别用于控制液晶的开关以及背光显示。如图3.5: 图3.5 (7)添加三个按键中断。read_pio_irq、return_pio_irq以及select_pio_irq,都设为1位PIO输入模式,设置为上升沿捕获来产生中断,分别实现读、返回、选择操作,由此触发中断实现相对应的功能。配置如图3.6: 图3.6(8)添加一个full-features的timer。此定时器设置为32位full-features,时间溢出为1ms。之所以选择full-features,是因为由 *.ptf文件编译生成内核镜像文件zImage时,需要一个full-fe
28、atures的timer,否则会报错。配置如图3.7: 图3.7(9)添加UART(RS232控制器):目的是为了在超级终端显示uClinux文件系统命令。配置如图3.8: 图3.8其余设置:SOPC Builder的系统模块添加完成以后,还需要完成以下几个工作:1. 自动分配基地址:这样做是为了不浪费空间;2. 自动分配IRQ,之所以要自动分配一下,是因为这个软件还不够智能,当模块建好以后,有出现重复中断号的现象,编译的过程就会出现错误;3. 定义处理器启动地址:把SDRAM定义为处理器启动地址和异常向量地址。完整的NiosII 系统配置及其地址映射如图3.9所示: 图3.9由图可以看到:中
29、断号是从小到大顺序排列的,没有重复。特别注意:中断号0是分配给定时器timer的,除了定时器外,不要把中断号0分配给任何其他器件。接下来,就要根据已产生的*.ptf文件来“Generate”生成系统模块原理图。注:*.ptf文件是系统实时生成的,系统的ptf文件类似于一个数据库文件, 它定义了SOPC Builder 生成完整系统必需的详细信息,该文件存储Nios II 系统的硬件内容,NiosII IDE 要使用该文件信息来为目标硬件编译软件程序。另外,该文件也是用于生成uClinux内核镜像zImage的文件。由此产生系统模块原理图如图3.10: 图3.10在产生NiosII 系统模块后,
30、需要设计几个模块来使CPU 正常运行,包括SDRAM_PLL 模块,Reset_Delay 模块。3.1.2 SDRAM_PLL模块必须保证CPU与SDRAM时钟频率相同,由于SDRAM与CPU之间的数据传输会有缓冲,所以必须配置好SDRAM的相移,否则无法正常工作。SDRAM_PLL模块是由MegaWizard 通过MegaCore 产生的代码,它产生有三个时钟,一个输入时钟,接在外面的50MHz晶振上,c0 产生CPU所需要的50MHz时钟,c1产生频率为50MHz 相位延迟为-75 度的时钟,提供给SDRAM使用。该模块如图3.11所示: 图3.113.1.3 Reset_Delays
31、模块Reset_Delays 模块主要起延缓reset 时间的作用。该模块设计如图3.12: 图3.12当所有模块都设计好了之后,接下来就要进行管脚的分配,这里我们采用开发饭自带的*.tcl文件进行管脚分配,需要注意的是,由于开发板没有复位按键,且系统模块中的RESET引脚必须管脚(否则无法工作),所以我们将系统模块的复位按键设为KEY0按键。其完整的顶层硬件设计如图3.13: 图3.13管脚分配成功后,需确定管脚分配没有问题,如图3.14: 图3.14我们就要进行漫长的编译过程,编译成功后,我们的硬件设计就完成了。最后,我们要将编译生成的*.sof(SDRAM目标文件)下载到开发板中,至此,
32、我们的硬件设计部分及烧写已完成。3.2 小结本章主要实现了系统的硬件平台的搭建,首先了解了SOPC 的设计流程以及NiosII 软核处理器的组成,然后通过SOPC Builder 来创建NiosII 硬件系统,完成了硬件上SPI接口以及其他控制模块的实现。第四章 系统软件设计4.1 软件设计的总体概况头文件及源文件列表,如图4.1: 图4.1各模块的概述如下: /* 通用模块接口头文件 */u integer.h : 对文件系统模块的顶层类型定义 #include #include /*sd卡读写相关函数,提供接口给文件系统使用*/u mmcbb.c : MMCv3/SDv1/SDv2 (SP
33、I模式) 控制模块 #include diskio.h #include “system.h” #include “unistd.h” #include “altera_avalon_pio_regs.h”u diskio.h : 底层磁盘接口模块 #include integer.h /*基本整型类型*/*文件系统相关函数,文件系统接口*/u ff.c : /* FAT文件系统模块 */ #include ff.h /* 文件系统配置和声明*/ #include diskio.h u ff.h : FAT文件系统模块头文件 #include integer.h /* 基本整型类型 */ #i
34、nclude ffconf.h /* 文件系统配置文件选项*/u ffconfig.h : 文件系统模块配置文件 /* 自定义模块 */u f_get_dir_file_list.c : /* 用于显示指定目录下的文件列表 */ #include f_get_dir_file_list.h: /* 对应头文件 */u f_get_dir_file_list.h : /* 头文件 */u f_display_filecontent.c : /* 用于显示文件的内容 */ #include f_display_filecontent.hu f_display_filecontent.h : /*
35、相应的头文件*/u main.c : 主函数 #include system.h #include ff.h #include #include #include string.h #include alt_types.h #include altera_avalon_pio_regs.h #include f_display_filecontent.h #include sys/alt_irq.h #include f_get_dir_file_list.h 本设计主要实现SD卡的读写,文件列表及文件内容显示等。4.2 软件设计的具体介绍4.2.1 通用接口相关头文件 (1)integer.
36、h文件: 此头文件主要是对文件系统模块的顶层类型定义。在嵌入式操作系统中由于不同处理器和不同编译器对诸如 int,long等基本类型的长度不一致,为了增加程序的可移植性,必须明确指定各基本类型的具体长度,此头文件明确了各基本类型的长度,为其他文件提供了通用接口,有利于实现程序的规范化。部分程序如下: typedef long LONG;typedef unsigned long ULONG;typedef unsigned long DWORD;4.2.2 SD卡读写相关函数(1) mmcbb.c: SD卡的底层驱动软件,采用的是SPI模式读写SD卡,主要实现的功能有对SD卡的初始化、读、写、
37、控制等操作,以及一些关于SD卡状态、命令和函数返回状态等结构体的定义,为文件系统函数的调用提供了接口。以下函数是提供给文件系统函数的接口:static BYTE send_cmd ()DSTATUS disk_status ( BYTE drv )DSTATUS disk_initialize (BYTE drv )DRESULT disk_read (BYTE drv,BYTE *buff, DWORD sector,BYTE count)DRESULT disk_write(BYTE drv,const BYTE *buff,DWORD sector,BYTE count) (2) dis
38、kio.h: 底层磁盘接口模块,与mmcbb.c相对应的头文件,同时里面也包含了一些文件系统强制要求命令的宏定义以及磁盘操作函数的返回状态的结构体定义。4.2.3 文件系统相关函数(1) ff.c: 通用的FAT文件系统的相关定义,主要应用于小的嵌入式系统,里面包含了FAT文件系统所需的各种变量以及宏的定义,包含了创建目录、打开文件、重命名、改变属性等文件操作所必须的常用函数,为了在SD卡上应用FAT32文件系统,只需修改和替换本文件中相关的一些函数即可,这些函数定义在mmcbb.c中,通过diskio.h头文件传递到本文件,只需把diskio.h中声明的函数与本文件中相应的函数做个替换即可。
39、 (2) ff.h:FAT文件系统模块头文件,与ff.c源文件相对应,同时里面还定义了一些ff.c文件中需要用到的一些与FAT文件系统相关的结构体和宏定义,如:文件属性和目录属性宏定义、文件访问控制和文件状态标志宏定义、文件函数操作返回状态结构体等。(3) ffconfig.h : FAT文件系统模块配置文件。主要包括函数和缓冲区大小配置、本地和命名空间配置、物理扇区配置和系统配置等。基本不需要修改,根据具体情况可做适当的修改。4.2.4 自定义功能模块(1) f_get_dir_file_list.c: 本程序的主要功能是读取指定目录下的文件列表并显示出来,在主函数中伴随着按键中断而调用。程
40、序的主体如下(有删减):#include f_get_dir_file_list.hstatic void set_ptrarray(char *ptr,UINT *index,const char *s) ptr*index = (char *)malloc(sizeof(s); if(ptr*index!= NULL) strcpy(ptr*index,s);上面函数的功能是:根据已知的字符串(目录的名称),为其动态分配空间并令指针数组中对应的元素指向它。之所以要这么做,是为了节省内存空间。我们知道,嵌入式系统中,各种存储器的空间都很有限,我们要尽量的减小代码运行时所占用的内存空间。若我们
41、定义一个二维数组,其中的每个以为一维数组都用来存储目录,则为了使目录都能存下,则我们一维数组的最小长度应等于目录名最长的长度,这样对于比较短的目录名,势必会浪费许多存储空间,而且最长的目录名我们也不知道。因此,为了节省存储器空间,我们采用动态分配内存的方式来存储目录名,这样既不浪费空间也不必事先知道最长目录名为多少。FRESULT get_dir_file_list(DIR *dir,TCHAR *filname_ptr_array,UINT *dir_count,TCHAR *dirname_ptr_array,UINT *fil_count) *dir_count = 0; *fil_count = 0; . . . . . . rc = f_opendir(dir, ); /打开当前根目录 . . . . . . for (;) rc = f_readdir(dir, &fno); /* Read a directory item */ if (rc | !fno.fname0) break; /* Error or end of dir */