0x03 LiteOS内核详解--stm32启动流程(下)
【摘要】 STM32复位后运行的第一条汇编代码当对STM32进行上电操作或者复位操作(按复位按钮,调用复位函数),STM32就会跳转到“中断向量表”中的地址0x0000_0004处执行已经写好的Rest_Hander处理函数,该函数使用汇编语言写的,在LiteOS中的如下位置“liteos\arch\arm\arm-m\armv7-m\gcc\los_startup.S”, 1. Reset_Han...
STM32复位后运行的第一条汇编代码
当对STM32进行上电操作或者复位操作(按复位按钮,调用复位函数),STM32就会跳转到“中断向量表”中的地址0x0000_0004处执行已经写好的Rest_Hander处理函数,该函数使用汇编语言写的,在LiteOS中的如下位置“liteos\arch\arm\arm-m\armv7-m\gcc\los_startup.S”,
1. Reset_Handler:
2. cpsid i
3. ldr sp, =_estack /* set msp, as it is not set in the vector */
4.
5. #if defined (__VFP_FP__) && !defined(__SOFTFP__) /* if FPU exist. */
6. /* enable FPU */
7.
8. ldr r0, =0xE000ED88
9. ldr r1, [r0]
10. orr r1, r1, #(0xf << 20) /* enable cp10 cp11 both */
11. str r1, [r0]
12. #endif
13.
14. /* init the data section */
15.
16. ldr r1, =_sdata
17. ldr r2, =_edata
18. ldr r3, =_sidata
19. 0:
20. cmp r1, r2
21. beq 0f
22. ldr r0, [r3], #4 /* 将_sidata地址对应内存中的数据读到r0中,并将_sidata地址加4 */
23. str r0, [r1], #4 /* 将R0中的数据写到_sdata地址对应内存中,并将_sdata地址加4 */
24. b 0b
25. 0:
26.
27. /* init the bss section */
28.
29. mov r0, #0
30. ldr r1, =_sbss
31. ldr r2, =_ebss
32. 0:
33. cmp r1, r2
34. beq 0f
35. str r0, [r1], #4
36. b 0b
37. 0:
38. bl SystemInit
39. bl __libc_init_array
40. bl main
41.
42. b .
43.
44. .size Reset_Handler, . - Reset_Handler
第2行:关闭所有中断,等价于PRIMASK=1
第3行:读取栈顶指针并赋值给sp寄存器,这个“_estack”符号的值定义在链接脚本中,os.ld文件* 中,取决于芯片RAM大小。
第5~11行,MPU初始化,暂不讲解。
第16行,将_sdata段的起始地址赋值给r1寄存器
第17行,将_edata段的起始地址赋值给r2寄存器
第18行,将_sidata段的起始地址赋值给r3寄存器
上面这三个符号的值都来自于os.ld文件中,_sdata~_edata之间的空间用于存放全局变量的值,所以在初始化中,需要将这块空间清0。
第19~24行,首先使用cmp r1, r2判断r1和r2寄存器中的值是否相等也就是_sdata和_edata的值是否相等,一开始肯定不相等,就不执行跳到0f地址处的这条指令了,注意:0f和0b这样写法你们可能很少见,0是标签0,就是代码块前面的那个0,我们的这个文件中有很多为0的标签,所以就通过b=backward和f=forward来区分是跳到后面的标签0处还是前面的标签0处,前面和后面不好区分,可以根据back单词有返回的含义来进行区分。
总体看来19~24行就是一个for循环,判断退出循环的条件是_sdata和_edata的值是否相等,在循环中将全局变量的数据从flash拷贝到ram的加载地址对应空间中。
ldr R0,[R3],#4 ;将存储器地址为R3的字数据读入寄存器R0,并将R3+4的值存入R3。
str R0,[R1],#4 ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+4写入R1
第29-36行,采用上面的类似于“for循环”的方法将.bss段清0.
第37-40行,执行SystemInit函数,用C语言在外部实现的,执行__libc_init_array函数,执行我们的main函数,单片机就转起来了!
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)