上一篇讲述了如何使用MDK-ARM快速评估一个应用程序:按键调整LED灯的亮否。但仍然不知道该如何入手开始自己的开发,这一篇讲述程序是如何启动及用户程序的基本配置等内容,了解了这些就知道程序的来龙去脉,我们也可以根据需要添加自己的应用了。但,为了能够获取更多的信息,读者需要根据文中的提示,阅读更多的书籍资料,来补充背后的更加详细的内容。 1.启动代码
什么是启动代码?通俗的讲,启动代码是指应用程序工程为了进入C/C++语言程序前的配置工作而写的汇编代码。如果应用程序工程只使用汇编语言编写程序,那么就没有所谓的启动代码。绝大多数嵌入式应用程序都是使用C/C++编写的,即使内嵌了汇编程序,也是需要启动代码的,因为只要用到C/C++语言,就需要在正常试用C/C++之前对其进行初始化,没错,试用C/C++之前要对其进行初始化。更多信息请参考[1]《Libraries and Floating-Point Support User Guide》中的“The ARM C and C++ Libraries->Tailoring the C library to a new execution environ->Initialization of the execution environment and execution of the application”小节。
启动代码除了完成C/C++库的初始化外,更重要的还需要根据Cortex-M内核的需要完成内核的配置和初始化。Cortex-M程序映像一般包括如下几个部分:1.向量表。2.C/C++启动例程。3.程序代码。4.C/C++库代码。一般情况下启动代码完成1和2,编译器会根据需要把C/C++库代码自动添加到程序映像中去。我们只需要关注自己的程序代码部分。但理解启动代码有助于理解程序的来龙去脉,并能够掌握程序的运行。
向量表其实就是按照既定的顺序排列的数组,数组的每个成员都是内核定义好的内容,大小是4个字节。这个既定的顺序就是Cortex-M内核规定的,必须服从的,向量表即:栈顶指针、复位异常、不可屏蔽异常、硬件错误异常、MPU错误异常、总线错误异常、未定义指令异常等,还有其它的中断等。向量表中除了栈顶指针指向的是一个栈外,其它的都是函数指针,当异常或中断被触发时程序就会按照向量表中保存的函数指针调用该函数。这个触发、调用过程是内核自动实现的,所以向量表是有顺序的,比如,不能把复位异常和不可屏蔽异常的内容调换,否则执行的功能也就调换了,因为内核不知道函数指针指向的是哪个意义的功能函数,只知道调用这个函数指针并执行这个函数。更多细节参考[2]。
MCU上电并从flash启动后,首先从向量表中取得第一个成员:栈顶指针,并赋值给MSP寄存器;然后再取得向量表中的第2个成员复位异常,并赋值给PC寄存器,这样MCU根据PC寄存器的内容就开始了程序的执行。为什么会首选取得栈顶指针而不是其它成员,这是因为有可能执行其它功能时会出现异常或中断,而此时需要有栈的支持,所以必须先把栈初始化完成,然后再执行其它功能,这样即使出现异常,程序也会根据异常处理错误。那如果在取第一个成员栈顶指针时出现异常怎么办?MCU会进入锁定状态,更多信息可以参考[2]。
我们知道内核的执行其实是个状态机的执行,它按照既定的方案执行处理功能。而向量表就是状态机中非常重要的数据来源,那就是出现异常或中断时,状态机会自动获取向量表的内容,这也就是为什么向量表是有顺序的,当然,向量表也是有大小的,不同的内核有不同的大小。还有一个也是非常明确的,向量表的地址是确定的,对于状态机来说,只要从0x00000000地址处获取的就是栈顶指针,从0x00000004地址处获取的就是复位异常,等等依次类推。如果你的程序用不到除栈顶指针和复位异常外的其它向量成员,则可以不指定他们的值,这样状态机也就不会充其它向量成员中获取值,你的程序照样运行的很好,但这只是理论上如此,实际中你应当至少定义15个向量来满足基本的应用。
STM32F469I-Disvoery使用的MCU:STM32F469NIH6是基于Cortex-M4内核的,Cotex-M4内核的向量表是确定的。我们参考GPIO_EXTI示例程序给的向量表来具体说明,见下图。
3.参考资料
[1] 《Libraries and Floating-Point Support User Guide》,ARM Compiler v5.06 for uVision ARM C and C++ Libraries and Floating-Point Support User Guide。
[2] 《The Definitive Guide to Arm Cortex-M3 and Cortex-M4 Processors, Third Edition》。
[3] 《ARM Compiler v5.06 for µVision armasm User Guide》