打印
[应用相关]

STM32 eCos 启动代码分析(一)系统复位

[复制链接]
1527|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powerful1|  楼主 | 2015-2-9 17:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
概述
最近接触了STM32,开始了解CortexM3系列ARM处理器上RTOS的移植和启动。
开始总是艰难的,CortexM3是arm7tdmi的升级产品,但实际上和之前的ARM7有着很大的区别。
首先,我们必须有支持CortexM3的编译器,因为CortexM3采用的是Thumb和Thumb2指令集,而不是ARM指令集。
好在eCos 3.0以后ecoscentric提供的toolchain已经支持了CortexM3虽然可能没有采用Thumb2指令集,但是编译和运行eCos是没问题的。
因为CortexM3的中断和异常的特殊性决定了它上面运行的启动代码的不同,这也是为什么我们看到ecos把cortexm的体系结构和之前
的ARM平行放置了。
我们首先看看eCos的第一条语句是怎么运行的,这样我们就比较容易理解后面硬件初始化和中断入口表的代码了。
纵观CortexM启动代码
要了解eCos的CortexM启动代码,需要理清下面几个文件的编译和链接关系。
packages/hal/cortexm/arch/current/src/vector.S
packages/hal/cortexm/arch/current/src/hal_misc.c
packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi

packages/hal/cortexm/arch/current/src/vector.S
//==========================================================================

.syntaxunified
.thumb

//==========================================================================
//Initial exception vector table
//
//This only contains the stack and entry point for reset. The table
//to be used at runtime is constructed by code in hal_reset_vsr().

.section ".vectors","ax"

.global hal_vsr_table
hal_vsr_table_init:

.long    hal_startup_stack // 0 Reset stack
.long    hal_reset_vsr // 1 Reset entry
这里我们可以看到,hal_vsr_table_init开始的预留了8个byte,我们可以猜想这个就是系统的启动部分。
但是,要想了解eCos的启动代码,我们必须知道hal_startup_stack和hal_reset_vsr来源于何处如何设定。
//==========================================================================

沙发
powerful1|  楼主 | 2015-2-9 17:28 | 只看该作者
packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi
//eCos memory layout

#include<pkgconf/hal.h>
#include<cyg/infra/cyg_type.inc>

MEMORY
{
sram : ORIGIN = 0x20000000, LENGTH =0x00010000-CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
flash: ORIGIN = 0x08000000, LENGTH = 0x00080000
rom : ORIGIN = 0x64000000, LENGTH = 0x01000000
ram : ORIGIN = 0x68000000, LENGTH = 0x00100000
}

SECTIONS
{
SECTIONS_BEGIN
SECTION_rom_vectors(flash, 0x08000000, LMA_EQ_VMA)
SECTION_RELOCS(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_text(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_fini(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_rodata(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_rodata1(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_fixup(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_gcc_except_table(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_eh_frame(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_got(flash, ALIGN (0x8), LMA_EQ_VMA)
SECTION_sram(sram, 0x20000400, FOLLOWING (.got))
SECTION_data(ram, 0x68000000, FOLLOWING (.sram))
SECTION_bss(ram, ALIGN (0x8), LMA_EQ_VMA)
CYG_LABEL_DEFN(__heap1)= ALIGN (0x8);
SECTIONS_END
}

hal_vsr_table= 0x20000000;
hal_virtual_vector_table= hal_vsr_table + 128*4;
hal_startup_stack= 0x20000000 + 1024*64;
这里我们可以看到,这个链接管理脚本设置了hal_startup_stack的大小。

使用特权

评论回复
板凳
powerful1|  楼主 | 2015-2-9 17:28 | 只看该作者
观察map文件
我们通过arm-eabi-nm这样的工具把elf文件生成几个map文件看一看这些symbol的具体位置。
hal_reset_vsr
hal_startup_stack
hal_reset_vsr是系统初始化的一个重要函数hal_reset_vsr还调用了stm32变体层的初始化函数hal_system_init。


使用特权

评论回复
地板
powerful1|  楼主 | 2015-2-9 17:29 | 只看该作者
分析一下生成的binary文件
以ROM类型的二进制文件为例,如果我们把STM32的芯片设定为从内部的ROM启动。
他会默认的执行0x0000000也就是0x0800000,我们通过Linux的ghex来看这个二进制文件的前8个字节。
我们会看到
0x20010000
0x08003085
而之前我们通过map文件查到的

0x20010000  hal_startup_stack
0x08003084  hal_reset_vsr




那么为什么这两个地址会差1呢,如果我们能合理的解释。那么我们基本上就清晰的了解了CortexM的启动部分了。

使用特权

评论回复
5
powerful1|  楼主 | 2015-2-9 17:30 | 只看该作者
查阅CorteM3权威指南
查阅以后我们看到有这样的解释,
在离开复位状态后,CM3 做的第一件事就是读取下列两个 32 位整数的值:
-从地址 0x0000,0000 处取出 MSP 的初始值。
-从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量,LSB 必须是 1。然后从这个值所对应的地址处取指。



因为 CM3 使用的是向下生长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加 1。

举例来说,如果你的堆栈区域在 0x20007C00‐0x20007FFF 之间,那么 MSP 的初始值就必须是0x20008000。

向量表跟随在 MSP 的初始值之后——也就是第 2 个表目。要注意因为 CM3 是在 Thumb态下执行,
所以向量表中的每个数值都必须把 LSB 置 1(也就是奇数) 正是因为这个原因,图 3.18 中使用 0x101 来表达地址 0x100。
当 0x100 处的指令得到执行后,就正式开始了程序的执行。在此之前初始化 MSP 是必需的,因为可能第 1 条指令还没执行就会被 NMI 或是其
它 fault 打断。MSP 初始化好后就已经为它们的服务例程准备好了堆栈。

对于不同的开发工具,需要使用不同的格式来设置 MSP 初值和复位向量——有些则开发工具自行计算。
如果想要获知细节,最快的办法就是参考开发工具提供的一个示例工程。
结论
通过以上的一些论证,我们了解了CortexM的启动特性,以及如何根据ecos的memory配置文件,
保证系统启动的时候设定好stack并且执行到eCos的初始化函数。


使用特权

评论回复
6
mmuuss586| | 2015-2-9 19:13 | 只看该作者

楼主刷帖啊;

使用特权

评论回复
7
搞IT的| | 2015-2-9 23:32 | 只看该作者
这个,看的不是很懂啊,要是有详细的代码解释就好了。。

使用特权

评论回复
8
getmore| | 2015-2-10 14:44 | 只看该作者
ecos好像只能在linux下运行吧,楼主,你是怎么搭建调试环境的,把这个说说吧!
好像jlink支持GDB远程调试,你是用的这个的吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

430

帖子

4

粉丝