嵌入式开发(4)启动文件理解

系列文章目录

嵌入式开发中断全解(1)
嵌入式开发中断全解(2)Hard Fault的诊断
嵌入式开发中断全解(3)外部中断和内部中断例程

这里说的启动文件代表硬件是STM32中的。

一、复位顺序

《Cortex M3与M4权威指南》章节4.8 P113
在这里插入图片描述
链接:https://pan.baidu.com/s/1Panqvf1PdIvYMGnOPdR64g
提取码:baba
在这里插入图片描述
After reset and before the processor starts executing the program, the Cortex-M processors read the first two words from the memory . The beginning of the memory space contains the vector table, and the first two words in the vector table are the initial value for the Main Stack Pointer (MSP), and the reset vector, which is the starting address of the reset handler . After these two words are read by the processor, the processor then sets up the MSP and the Program Counter (PC) with these values.
重置后,在处理器开始执行程序之前,Cortex-M处理器从内存中读取前两个单词。内存空间的开头包含向量表,向量表中的前两个单词是主堆栈指针 (MSP) 的初始值,而重置向量是重置处理程序的起始地址。在处理器读取这两个单词后,处理器然后使用这些值设置MSP和程序计数器(PC)。
建议下载个有道云词典,ctrl++alt+d截图翻译好用的不行, 英语好的当我没说哈哈哈哈!!

二、启动文件

1.定义
启动文件由汇编编写,是系统上电复位后第一执行的程序,后缀.s的文件。用汇编得原因可能是考虑执行效率的问题,不需要初始化栈,上电就能运行,但国产厂家不提供gcc就有点麻烦了。
2.特征
(1)初始化堆栈指针,主要是为 C 语言提供良好的运行环境。注意:了解堆栈之前得了解内存分配。例如:_initial、_sp、_heap_base可在map文件只能看到_sp的地址安排,却找不到_heap_base因为工程代码没有涉及到堆的操作,编译的时候就没分配堆的,地址相关信息,但启动文件有针对heap(堆)的配置,这时候Heap_size分配多大都没有实际意义,不管是你写0还是0x0000200都是没有差别的,就像写的代码定义了完全没有用到的变量一样,编译时不会安排内存空间;若使用了malloc(),calloc()这两个函数就是申请堆空间的,这时候再去启动文件中的heap进行配置地址信息就会出现了,注意:在用户代码里做内存动态分配时注意分配的而空间大小,要遵循启动文件里的heap大小限制,必要时要做一些相对应的调整。

除了上诉堆的分配,我们会发现启动文件会用掉1kb的RAM,当你查看stm32编译的map文件时会发现单单一个启动文件就用掉了1024bit的RAM,单片机的存储都是很宝贵的,如果单纯只是初始化不会用到那么多,其实这1024bit是给栈用的,0x400=1024字节,有时候得根据工程取改变栈如图2,反之如果涉及得局部变量较少,中断嵌套情形也不多,完全可以将栈数据设计得小些
在这里插入图片描述
/*********************************************图1 *****************************************************/
图1
/*********************************************图2 *****************************************************/

(2)进行复位处理,执行该 Reset_Handler 函数
(3)初始化向量表,异常入口地址列表
在这里插入图片描述
注意:自己写的中断函数要和向量表的中断函数名一样。
弱声明_weak、向量表的中断名、DCD的。尽量不要取改动。
(4)配置系统的时钟,调用 SystemInit
(5)调用 C 库函数__main 进入 main.c 中的 mai n 函数执行

三、异常向量表

1、8051

AT89S51 共有 5 个中断源:2 个外部中断、2 个定时器中断、1 个串口中断。

中断源		入口地址 	中断号
外部中断 0 		0003H 		0
定时器 0 		000BH 		1
外部中断 1 		0013H 		2
定时器 1 		001BH 		3
串口中断 		0023H 		4

在这里插入图片描述

2、STM32

《Cortex M3与M4权威指南》章节7.3 P235

(1)背景

In most typical applications, this is all you need to do. When the interrupt triggers, the corresponding Interrupt Service Routine (ISR) will execute (you might need to clear the interrupt request from the peripheral within the handler). The name of the ISR can be found inside the vector table inside the startup code, which is also provided by the microcontroller vendor. The name of the ISR needs to match the name used in the vector table so that the linker can place the starting address of the ISR into the vector table correctly.
重点细节:中断服务函数的指定运行,由编译链接阶段已经决定好。

(2)分析向量表中0x00000058地址装载的函数地址

(1)经过MDK编译完成后,会输出一个*.map文件,里面存储了以下主要信息:
Section Cross References:模块、段(入口)交叉引用;
Removing Unused input sections from the image:移除未使用的模块;
Image Symbol Table:映射符号表;
Memory Map of the image:内存(映射)分布;
Image component sizes:存储组成大小。

我们需要重点关注的是“Image Symbol Table”,里面描述了各种符号的映射地址,其中包含了各个函数的地址,通过该文件,可以找到EXTI0_IRQHandler函数地址为0x08000383,如下图。
在这里插入图片描述
高地址保存低字节 低地址保存高字节。这里科普个c语言大端序,小端序的知识。
大小端序:
在不同的计算机中他的存储策略有可能有差异,就大端、小端序
大端序:
高有效位存放与低地址
比如数据为 12345

在这里插入图片描述
小端序:
低有效位存放与低地址
比如数据为 12345

在这里插入图片描述
(2)使用MDK仿真访问向量表中0x00000058地址上装载的内容。
在这里插入图片描述
通过上图观察到,向量表中0x00000058地址上装载的内容恰恰是EXTI0_IRQHandler函数地址0x08000383。也就是说,在代码的链接阶段,链接器将匹配正确的中断服务函数起始地址放到对应的向量表入口地址中。

(3)有效的中断跳转

在这里插入图片描述
void EXTI0_IRQHandler(void)中断服务函数。

(4)无效的中断跳转(未编写中断服务函数情况)

在这里插入图片描述
WEAK关键字:
表示弱声明,若外部文件没有声明EXTI0_IRQHandler函数,则在编译链接的阶段,链接本汇编起始startup_stm32f40_41xxx.s文件即启动代码中的EXTI0_IRQHandler函数。反之,链接外部文件中的EXTI0_IRQHandler函数。

B . :
等同于一个while(1)循环,作用是捕获有问题的中断。例如中断服务函数名字有误或跟没有编写。当产生中断请求后,则跳转到启动代码中的中断服务函数执行程序,但启动代码中的中断服务函数是空函数,程序又得向下执行,最后被“B .”捕捉到。
``

该工程是实验的。按下按键,产生中断,并不是直接跳转到中断服务函数地址。
在这里插入图片描述
在这里插入图片描述
工程代码:
链接:https://pan.baidu.com/s/1gl9O4gvpbFj7V3RZbEN1pQ
提取码:baba

总结

多多指教,努力成为”栈溢出“工程师!!!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yank_k

点个关注加分享,一起探讨学习!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值