了解BootLoader——基于MPC5744P Bootloader例程
一、BootLoader的作用:BootLoader是固化在PFlash中的一个程序,其作用可以分为两部分:boot和load。
(1)boot:MCU上电时首先会运行BootLoader程序(因为它一般位于PFlash最前面的启动区,接下来会谈到启动区Boot location的概念),BootLoader程序会初始化系统时钟、看门狗等以保证系统的正常运行,此外还会初始化CAN(也可以是串口、SPI等)以实现和上位机的通信。
(2)load:系统初始化完成后,程序会进入等待状态,如果在预定时间内没有接收到上位机的程序下载请求信号(CAN帧),则跳转并执行MCU内部原有的用户应用程序(位于PFlash的其他启动区)。如果在预定时间内接收到来自上位机的程序下载请求信号,则BootLoader程序进入新程序下载状态。下载过程中,上位机与BootLoader程序之间采用一问一答的方式逐行的下载S19文件(用户应用程序的可执行文件)并进行解析,得到程序地址和程序数据,从而将每一行程序数据按照程序地址写入到PFlash中。程序下载完成后,清除RAM,关闭CAN等BootLoader用到的外设,跳转到新的用户应用程序并开始执行。
二、Boot location的概念:Boot location就是每次MCU复位后运行BAM(Boot Assist Module)时寻找合法复位配置半字RCHW(Reset Configuration Harf-Word)和应用程序开始地址(Application Start Address,也可以叫做应用程序复位向量地址(Reset Vector)的区域。复位后CPU将从Boot location0~7依次查找由正确Boot_ID--0x5A组成的合法复位配置半字和应用程序开始地址,从而执行用户应用程序。MPC5744P有8个Boot location,在Flash Memory Map中标明了哪些block可以作为Boot location,如下图:
Boot location的组成如下图所示:
Boot location的起始位置是复位配置半字(RCHW),其结构如下所示。
只有设置了真确的BootID,该Boot location才被识别为可启动的,如BootLoader程序和用户应用程序生成的S19文件:
在BootLoader程序的S19文件第二行中,0x00F98000为Boot location_0的起始地址,也就是RCHW的地址,其中存放的数据为0x01_5A,RCHW的VLE位置1,BOOT_ID为0x5A,即配置该Boot location为可启动的。reserve的16-31位默认为0x00
从用户应用程序的S19文件第三行可以看到,0x00FA0004为用户应用程序开始地址(应用程序复位向量地址),其中记录的数据0x0100000为应用程序的复位函数地址,也就是应用程序真正开始执行的地址。因此,一般用如下方法实现到用户应用程序的跳转:
#define APP_StartAddr (*(uint32_t*)0x00FA0004)
(*(void (*)(void))(APP_StartAddr))();
三、BootLoader程序和用户应用程序App在PFlash中的位置关系(Flash分配)
对BootLoader程序和用户应用程序的 link_file做如下设置:
MEMORY //BootLoader
{ /*16 KB low flash memory block 2 (boot location 0) from 0x00F98000 to 0x00F9BFFF*/
/*16 KB low flash memory block 3 (boot location 1) from 0x00F9C000 to 0x00F9FFFF*/
/* use the low flash memory block 2 and 3(32KB in total) as bootloader area */ flash_rchw : org = 0x00F98000, len = 0x4
cpu0_reset_vec : org = 0x00F98004, len = 0x4 m_text : org = 0x00F99000, len = 28K /*code flash for bootloader interrupt vector table, startup and boot codes*/ m_data : org = 0x40000000, len = 384K /*system SRAM*/ local_dmem : org = 0x50800000, len = 64K /*CPU core data tightly coupled memory*/
}
MEMORY //User App
{ flash_rchw : org = 0x00FA0000, len = 0x4
cpu0_reset_vec : org = 0x00FA0004, len = 0x4 m_text : org = 0x1000000, len = 2048K
m_data : org = 0x40000000, len = 384K local_dmem : org = 0x50800000, len = 64K
}
则BootLoader和App的在PFlash中的关系如下:
四、S19文件结构:
五、数据对齐问题:
例程中的对齐函数主体及注释如下:
stafno = (srcd_t->addr&0x7)>>; /* number of uint16_t need to be pre-staffed */ //if addr is not a multiple of 8-Bytes, get the surplus bytes then >>1
srcd_t->addr &= 0xFFFFFFF8; /* align data base address at 4W */ //about why >>1(divided by 2 regardless odd num addr): maybe there isn't odd address if(stafno)
{
for(i=srcd_t->dtlen; i>; i--)
srcd_t->data[i+stafno-] = srcd_t->data[i-]; // move forward data in number of stafno srcd_t->dtlen += stafno; // update dtlen while(stafno--)
srcd_t->data[stafno] = 0xFFFF; // pre-staff 0xFFFF
} while((srcd_t->dtlen&0x000003)!=) // need to append post-staffing uint16_t //if data num is a multiple of 4(each data is uint_16, so it's a judge of 64bits - 8bytes)
srcd_t->data[srcd_t->dtlen++] = 0xFFFF; //if not enough 4*uint_16 - 8bytes, padding with 0xFFFF behind data's tail
}
// conclusion: address is aligned with 8bytes by &0xFFFFFFF8, but data field will not move accordingly,
// it just padding with 0xFF in the front of array, so as to accord with origin address(0x0004) correctly
//
// address data(uint16) address data(uint16)
// |0x0000| |0x0000|<-- 0xFF
// |0x0002| after |0x0002| 0xFF
// |0x0004|<-- 0x55(data[0]) =======>> |0x0004| 0x55
// |0x0006| 0x66 address |0x0006| 0x66
// |0x0008| 0x77 align |0x0008| 0x77
// |0x000A| 0x88 |0x000A| 0x88
// |0x000C| |0x000C|
//
// note: (1) i guess that 0xFF will not be recognized as a instruction by CPU, so CPU fetch instruction from 0x0000
// but execute from 0x0004 in fact.
// (2) and note that the graph above is base on the struct SRecord_t,
// so that data[0] is always correspond with base address(SRecord->addr)
其中srcd_t的结构如下:
typedef struct {
uint32_t addr;
uint32_t dtlen; // num of valid data
uint16_t data[];
} SRecord_t;
另外,关于数据对齐问题,可以参考博文:https://blog.csdn.net/maxlovezyy/article/details/70231804
六、其他:下图为建立多核工程时的Flash和RAM资源的分配,可以用来参考以加深对程序在内存中的存储的理解
了解BootLoader——基于MPC5744P Bootloader例程的更多相关文章
- STM32 Bootloader基于ymodem传输协议串口IAP升级详解
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...
- nrf52——DFU升级USB/UART升级方式详解(基于SDK开发例程)
摘要:在前面的nrf52--DFU升级OTA升级方式详解(基于SDK开发例程)一文中我测试了基于蓝牙的OTA,本文将开始基于UART和USB(USB_CDC_)进行升级测试. 整体升级流程: 整个过程 ...
- PIC18 bootloader之UART bootloader
了解更多关于bootloader 的C语言实现,请加我Q扣: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 应客户要求, 将PIC ...
- nrf52——DFU升级OTA升级方式详解(基于SDK开发例程)
在我们开始前,默认你已经安装好了一些基础工具,如nrfutil,如果你没有安装过请根据官方中文博客去安装好这些基础工具,连接如下:Nordic nRF5 SDK开发环境搭建(nRF51/nRF52芯片 ...
- S32Kxxx bootloader之UDS bootloader
了解更多关于bootloader 的C语言实现,请加我Q扣: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 两周前完成了基于UDS ...
- 【Bootloader】探究bootloader,分析u-boot源码
Preface 之前也发表过关于<Bootloader启动过程分析>的文章,但是内容表达得比较抽象,大多是文字叙述,所以这里从系统和代码的角度来深入分析bootloader的启动过程. 工 ...
- BLE CC2541 串口BootLoader 即 SBL BootLoader 资料 收集
1.[CC254X_Bootloader]SBL(串口Bootloader)使用说明 2.CC2540协议栈高速串口通信解决(UART的DMA方式) 3.[BLE]CC2541之SBL 4.[BLE] ...
- PIC16 bootloader之UART bootloader
了解更多关于bootloader 的C语言实现,请加我Q扣: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). PIC16 bootl ...
- PIC18 bootloader之CAN bootloader
了解更多关于bootloader 的C语言实现,请加我Q扣: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). PIC18 ...
随机推荐
- Java I/O系统学习系列五:Java序列化机制
在Java的世界里,创建好对象之后,只要需要,对象是可以长驻内存,但是在程序终止时,所有对象还是会被销毁.这其实很合理,但是即使合理也不一定能满足所有场景,仍然存在着一些情况,需要能够在程序不运行的情 ...
- 梯度下降法及一元线性回归的python实现
梯度下降法及一元线性回归的python实现 一.梯度下降法形象解释 设想我们处在一座山的半山腰的位置,现在我们需要找到一条最快的下山路径,请问应该怎么走?根据生活经验,我们会用一种十分贪心的策略,即在 ...
- 远程传输命令scp
Linux scp 命令用于 Linux 之间复制文件和目录. scp 是 secure copy 的缩写, scp 是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令. scp 是加 ...
- IPv6笔记-地址结构与分类
1.地址基础 IPv6地址由被划分为8个16位块的128位组成. 然后将每个块转换为由冒号符号分隔的4位十六进制数字. 2001::3238:00E1:0063:0000:0000:FEFB 每一块多 ...
- springboot~高并发下耗时操作的实现
高并发下的耗时操作 高并发下,就是请求在一个时间点比较多时,很多写的请求打过来时,你的服务器承受很大的压力,当你的一个请求处理时间长时,这些请求将会把你的服务器线程耗尽,即你的主线程池里的线程将不会再 ...
- java遍历一个实体
//遍历order,得到属性值不为空的属性,type:操作类型.0是新增,1是更新 private Map<String, Object> reflect(Order order,Stri ...
- 【Java】final修饰符的使用
final修饰符的使用 1.修饰类: final修饰的类不能被继承,final修饰的类里面的方法都是(隐式)final方法 2.修饰方法: final修饰的方法不能被重写 3.修饰变量(被修饰的变量一 ...
- 【计算机网络】TCP基础知识详解
1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...
- shell脚本0——”一切皆文件“, 认识Shell
一.”一切皆文件“与“管道” 1)管道:grep foo /path/to/file | grep -n -k 3 | more 实际过程与我们直观认为的相反,最好通过实际过程理解.首先运行的是mor ...
- PL真有意思(一):引言
前言 断断续续学编译原理到之前发过写一个编译器和正则表达式引擎系列文章也有一段时间了,然后最近看完PLP这本书,这本书应该算是入门书,但是对我这种半吊子收获很大.所以为了弥补最近学操作系统和接外包摸的 ...