|
一、ARM9+LINUX开发历程
使用了51系列和MOTOROLA单片机若干年,觉得自己已经跟不上嵌入式发展的时代了。决定开发一种新的硬件平台,综合比较了一下,觉得ARM9+LINUX模式不错。先从头捋一遍32位嵌入式开发平台的流程:
芯片选型——使用DXP画原理图(如果有可能买块开发板可以极快加快进度)——使用DXP画PCB图——芯片购买/PCB投板生产——芯片焊接——使用ADS编写简单硬件测试程序,调试硬件——搭建LINUX服务器,在服务器建立交叉编译环境——利用服务器和本机超级终端开发U-BOOT-1.3.4——利用U-BOOT-1.3.4的以太网FTP功能和服务器移植开发LINUX-2.6.26 内核——开发文件系统——开发驱动程序——应用程序开发,项目完基本成后回过头来想就是这个一个过程,中间走了不少弯路,在本博客中都有记载,很多问题有的也没有来得及记。
说干就干,时间安排如下:
(1)5"7月硬件设计(芯片,型号,预测价格),已初步完成
CPU:AT91RM9200,81
SDRAM:MT48LC16M16A2TG-75IT(两片32MB*2) 74*2
FLASH:S29GL256N10TAI010(NOR型,32MB,存代码,写慢读快)57.52
FLASH∶K9F2G08U0B(NAND256MB,预留存测试数据,写快读慢)41.1
铁电存储器:FM24CL64(代替EEPROM24LC65,8KB)8.29
以太网物理层控制器:DM9161E(100M/10M自适应)9.4
从USB接口:用于与PC机通信
主USB接口:用于后续移植LINUX时软件更新
触摸屏驱动器:TSC2046(预留)
液晶显示屏模块-TFT液晶显示接口(预留)
(2)ADS+AXD+J-LINK调试过程
目的是为了熟悉ARM开发流程,ADS开发环境,以便为将来U-BOOT的移植打下基础.由于网上资料不多,本步骤走了不少冤枉路,特总结在此,以便以后可以参考.容易步骤省略.
安装ADS>>创建ADS工程>>添加所需要文件>>DEBUG SETTING,将程序的RO_Base设为0X200000则将程序导入AT91RM9200的片内16K的SRAM中运行,实践证明此时不需要管BMS引脚是高是低都能正常运行,也不需要进行REMAP;若将程序的RO_Base设为0X20000000则将程序导入片外64M的SDRAM中运行,此时程序导进SDRAM后需要SETMEM命令将SDRAM初始化,才能正常运行。
通常出现RDI Warning 00005ata abort的告警时是由于CPU复位时间不购导致的,且程序会莫名其妙出现Read memory error @address 0x00200020,word access : Memory access timeout的J-Link RDI Error告警。此时只需要在AXD的Option>target Configure>选择J-LINK,然后点击Configure>选择CPU页,在Reset strategy框中选择Hardware,halt after reset(normal),在Delay after reset中填写所需要的芯片复位时间,由于AT91RM9200的慢时钟需要900ms左右的启动时间,所以将复位时间设为2000ms即可正常调试。(图片无法帖出,遗憾!)
ADS+AXD的主要功能是进行硬件调试,检测SDRAM,FLASH是否能正常工作。源码调试不一定非要AXD不可,有GDB等优秀的调试手段
(3)硬件调试过程
8月25日拿终于拿到了呕心沥血设计的板子,外协厂家的手艺还不错,板子焊得干净漂亮。首先用万用表测量各电源等级的正负端,判定12V,5V,3.3V,1.8V,-5V,-12V等电源回路不存在短路现象,免得烧掉板子后悔莫及。一切OK,愈发佩服焊接工人,这么多芯片,电容,电阻居然没有什么大问题!找来USB转串口线,接上板子的DBUG口,紧张时刻来临,打开超级终端,设置波特率115200,数据位8,无奇偶,1停止位,无数据流控制,给开发板上电,很遗憾传说中的CCCCC一直没有出现,哪里出问题?反复查看原理图和电路板,发现R122电阻居然给我焊成了10K的,没有办法,飞吧。继续上电,涛声依旧,再看电路板,有个6800P的DPLL用滤波电容的颜色怎么跟0.1U的电容颜色一致?我汗,居然这么多问题,刚才还在赞扬外协,实在无语!重新找来6800P电容,焊上。感觉没有问题,用示波器测32.768KHZ晶振有波形,BMS引脚已经拉高。最后怀疑RS232的接线有问题,反复折腾,2,3,5各线换来换去,在某个刹那超级终端终于捕捉到了一个C,虽然只有一个,但让我信心大增,继续查找。终于发现原来DB-9的232接口焊成了公头,设置时按母头设计,我晕阿。记住了,公头5-母头1,公头4-母头2,公头3-母头3。。。。。。。还需要紧记与电脑连接时,2,3需要调换才行。电烙铁来,我飞,上电,一切OK。久违的CCCCCCC犹如洪水泛滥,一发不可收拾,逛激动。。。。。。。找来loader,使用XMODEN协议传下去,正常,继续使用XMODEN协议传编译好的U-BOOT.BIN,U-BOOT终于转起来。快下班了,匆匆忙忙用网线连了一下,灯居然亮了,感觉人生原来是如此美好!是夜睡了晚好觉。
8月27,loader ,boot,u-boot使用超级终端折腾得差不多了,才想起来网线一直没有用过,找来网线我插。??没有反应?继续插还没有反应。难道前天眼花了?反复插,终于灯亮了一下,激动。在U-BOOT里使用setenv addrip 172.21.26.1设置IP,在笔记本里我反复ping,反复超时,郁闷。复位,糟糕灯不亮了,重新上电,灯还不亮,为什么?探索中。。。。。。。原来U-BOOT没有相应PING命令,只能测到ACTIVE即可算连接通上,而PC机的PING命令对U-BOOT也无效,能将内核通过以太网以FTP协议传下去即可认为网络通信正常。
9月1日发现使用MAX660和MAX765产生负电源功率太小,准备采用模块电源供电。调试模拟电路发现DA电压经单/双极性运放输出后带负载时电压下降厉害,加一个电压跟随器后正常。所以在需要提高输入阻抗降低输出阻抗的场合使用电压跟随器是最好的选择。
(3)U-BOOT的移植
下载了U-BOOT-1.3.4版本,按文档设置好编译器路径及前缀 LINUX下的环境变量。
修改Makefile文件中以下部分:
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-unknown-linux-gnueabi-
endif
修改include〉configs〉at91rm9200dk.h(修改配置,主要是SDRAM的大小,NORFLASH的信息)
修改board>atmel>at91rm9200dk>at91rm9200dk.c(主要修改片选及NANDFLASH的引脚配置)
进入U-BOOT-1.3.4的文件夹,执行如下命令:
make distclean 删除原先的配置文件
make clean 删除原来编译生成的目标文件和中间文件
make at91rm9200dk_config 将U-Boot设为for 9200
make 编译最终的可执行文件
gzip u-boot.bin 压缩成U-BOOT.BIN.GZ,u-boot-1.3.4对AT91RM9200的支持非常棒,几乎没有修改什么咚咚就可以正常转起来了。
(4) U-BOOT的下载固化
1、将loader.bin通过超级终端下载到板子中,使用XMODEN协议,下载完继续出现CCCCC
2、继续在超级终端使用XMODEN协议下载U-BOOT.bin到板子中,出现以下内容:
Loader 1.0 (Mar 1 2008 - 21:44:40)
XMODEM: Download U-BOOT (to address 20F00
CCCCCCCCCC
U-Boot downloaded successfully
U-Boot 1.3.4 (Sep 22 2008 - 13:46:33)
DRAM: 64 MB
Spansion: S29GL256N (32M Byte)
Flash: 32 MB
NAND: No SmartMedia card inserted
0 MB
*** Warning - bad CRC, using default environment
SSC 510T-Boot>
至此,U-BOOT已经在板子中正常运行起来。将U-BOOT和BOOT.bin固化到板子中(U-BOOT的FLASH驱动此前已经修改完成,有时间再另写)
SSC 510T-Boot> protect off all (去掉FLASH写保护功能)
SSC 510T-Boot> erase 1:0 (擦除第一块FLASH的0扇区,128KB)
SSC 510T-Boot> loadb 0x21000000 (使用KERMIT协议下传BOOT.BIN)
SSC 510T-Boot> cp.b 0x21000000 0x10000000 0x5000 (将BOOT.BIN固化到FLASH中)
SSC 510T-Boot> loadb 0x22000000 (使用KERMIT协议下传U-BOOT.BIN.TAR)
SSC 510T-Boot> cp.b 0x22000000 0x10010000 0xFFFF (将U-BOOT.BIN.TAR固化到FLASH中)
SSC 510T-Boot> protect on all
但是发现boot.bin只能执行到下面:
**Welcome to ATMEL AT91RM9200**
*******************************
WFG: Bootloader 2
BOOT 1.0 (Sep 25 2008 - 12:40:29)
Uncompressing image...
由于无法进行源码级调试,只能将调试信息发到超级终端了.逐步证明makecrc()函数没有问题,问题出现在gunzip()函数上的magic[0] = (unsigned char)get_byte()此语句中.想象可能跟编译时出现了-mshort-load-bytes错误有关,为了编译通过我去掉了该选项,导致了CPU在以字(16位)组织的FLASH中按字节(8位)读取时出现了错误,估计可能是类似于M68K系列CPU的双总线错误差不多.折腾了两天才解决此问题.
原来我使用了4.2版本的编译器编译U-BOOT-1.3.4和内核,都没有出什么错误,就想当然用它来编译BOOT,结果发生了cc1: error: unrecognized command line option "-mshort-load-bytes"错误,在网上查找,试图使用-malignment-traps来代替也不行.后来找了个3.2版本的编译器编译通过却发射了如我其他帖子所描述那样的无法BOOT的过程.在网上反复查找,确定BOOT只能用cross-2.95.3的编译器来编译.事实证明确实如此,将编译好的boot.bin和u-boot.bin.gz烧到FLASH中去后,我FLASH使用S29GL256N,正常启动!启动画面如下:
Loading: T T T T ************************
**Welcome to ATMEL AT91RM9200**
*******************************
WFG: Bootloader 2
BOOT 1.0 (Sep 25 2008 - 12:40:29)
Uncompressing image...
Uncompressing ...
gunzip() out! (这个就是我调试用的输出信息,证明程序运行到此处没有问题!)
done....
U-Boot 1.3.4 (Sep 25 2008 - 12:49:14)
DRAM: 64 MB
Spansion: S29GL256N (32M Byte)
Flash:
NAND: No SmartMedia card inserted
0 MB
In: serial
Out: serial
Err: serial
SSC 510T-Boot> protect off all (去掉FLASH保护,准备写入内核)
Un-Protect Flash Bank # 1
SSC 510T-Boot> printenv
bootdelay=3
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
serverip=172.21.26.148
netmask=255.255.0.0
ipaddr=172.21.16.1
stdin=serial
stdout=serial
stderr=serial setenv ipaddr 172.21.26.100 (设置环境变量)
SSC 510T-Boot> setenv bootcmd 0x10040000 (内核位置)
SSC 510T-Boot> setenv bootm 0x10240000 (文件系统位置)
SSC 510T-Boot> saveenv
Saving Environmen
Un-Protected 1 sectors
Erasing Flash...Erasing sector 1 ... ok.
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
SSC 510T-Boot> erase 1:2-17 (擦除2-17扇区,存放内核)
SSC 510T-Boot> erase 1:18-36 (擦除18-36扇区,存放文件系统)
SSC 510T-Boot> tftpboot 20000000 zImage.img (通过以太网下载内核)
TFTP from server 172.21.26.148; our IP address is 172.21.26.100
Filename 'zImage.img'.
Load address: 0x20000000
Loading: T T T T ###############################################################
##
#############
done
Bytes transferred = 1134056 (114de8 hex)
SSC 510T-Boot> cp.b 20000000 10040000 1fffff (将内核写道FLASH中,1分钟左右)
Copy to Flash... done
SSC 510T-Boot> tftpboot 21000000 ramdisk.cramfs (通过以太网下载文件系统)
TFTP from server 172.21.26.148; our IP address is 172.21.26.100
Filename 'ramdisk.cramfs'.
Load address: 0x21000000
Loading: #################################################################
#################################################################
#####################################
done
Bytes transferred = 2449408 (256000 hex)
SSC 510T-Boot> cp.b 21000000 10240000 300000 (将文件系统写到FLASH中,5分钟左右)
Copy to Flash... done
SSC 510T-Boot>
到这里成功了一半了,但发现在star kernel.......后再也没有什么反应,分析如下:
内存中:
20000000-内核
20410000-文件系统
20F00000-U-BOOT.BIN
21000000-内核解压到此处运行
发现U-BOOT.BIN与内核运行处只有1M空间,察看源码U-BOOT除了本身占用了115K外还须留了不小的空间传递参数给内核,可能是此空间被覆盖了造成所传递参数被破坏,导致内核无法启动.将U-BOOT移到21F00000处,重新倒入内核文件系统,系统正常运行了!
在移植内核时发生machine ID 错误,把U-BOOT的at91rm9200_config改成at91rm9200dk_config就可以了。或者在LINUX-2.26.3/arch/arm/mach-at91/board-dk.c中的AT91RM9200DK修改为AT91RM9200,如下:
MACHINE_START(AT91RM9200, "Atmel AT91RM9200-DK")
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = dk_map_io,
.init_irq = dk_init_irq,
.init_machine = dk_board_init,
MACHINE_END
(5)内核编译
1、安装
从www.kernel.org上下载Linux2.6.26版的kernel,解压到 /usr/src/arm/linux-2.6.26
从http://maxim.org.za/AT91ARM9200/2.6/ 上下载针对rm9200的补丁(这个网站很难上,多试几次),文件名:2.6.26-at91.patch.gz,复制到 /usr/src/arm/linux-2.6.26,然后在命令行界面中执行 zcat 2.6.26-at91.patch.gz |patch -p1
下载GCC编译器,文件名:arm-linux-gcc-4.1.2.tar.bz2,解压到 /usr/local/arm/4.1.2
2、修改
打开内核原代码根目录下的Makefile,找到如下两行:
ARCH ?=$(SUBARCH)
CROSS_COMPILE ?=
修改为:
ARCH ?=arm
CROSS_COMPILE ?=/usr/local/arm/4.1.2/bin/arm-linux-
3、编译内核
执行如下命令:
make at91rm9200dk_config
make menuconfig
make zImage
大约15分钟内核就会编译好,生成的内核文件在/usr/src/arm/linux-2.6.16/arch/arm/boot/zImage
4、配置选项
当执行make menuconfig后,进入配置菜单,有些选项必须改成如下的内容,否则生成的内核不能运行:
boot options->Compressed ROM boot loader base address=0x21000000
boot options->Compressed ROM boot loader BSS address= 0x21200000
boot options->Default kernel command string= "mem=64M console=ttyS0,115200 initrd=0x20410000,900000 root=/dev/ram0 rw"
如果打算使用NFS,必须选中以下这一选项:
File systems->Network file systems->NFS file system support
到此处后发现生成的Image和zImage文件用FTP倒入板子中均不能用GO命令正常启动。Image老是报告machine ID 错误,而zImage则是发生CRC错误,如下界面:
crc error
-- System halted*****************************
而使用如下命令:
gzip Image
./mkimage -A arm -O linux -T kernel -C gzip -a 0x20000000 -e 0x21000000 -d Image.gz uImage
生成的Image.gz则发生解压错误:
## Booting kernel from Legacy Image at 20000000 ...
Image Name:
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 1241675 Bytes = 1.2 MB
Load Address: 20000000
Entry Point: 21000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... Error: inflate() returned -3
GUNZIP: uncompress or overwrite error - must RESET board to recover |
|