## uclinux实验
### 1. 实验内容
通过本实验了解如何建立复杂的NIOS II,如何在Nios II系统运行uClinux操作系统,以及在uClinux操作系统环境上开发简单用户应用程序。
本实验要求利用SOPC建立一复杂的NIOS II,通过NIOS II IDE配置uClinux,实现在uClinux在NIOS II上的运行。
\\
\\
### 2. 实验步骤
#### 2.1 NiosⅡ硬件设置
1. 工程建立:首先在Quartus II新建一个名为uclinux的工程,工程建立之后在工具栏中点击{{ ::图标.png |}}图标,出现SOPC Builder对话框。在System Name对话框里设置Nios系统名nios_cpu,HDL语言选择Verilog,如下图(图22-1)所示。
{{ ::图22-1.png |图22-1 SOPC Builder对话框}}
**图22-1 SOPC Builder对话框**
2. 系统设置:点击【File】→【New Board Description】,出现如下对话框,对目标板进行编辑。在Netlist选项中将Device Family定义为Cyclone II,如下图(图22-2)所示。
{{ ::图22-2.png |图22-2 目标板编辑}}
**图22-2 目标板编辑框**
在Flash Memory对话框中对点击【New Flash Memory】,将Device命名为u10(这个名字是任意自取的,但一定要有),如下图所示。
{{ ::图22-3.png |图22-3 Flash Memory设置}}
**图22-3 Flash Memory设置**
在Files选项里定义Board Description Name为de4(该名字可以任意自取),然后点击Finish,如图22-4所示。
{{ ::图22-4.png |图22-4 目标板名字设置}}
**图22-4 目标板名字设置**
3. 时钟设置:在对目标板设置完毕后,在Target设置栏的下拉菜单中会出现de4选项,选择de4。在clock设置栏中,添加两个External时钟clk和clk_50,分别是100MHz和50MHz。
{{ ::图22-5.png |图22-5 时钟设置}}
**图22-5 时钟设置**
4. SOPC组建添加:
系统中缺省没有网卡和SRAM组件,所以要将光盘中的DM9000A(网卡)和SRAM_16Bit_512K(SRAM)两个文件夹添加到uClinux工程文件夹中,这样就会出现网卡和SRAM组件。
将Avalon Components中的选项中组建添加到自己的工程中,具体方法是将相关的组建拖进右边的对话框中,如图22 6所示。主要有Nios II Processor,Bridges中的Avalon Tristate Bridge,Communication中的Jtag UART和UART,Memory中的onchip_memory, SDRAM controller, Flash Memory,Other里面的Interval timer,PIO。
{{ ::图22-6.png |图22-6 NiosⅡ系统配置}}
**图22-6 NiosⅡ系统配置**
5. SOPC组建设置:将组建添加完后需要对组建进行设置,首先是Flash,双击Module Name中的cfi_flash_0,出现设置对话框,将Address Width设置为25bits,Data Width设置为8bits,如图22 7所示。
{{ ::图22-7.png |图22-7 Flash设置}}
**图22-7 Flash设置**
同样的方法打开SDRAM设置框,按照图22-8进行设置。
{{ ::图22-8.png |图22-8 SDRAM设置}}
**图22-8 SDRAM设置**
对PIO进行设置,首先将它的Module Name改为led_pio。然后将位长改为8。
6. 时钟与中断的设置
对与上述组建的设置,除了SDRAM设置为clk_50外,其他的都设置为clk。按图22 9所示的设置中断优先级。
{{ ::图22-9.png |图22-9 时钟与中断设置}}
**图22-9 时钟与中断设置**
设置cfi_flash的Base地址为0;设置sdram的base地址为0x2000000,将这两个地址固定,然后将它们的基地址固定,在基地址一栏中点右键,选择Lock Base Address,如下图(图22-10)所示:
{{ ::图22-10.png |图22-10 锁定基地址}}
**图22-10 锁定基地址**
然后点击System下拉菜单的Auto-Assign Base Addresses,对其他外设自动分配地址。
在SOPC Builder中选择Next 到More “cpu_0” Settings标签栏,设置系统复位和启动时运行的地址,如图22-11所示:
{{ ::图22-11.png |图22-11 设置启动地址}}
**图22-11 设置启动地址**
至此一个SOPC系统就设置完毕了。
点击【Next】到System Generation,HDL选项上打钩,这里我们不进行仿真所以对取消Simulation,如图22-12所示。点击【Generate】,如果没有报错说明系统生成正确。
{{ ::图22-12.png |图22-12 系统生成}}
**图22-12 系统生成**
7. 时钟设置:新建一个名为uclinux的原理图文件,然后添加一个名为SDRAM_CLK的ALTPLL(锁相环),如图22-13所示。
{{ ::图22-13.png |图22-13 添加内部锁相环}}
**图22-13 添加内部锁相环**
点击【Next】,进入设置界面(图22-14),首先将Device family设置为CycloneⅡ,Device speed设置为8,输入时钟频率设为50MHz。
{{ ::图22-14.png |图22-14 时钟设置}}
**图22-14 时钟设置**
点击【Next】,对第一个输出时钟进行设置,第一个时钟是SDRAM的时钟,只需要将Clock phase shift设为-63,如图22-15所示。点击【Next】,将第二个时钟设置为50MHz,无相位偏移。同样的将第三个时钟设置为100MHz无相位偏移。然后点击【Finish】生成锁相环。
{{ ::图22-15.png |图22-15 输出时钟设置}}
**图22-15 输出时钟设置**
8. 原理图文件设计:将上述生成的锁相环符号和nios_cpu符号添加到原理图中,如图22-16和图22-17所示。
{{ ::图22-16.png |图22-16 时钟连接}}
**图22-16 时钟连接**
{{ ::图22-17.png |图22-17 原理图设计}}
**图22-17 原理图设计**
在对所有管脚连接完,并分配好管脚位置后,对工程进行编译,至此SOPC系统的硬件部分设计完毕。
#### 2.2 软件环境配置
1. 软件安装
在NiosⅡ上运行uClinux需要安装Microtronix uClinux。如果开发环境Quatars6.0+NiosⅡ6.0,应该安装版本1.4。如果是Quatars7.0+NiosⅡ7.0,则需要更高版本1.4.1,产品光盘中带的是1.4.1版本。在安装时要注意指明NiosⅡ的安装路径,如图22-18所示:
{{ ::图22-18.png |图22-18 nios中Linux安装}}
**图22-18 nios中Linux安装**
2. uclinux内核编辑
在安装完毕后,启动NiosⅡ IDE,选择菜单File→Switch workspace,在里面指定前面所建立的NIOS核所在的路径,这里假定为:c:\uClinux下,如图22-19所示。
{{ ::图22-19.jpg |图22-19 将工作目录切换至NIOS核所在的目录}}
**图22-19 将工作目录切换至NIOS核所在的目录**
新建一个Linux Kernel Project(File→new→project…),如图22-20所示。
{{ ::图22-20.png |图22-20 新建工程}}
**图22-20 新建工程**
点击【Next】在Project name中填入kernel,如图22-21所示。
{{ ::图22-21.png |图22-21 工程名设置}}
**图22-21 工程名设置**
点击【Next】指定该工程对应的SOPC系统,点击【Browse】在SOPC System的路径找到.ptf文件(假定前面的NIOS系统存在了c:\uClinux下),在Kernel Options栏中,upload Memory选择cfi_flash,Execute Memory 选择sdram,如下图所示。
{{ ::图22-22.png |图22-22 SOPC System选择}}
**图22-22 SOPC System选择**
点击【Finish】,这时IDE的Navigator栏(一定要切到navigator栏)中,会出现刚才新建的kernel,点击右键所建立的工程,选择configure kernel(图22-23)。
{{ ::图22-23.png |图22-23 configure kernel}}
**图22-23 configure kernel**
这时会弹出Kernel的配置窗口(图22-24)。
{{ ::图22-24.png |图22-24 配置窗口}}
**图22-24 配置窗口**
这里我们需要对内核进行配置。进入Device Driver→ATA/ATAPI/MFM/RLL support,点击空格键或N,这时可以发现在<>内没有任何符号,如图22-25所示,这样在对内核进行编译的时候不会对这个驱动程序进行编译。
{{ ::图22-25.png |图22-25 ATA/ATAPI/MFM/RLL驱动设置}}
**图22-25 ATA/ATAPI/MFM/RLL驱动设置**
进入Device Driver→Character Devices→Serial driver设置串口,选择如图22-26所示。
{{ ::图22-26.png |图22-26 串口设置}}
**图22-26 串口设置**
这样uclinux既可以支持串口控制台也可以支持Jtag控制台。
进入Processor type and features→CPU(NIOS2)→选择NIOS2.
进入processor type and features→Platform→选择Microtronix cyclone board support.
进入Networking Support→Network Device Support,进入Ethernet<10 or 100MHz>Davicom DM9000。其他各项都采样默认设置project。
注意:如果工程中用到网卡需要将网卡的驱动程序相关宏定义进行修改,程序路径为:
NiosⅡ路径(假设Quartus和NIos安装在c盘下) c:\Altera\70\nios2eds\bin\ eclipse\plugins\com.microtronix.nios2linux.kernel_1.4.1\ linux-2.6.x\drivers\net\dm9000x.c。然后打开工作目录uClinux/kernel/buid/include中的nios_system.h文件,可以看到na_dm9000a_0,na_dm9000a_0_irq这两个宏。在dm9000x.c中搜索以下两行:
#define DM9000_MIN_IO (na_dm9000)
static u8 irqline = na_dm9000_irq;
将第一行修改为:#define DM9000_MIN_IO (na_dm9000a_0)
将第二行修改为:static u8 irqline = na_dm9000a_0_irq;
在这里修改的原因是:要使得dm9000x.c中的变量要和nios_system.h中定义的变量相同,否则编译不能通过。
在设置完后选择保存,然后build内核(图22-27)。
{{ ::图22-27.jpg |图22-27 编译内核}}
**图22-27 编译内核**
3. uclinux文件系统建立
在File→new→project…对话框中选择linux filesystem project, 和建立uClinux 内核工程一样,在SOPC Builder System栏,选择刚才我们在建立uClinux_kernel工程时选择的SOPC件系统(图22-28)。
{{ ::图22-28.jpg |图22-28 建立文件系统设置}}
**图22-28 建立文件系统设置**
工程完成后在Navigator栏中栏下把\target\etc目录下inittab文件打开,将ttys1下前面的“#”去掉,将串口打开,如图22-29。然后编译(图22-30)。
{{ ::图22-29.jpg |图22-29 建立文件系统}}
**图22-29 建立文件系统**
{{ ::图22-30.jpg |图22-30 编译内核}}
**图22-30 编译内核**
将工程下载到flash中,点击菜单Tools→lash programmer,出现(图22-31):
{{ ::图22-31.png |图22-31 Flash programmer}}
**图22-31 Flash programmer**
点击左上角第一个New lauch configuration ,出现(图 22-33):
{{ ::图22-32.jpg |图22-32 新建下载配置}}
**图22-32 新建下载配置**
把program software project into flash memory中的勾去掉。
在Target Hardware中选择SOPC系统的路径(图22-33)。
{{ ::图22-33.png |图22-33 设置SOPC的路径}}
**图22-33 设置SOPC的路径**
Flash Program 有三种下载方式,在这里选择Program a file into flash memory,首先下载linux内核,路径为:内核工程路径c:\uclinux\kernel\build\vmlinux.bin,offset为0x0,然后点击Program flash进行下载。
注意:在这里的选项可能是灰的,要求一定要把JTAG下载线连接到USB口上。
{{ ::图22-34.jpg |图22-34 kernel下载参数}}
**图22-34 kernel下载参数**
然后下载文件系统,路径为:文件系统工程路径c:\uclinux\fs\romfs.bin,offset为 0x200000。
{{ ::图22-35.png |图22-35 kernel下载参数}}
**图22-35 kernel下载参数**
4. 启动uCinux
进入NiosⅡ command shell(程序→Altera→NIOS II EDS→NiosⅡ command shell),输入nios2-terminal命令(这时先不要回车执行),在Quartus II中下载Nios内核到FPGA,然后马上回车执行命令,这时系统启动,会出现如图22-36的画面。
{{ ::图22-36.png |图22-36 系统启动}}
**图22-36 系统启动**
这时在login后面输入root,Password后面输入uClinux。这时linux就在内核上运行起来了。
也是将串口作为终端控制台来连接。
i. 将串口连接至计算机。
ii. 打开超级终端,按以下参数设置(图 2237):
波特率: 115200 波特/秒
数据位: 8位
停止位: 1位
奇偶校验: 无
流控: 无
{{ ::图22-37.jpg |图22-37 串口设置}}
**图22-37 串口设置**
在Quartus中将NIOS下载到FPGA中,超级终端的显示如图 22-38所示。
{{ ::图22-38.jpg |图22-38 串口显示}}
**图22-38 串口显示**
#### 2.3 建立uClinux应用程序
1. 点击【File】→【New】→【Projects…】→【Linux application project】,新建一个名为Hello的工程。
2. Navigator栏中右键选中新建的工程Hello,点击【New】→【Source File】,如图 22 39所示。在File Name栏里输入文件名Hello.c。
{{ ::图22-39.jpg |图22-39 新建源文件}}
**图22-39 新建源文件**
3. 在编辑栏里输入一个Hello World的C程序(图22-40)。
{{ ::图22-40.png |图22-40 输入源程序}}
**图22-40 输入源程序**
4. altera\70\nios2eds\examples\software\linux\apps\samples\hello下的makefile文件复制到工程目录下,并修改PRGJ_NAME=HelloDIR=.。如图22-41所示。
{{ ::图22-41.png |图22-41 设置Makefile}}
**图22-41 设置Makefile**
5. 然后在NiosⅡ C/C++ Project 栏下,在Hello工程上点击右键,选择Create make target,点击OK。然后在Hello工程上点右键Build make target,选择All并点击Build进行编译(图 22-42)。
{{ ::图22-42.jpg |图22-42 编译程序}}
**图22-42 编译程序**
6. 这时会产生Hello.exe文件(图22-43)。
{{ ::图22-43.png |图22-43 生成的Hello.exe}}
**图22-43 生成的Hello.exe**
7. 将生成的Hello.exe文件复制到文件系统的home目录下(图22-44),编译后将新的文件系统重新下载到目标板上。
{{ ::图22-44.png |图22-44 拷贝到文件系统的目录下}}
**图22-44 拷贝到文件系统的目录下**
8. 登陆uClinux后,直接在命令行输入Hello,在屏幕上打印出Hello World。如下图所示。
注意:在登陆uClinux后的默认路径是在/Home下,如果将应用程序粘贴到了其他文件夹,需要切换路径。
\\
\\
### 3. 注意事项
1. 在启动nios2-terminal之前,一定要重新下载Nios核否则可能登陆失败。\\
2. 若在启动nios2-terminal后,提示有多个cable问题,nios2-terminal --cable命令检查cable的状态,然后选择一个正确的cable,如nios2-terminal --cable 2。\\
3. 在建立SOPC系统中,选择器件时其型号和大小应该和实验板上的一致。\\
4. 在上述SOPC系统中,定时器timer一定要有,否则会出错。\\
5. 在添加Flash时,一定要设定Referencd Designator(chip label),即不能是默认的“none”,可以修改成任意别的字符,如“FL”。否则烧写Flash 会出现错误。\\
6. 在编译的时候,有些管脚是有特殊作用,但也可以当普通I/O使用,不过需要按如下步骤设置:\\
i.Step 1:Assignments → Device(图22-45)。
{{ ::图22-45.png |图22-45 管脚设置(a)}}
**图22-45 管脚设置(a)**
ii. Step 2:按下Device and Pin Options,选择Dual-Purpose Pins(图 22 46)。
{{ ::图22-46.png |图22-46 管脚设置(b)}}
**图22-46 管脚设置(b)**
iii. Step 3:将nCEO改成Use as regular I/O(图 22-47)。
{{ ::图22-47.png |图22-47 管脚设置(c)}}
**图22-47 管脚设置(c)**
\\
\\