有没有人在STM32F103上用UART IAP跑过RT-Thread?

发布于 2013-12-31 17:27:56
我修改之后用IAP加载,启动时出现和原来这个帖子中一样的问题,不调度:
topic3231.html

然后下载了最新的GNU Tools for ARM Embedded Processors 4.8-2013-q4,编译之后跑不起来。

这次用MDK的armcc编译之后也出现了和GCC 4.7编译一样的问题,启动之后在启动调度的地方失败。


这里还有一个问题没太搞明白,用MDK编译之后,ELF文件信息如下:
$ readelf -l rtthread-stm32.axf

Elf 文件类型为 EXEC (可执行文件)
入口点 0x80030ed
共有 1 个程序头,开始于偏移量168212

程序头:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000034 0x08003000 0x08003000 0x0c038 0x0db14 RWE 0x8

Section to Segment mapping:
段节...
00 ER_IROM1

0x8003000是IAP要求的。但GCC修改stm32_rom.ld之后不行:
$ readelf -l rtthread-stm32.axf

Elf 文件类型为 EXEC (可执行文件)
入口点 0x800d999
共有 2 个程序头,开始于偏移量52

程序头:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08000000 0x08000000 0x0f7d8 0x0f7d8 R E 0x8000
LOAD 0x010000 0x20000000 0x0800f7d8 0x000bc 0x015b4 RW 0x8000

Section to Segment mapping:
段节...
00 .text
01 .data .stack .bss

这里我测试了一下,应该是因为Align太大的原因,如果设置为0x08100000是可以的。
但这里的Align好像不是在.ld文件中设置的?还没找到是什么情况。同样的GCC,我在CoIDE中
编译的对象也全部是2^15,但在emIDE中却又很小,在.ld中没有找出什么区别来,但又不应该
是编译器定死的。

另外奇怪的是,GCC 4.7和4.8编译出现readelf看到的是一样的,但4.7编译的系统可以由
IAP下载之后启动,只是启动之后不调度;而GCC 4.8编译出来之后一跑似乎就死了,没有
任何输出。

查看更多

关注者
0
被浏览
3.9k
10 个回答
qllaoda
qllaoda 2014-01-03
入口地址肯定得是4的整数倍吧,0x800d999能行?考虑到Flash的结构,用这个地址也没什么意义啊,因为闪存只能整个扇区一起擦除,所以主程序入口应该放在闪存扇区的边界处吧
我用0x08010000没问题。
Cyberman
Cyberman 2014-01-03
是挺奇怪的,你不说我还没有注意readelf显示的入口地址是一个奇数值,不过它和armcc编译的那个结果一样,
在IAP程序中选择3可以开始启动RT-Thread,只是重启到最后不调度(我刚好有原来上次遇到问题时的调试代码
在里面)。

这个地址应该是Flash block的整数倍,是ST官方给的UART IAP文档中给出的值。只是我奇怪为什么GCC编译
出来的那个Align非常大,这个应该不是GCC缺省的,因为在emIDE中我用同一个编译器,最后readelf显示的
Progarm段的对齐是0x4;但我没弄清楚这个值受什么的影响。

GCC 4.8的问题有应该和用IAP无关,不用IAP,直接用它编译出来的RT-Thread还是跑不起来,至少串口没有
任何显示,我没有调试环境,所以不知道跑成什么样了。
Cyberman
Cyberman 2014-01-03
入口地址肯定得是4的整数倍吧,0x800d999能行?考虑到Flash的结构,用这个地址也没什么意义啊,因为闪存只能整个扇区一起擦除,所以主程序入口应该放在闪存扇区的边界处吧
我用0x08010000没问题。


我不太清楚ELF头中的入口地址指什么,但我仔细看了一下,不管是GCC编译的结果,还是armcc的编译结果,实际上它都是一个奇数地址。在GCC中是Reset_Handler + 1。不管是4.8还是4.7,编译出来都是这样,但奇怪的是4.7编译的结果能跑起来而4.8不行。用缺省的stm32_srom.ld编译出来的结果也是这样的。
qllaoda
qllaoda 2014-01-03
用bin文件啊,elf文件的格式我不清楚。rtconfig.py最后不是有一句
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin
fromelf -z $TARGET'
这个可以生成对应的bin文件
stm32_rom.ld里修改一下
MEMORY
{
CODE (rx) : ORIGIN = 0x08010000, LENGTH = 1M /* 1M flash */
DATA (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */
}

把CODE定位到0x08010000,当然代码里也需要把中断向量表映射到这个位置上。
最后把生成的bin文件通过bootloader直接烧写到Flash的0x08010000处即可。
Cyberman
Cyberman 2014-01-03
用bin文件啊,elf文件的格式我不清楚。rtconfig.py最后不是有一句
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin
fromelf -z $TARGET'
这个可以生成对应的bin文件
stm32_rom.ld里修改一下
MEMORY
{
CODE (rx) : ORIGIN = 0x08010000, LENGTH = 1M /* 1M flash */
DATA (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128K sram */
}

把CODE定位到0x08010000,当然代码里也需要把中断向量表映射到这个位置上。
最后把生成的bin文件通过bootloader直接烧写到Flash的0x08010000处即可。


MDK才用fromelf吧,它对应的文件是stm32_rom.sct吧,两个我都修改了测试过,MDK的版本
也会出现问题。我加载用的是bin文件。
GCC的那个对齐是怎么来的我已经知道了,是GCC ld的一个page align功能导致的,它缺省的
page align似乎是0x8000,可以用-n把它取消,或者用-z max-page-size=xxxx重新设置。

DS中我没看到STM32F103C8的内置Flash的Page Size和Erase Block的大小,按说用IAP
应该是要Erase Block对齐吧;不过官方文档给的是0x08003000,应该是OK的。

我测试了一下CoIDE + CoOS的bin文件,用IAP烧进去是能跑起来的,不过刚烧完也出现一个
启动之后只在主程序中打印了信息,后面的两个线程都跑不起来;后来用JLink先r然后g之后,
再在IAP中选择3就可以跑起来了;RT-Thread一直不行,目前还没找到原因。

GCC 4.8编译出来无法启动也没找到原因,用它编译CoIDE + CoOS结果是OK的。
mabg
mabg 2014-01-03
KEIL IAP + RTTHREAD APP 跑过 没有问题
Cyberman
Cyberman 2014-01-04
KEIL IAP + RTTHREAD APP 跑过 没有问题


KEIL也有IAP吗?我还没看到,我用的是ST官方的那个,用Keil MDK编译的。
zchong
zchong 2014-01-05
裸奔的iap跑过没?
Cyberman
Cyberman 2014-01-06
裸奔的iap跑过没?

祼奔的IAP指什么,是用IAP下载一个祼奔的程序吗?这个还没试过,我只用它测试了下载测试了GCC/armcc编译的RT-Thread,和CoIDE中用GCC编译的一个基于CoOS的应用,后者是正常跑起来的了。祼奔应该不会有什么问题吧。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览