做过ARM7+ucos的项目,可是都是写一些外围驱动和应用代码,有一些细节还是有些模糊,空闲时间买块ARM板学习,淘宝上44b0x价格便宜,挺有性价比的。
山寨的板子当然就是抄袭“龚俊“的,所以资料什么的,很多学习资料;但用官方的SDK,一是放心,可以自己任意修改;二是练手也有益。
考虑移植u-boot过去,跑个uclinux,但是初级点的还是先跑个ucos,另外跑个lwip,参考主要的代码有:
44b0x的bsp参考sumsung的SDK
ucos+lwip的porting参考README
u-boot直接去soureforge上download一个
有了这些就可以干活了,ucos调试工具:ADS(armgcc)+HJTAG+WIGGLER;当然如果要调试u-boot的话就arm-elf-gcc+arm-elf-gdb+ocdremot;或者直接用wiggler将u-boot烧到flash原始调试方法
1. 44b0x详解
下图是山寨板的内存分布,其中SDRAM为16M:0x0c00 0000~0x0c80 0000,FLASH为2M:0~0x0020 0000
2. LD链接
对以ADS调试来讲,LD直接在ADS中填写相应地址,比如调试
-info totals -ro-base 0xc100000 -rw-base 0xc500000 -first 44binit.o(init)
(
ro-base、rw-base这个设置对代码烧入flash以后的分布没有关系,只是把RAM中的code和data分段了一下. RAM中一般来说ro段后面紧跟着rw段,rw段后面紧跟着zi段。
)
0x0C10 0000其实是可以比较随意的,0xc00 5000~0xc70 0000都可以
这个时候可以用ADS加载到调试版调试:ADS是加载到0x0C10 0000的
或者U-boot加载运行:
tftp 0xc100000 ucos.bin
go 0xc100000
从0xc10 0000开始跑
反汇编elf文件,得到结果如下
Init
0x0c100000: ea000125 %... B ResetHandler ; 0xc10049c
0x0c100004: ea00005d ]... B HandlerUndef ; 0xc100180
......
** Section #2 'ER_RW' (SHT_PROGBITS) [SHF_ALLOC + SHF_WRITE]
Size : 64 bytes (alignment 4)
Address: 0x0c500000
** Section #3 'ER_ZI' (SHT_NOBITS) [SHF_ALLOC + SHF_WRITE]
Size : 79216 bytes (alignment 4)
Address: 0x0c500040
下面是一个u-boot加载的ucos运行中的内存分布图
|0x0C80 0000
| ucos的代码会把二级中断向量表放这里的
|0xc7f ff00-main在栈底,先进后出
|
| stack栈
|
|0xc7f f000堆heap end地址,紧跟的是stack栈
|
| 堆heap
|
|
|0x0C70 0000=0x0C80 0000-1MB
|
|
| rw段+bss
|
|0x0C50 0000:ucos rw段紧跟的是ZI段(BSS)
|
|
|
| ....把应用程序ucos加载到这里开始跑
|
|0x0C10 0000:ucos ro段
|
|
|0xc00 0000+1024
|
| u-boot指向的二级中断(可以修改为ucos的二级中断)
|
|0xc00 0000
.
.
.
|0x0020 0000
|
| 应用程序(ro+rw)
|
|0x0008 0000
|
|
|
|0x0005 0000
|
| u-boot env
|
|0x0004 0000
|
| u-boot程序,44b0x的中断,指向u-boot的二级中断0x0c000000,可修改
|
|_start = 0x0000 0000
只读的代码段和常量被称作RO段(ReadOnly),可读写的全局变量和静态变量被称作RW段(ReadWrite),RW段中要被初始化为零的变量被称为ZI段(ZeroInit),也叫未初始化段BSS,下面是编译对比图,清楚比较了代码的分布
另外局部变量,临时变量在栈stack中,malloc声明变量在堆heap中
Code RO Data RW Data ZI Data Debug
2900 1491 61 20 Grand Totals
=======================================================
char tmp = 10;或者static char tmp = 10;之后结果是
=======================================================
Code RO Data RW Data ZI Data Debug
2900 1491 62 20 Grand Totals
========================================================
char tmp = 0;或者char tmp;之后结果是
========================================================
Code RO Data RW Data ZI Data Debug
2900 1491 61 21 Grand Totals
========================================================
ADS中的处理ro-base和rw-base是定死的,下面就是汇编中拷贝的代码部分,拷贝RO和RW到RAM中
;********************************************************
;* Copy and paste RW data/zero initialized data *
;********************************************************
LDR r0, =|Image$RO$Limit| ; Get pointer to ROM data
LDR r1, =|Image$RW$Base| ; and RAM copy
LDR r3, =|Image$ZI$Base|
;Zero init base => top of initialised data
CMP r0, r1 ; Check that they are different
BEQ