尝试IAR下创建stm32新工程及bootloader

之前在iar下开发都是在官方例程或网络中下载的例程,开发时IAR直接跳入main中执行c代码,最近想创建个新的stm32工程来写一些汇编文件了解下CM3汇编指令,于是痛苦摸索了很多天。

起初创建了IAR新工程,使用的stm32f103x,加入了官方提供的iar工程文件:startup.s,原本想将keil下的startup文件直接copy过来,然而现实是keil和iar使用的一些汇编伪指令差别很大,一个百行的startup.s就有一万个错误,直接爆炸。不过官方分别提供了keil iar gcc对应的工程及启动文件,可以按需求使用。

startup.s文件中最重要的自然是__vector_table,一个异常向量表,表中记录了所有异常的入口地址

除第一个外,其它都是入口地址。CM3将第一个视为芯片复位后MSP的值,这里我一直有个猜测但还没有实验,CM3的MSP不需要手动配置,而是复位后默认去flash的0x80000000地址去取 (我的stm32f103 flash首地址从0x80000000开始,似乎也会被映射位0x0,两个地址都可用,但相对的都是flash的0地址。也就是说工程生成的bin文件前四个字节就是MSP的复位值),这样的话是不是CM3的bootloader不一定非要使用汇编来写,直接跑c也是可以的?如果说汇编能够使用16位指令来节省空间,那么c在编译时不会生成16位指令吗?

加入启动文件还要根据芯片选择官方提供的.ICF文件,ICF文件主要用来告诉编译器芯片的RAM ROM地址范围以及程序中的不同段在存储器中的存放位置。

IAR中有一些段的内部关键字如CSTACK,HEAP等

使用的ICF中将向量表放在flash的首地址

place at address mem:0x80000000 { readonly section .intvec };

startup.s中__vector_table自然是被放在.intvec段:

SECTION .intvec:CODE:NOROOT(2)

在IAR生成的map文件中可以清晰的看到

至于A1 P1 字样,IAR解释为A是绝对位置,P则是相对位置

这两个文件添加完成后执行编译发现报错:__iar_program_start没有定义,

在IAR option中看到了他的身影:

IAR执行连接时默认去找__iar_program_start入口,最开始第一个钩我没有勾上,导致无法连接入IAR提供的.S文件,__iar_program_start自然不会被找到。这个入口也可以选择被重新定义完全由开发者重命名重写。

IAR安装目录下提供了很多种类芯片的.S文件,其中一些是启动文件和初始化文件,CM3的__iar_program_start被放在cstartup_M.s中。

起初我尝试了重写__iar_program_start入口,这个模块中主要去初始化全局段以及对一些未赋值的全局变量段清零就可以了,后来发现IAR  .map文件中有

Region$$Table$$Base     0x00000000         --   Gb  - Linker created -
Region$$Table$$Limit    0x00000000         --   Gb  - Linker created -

字样,查阅了一些资料有说这两个符号标志了一块内存,里面存放了多个段的信息。实际上到最后我也没摸索出该怎么使用它们,主要是全局变量所在的段如何与ICF文件对应起来成了问题。如果pass这一过程那么C代码中则不允许有全局变量,汇编中不能使用DCB之类的开辟内存,有的话IAR则会报出__iar_data_init3错误,一直搞不懂全局变量为什么和__iar_data_init3会有关。

 这个__iar_data_init3模块在官方提供的__iar_program_start里面被调用过,由于没有找到__iar_data_init3源码,只看到了__iar_data_init函数,所以一直猜测__iar_data_init3就是__iar_data_init。

至于__iar_data_init代码是c写的:

里面确实和RegionTable有关联,至于怎么实现的,将全局变量从ROM搬到RAM 我在源码中实在看不出来。

最后绕不过全局段初始化这个槛,还是勾上使用IAR提供的.s选项,使用iar的__iar_program_start,程序可以正常跳转运行。。。。

猜你喜欢

转载自my.oschina.net/u/3699634/blog/1829084