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

概述

最近接触了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来源于何处如何设定。

//==========================================================================


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的大小。

观察map文件

我们通过arm-eabi-nm这样的工具把elf文件生成几个map文件看一看这些symbol的具体位置。

hal_reset_vsr

STM32 eCos 启动代码分析(一)系统复位_第1张图片

hal_startup_stack

STM32 eCos 启动代码分析(一)系统复位_第2张图片

hal_reset_vsr是系统初始化的一个重要函数

hal_reset_vsr还调用了stm32变体层的初始化函数hal_system_init。

STM32 eCos 启动代码分析(一)系统复位_第3张图片

分析一下生成的binary文件

以ROM类型的二进制文件为例,如果我们把STM32的芯片设定为从内部的ROM启动。

他会默认的执行0x0000000也就是0x0800000,我们通过Linux的ghex来看这个二进制文件的前8个字节。

我们会看到

0x20010000

0x08003085

而之前我们通过map文件查到的

0x20010000  hal_startup_stack

0x08003084  hal_reset_vsr


STM32 eCos 启动代码分析(一)系统复位_第4张图片


STM32 eCos 启动代码分析(一)系统复位_第5张图片


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

查阅CorteM3权威指南

查阅以后我们看到有这样的解释,

在离开复位状态后,CM3 做的第一件事就是读取下列两个 32 位整数的值:

-从地址 0x0000,0000 处取出 MSP 的初始值。
-从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量,LSB 必须是 1。然后从这个值所对应的地址处取指。


STM32 eCos 启动代码分析(一)系统复位_第6张图片


因为 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的初始化函数。




你可能感兴趣的:(STM32 eCos 启动代码分析(一)系统复位)