Bootloader的含义:它是嵌入式系统在加电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运行。
在一些应用场景中,用户需要在Flash中存储多个应用程序,然后通过Bootloader来决定到底运行哪个应用程序。
在实现这个功能前需要先了解几个概念,首先,ARM是如何开始执行程序的,还有bin文件里包含的信息。
在ARM Cortex-M权威指南中有一段话:“在复位后以及处理器开始执行程序前,Cortex-M处理器会从存储器中读出两个字(1Word = 4Byte),它的头两个字为主栈指针(MSP)的初始值,以及代表复位处理起始地址的复位向量。处理器读出这两个字后,就会将这些数值赋给MSP和程序计数器(PC)”。
那么对应的其实就是bin文件的前两个字,bin文件是小端模式,就是说MSP = 0x200040A0;PC = 1000096D。
从工程的.map文件也能进一步确认这个点,后面的两个字其实就是NMI_Handler和HardFault_Handler的映射地址。
那么有了上面的认识之后,要实现跳转代码,归根到底其实就是将代码的MSP和PC装到内核当中即中断向量重映射(Cortex-M0就是装载到R0寄存器)。
第一步,我们需要在代码中指定一个装载地址,以便内核去寻址(这里必须分配好Flash的大小,看是否会冲掉其他数据或者代码)。
要注意的是,生成app.bin前需要先设置IROM1的地址且要与上图的地址一一对应,这样生成的bin文件才能被正确执行。
通过这种方式得到bin文件后,在Bootloader的工程中添加该bin文件的数组。
再通过下面的函数进行跳转,即可运行"application_1_bin"或其他的app.bin,不同的厂商对应的跳转方式和地址会有不同。
最后补充说明一下,现在很多芯片都是采用cache模式的,就是说代码并不是简单的上电就把代码从Flash全部搬到RAM中再执行的(PRAM模式),而是在cache中边搬边执行的,而cache本身就是一段特殊功能的RAM,只是它的作用区别于用户的Data RAM,所以这里存储的地址(类似0x1000096D)是cache的地址,而在芯片的总线上cache一般会映射到Flash中,比如0x10000000对应Flash的0x00000000,那么cache在上电的时候就会从flash的0x00000000位置开始搬代码,这个地址根据不同芯片厂商会不一样。
网友评论