IAR中cortex-m4启动流程分析
时间:11-25
来源:互联网
点击:
- void wdog_disable(void)
- {
/* First unlock the watchdog so that we can write to registers */ wdog_unlock(); /* Clear the WDOGEN bit to disable the watchdog */ WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK; - }
- void wdog_unlock(void)
- {
/* NOTE: DO NOT SINGLE STEP THROUGH THIS */ /* There are timing requirements for the execution of the unlock. If * you single step through the code you will cause the CPU to reset. */ /* This sequence must execute within 20 clock cycles, so disable * interrupts will keep the code atomic and ensure the timing. */ DisableInterrupts; /* Write 0xC520 to the unlock register */ WDOG_UNLOCK = 0xC520; /* Followed by 0xD928 to complete the unlock */ WDOG_UNLOCK = 0xD928; /* Re-enable interrupts now that we are done */ EnableInterrupts; - }
禁用看门狗流程很简单:先是解锁寄存器,然后更改看门狗寄存器里面的值来禁用看门狗。解锁看门狗寄存器:向解锁寄存器里连续写入0xC520和0xD928,两次写入的时间必须小于20个时钟周期。所以在解锁过程中不能单步运行,期间也不能被中断打断,解锁函数是 wdog_unlock()。上面DisableInterrupts和EnableInterrupts已经在arm_cm4.h中定义过:
#define DisableInterrupts asm(" CPSID i");
#define EnableInterrupts asm(" CPSIE i");
解锁看门狗寄存器后,向看门狗寄存器里写入适当的值就可以禁用看门狗了。
也就是把WDOG_STCTRLH 寄存器(地址是0x40052000)的第0位置0.
②common_startup
初始化RAM(复制向量表、清零.bss段等,为C语言运行环境做准备)。
1 /* File: startup.c */ 2 #include "common.h" 3 #pragma section = ".data" 4 #pragma section = ".data_init" 5 #pragma section = ".bss" 6 #pragma section = "CodeRelocate" 7 #pragma section = "CodeRelocateRam" 8 /********************************************************************/ 9 void 10 common_startup(void) 11 { 12 /* Declare a counter well use in all of the copy loops */ 13 uint32 n; 14 /* Declare pointers for various data sections. These pointers 15 * are initialized using values pulled in from the linker file 16 */ 17 uint8 * data_ram, * data_rom, * data_rom_end; 18 uint8 * bss_start, * bss_end; 19 /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ 20 extern uint32 __VECTOR_TABLE[]; 21 extern uint32 __VECTOR_RAM[]; 22 /* Copy the vector table to RAM */ 23 if (__VECTOR_RAM != __VECTOR_TABLE) 24 { 25 for (n = 0; n 0x410; n++) 26 __VECTOR_RAM[n] = __VECTOR_TABLE[n]; 27 } 28 /* Point the VTOR to the new copy of the vector table */ 29 write_vtor((uint32)__VECTOR_RAM); 30 /* Get the addresses for the .data section (initialized data section) */ 31 data_ram = __section_begin(".data"); 32 data_rom = __section_begin(".data_init"); 33 data_rom_end = __section_end(".data_init"); 34 n = data_rom_end - data_rom; 35 /* Copy initialized data from ROM to RAM */ 36 while (n--) 37 *data_ram++ = *data_rom++; 38 /* Get the addresses for the .bss section (zero-initialized data) */ 39 bss_start = __section_begin(".bss"); 40 bss_end = __section_end(".bss"); 41 /* Clear the zero-initialized data section */ 42 n = bss_end - bss_start; 43 while(n--) 44 *bss_start++ = 0; 45 /* Get addresses for any code sections that need to be copied from ROM to RAM. 46 * The IAR tools have a predefined keyword that can be used to mark individual 47 * functions for execution from RAM. Add "__ramfunc" before the return type in 48 * the function prototype for any routines you need to execute from RAM instead 49 * of ROM. ex: __ramfunc void foo(void); 50 */ 51 uint8* code_relocate_ram = __section_begin("CodeRelocateRam"); 52 uint8* code_relocate = __section_begin("CodeRelocate"); 53 uint8* code_relocate_end = __section_end("CodeRelocate"); 54 /* Copy functions from ROM to RAM */ 55 n = code_relocate_end - code_relocate; 56 while (n--) 57 *code_relocate_ram++ = *code_relocate++; 58 }
在IAR中,
上面代码中,先是指定了5个不同名称的段(前3个是保留段名称,代表这些段是从这里开始的),CodeRelocate和CodeRelocateRam是在*.icf文件中定义的块(block):
define block CodeRelocate { section .textrw_init }; define block CodeRelocateRam { section .textrw };
quote:
The
_ramfunc keyword makes a function execute in RAM. Two code
sections will be created: one for the RAM execution (.textrw), and one for the ROM initialization (.textrw_init).
外部变量引用
extern uint32 __VECTOR_TABLE[]; extern uint32 __VECTOR_RAM[];
来自IAR的链接文件(.icf),在.icf文件中已经定义了变量 __VECTOR_TABLE 和 __VECTOR_RAM 其值都是0x1fff0000."Copy the vector table to RAM"这段代码进行判断,如果向量表不在RAM中,则把向量表拷贝到RAM开始的地址上,这里由于在RAM中调试,代码是直接下载到RAM中的,所以不用拷贝。
向量表已经在RAM中了,接下来要重定向向量表,以便在发生异常时到RAM中取得异常入口地址(默认情况下是在0x0取)。
后面的代码是拷贝数据到RAM中,搭建好C语言运行环境。
IARcortex-m4启动流 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)