【5744】MPC5744入门笔记(4)基于Can的bootloader实现

0. 目录

文章目录

  • 0. 目录
  • 1 外设接口
  • 2 启动原理
    • 2.1 启动分区地址
    • 2.2 寻找启动分区
    • 2.3 实际测试
  • 3. 制作bin文件
  • 4. 升级
    • 4.1 flash划分
    • 4.2 升级协议
    • 4.3 升级机制
  • 5. 遇到的问题
  • 6. 参考链接
  • 7. 系列文章

1 外设接口

基于can接口的bootloader实现,当然要用的物理接口就是can接口和flash操作接口。

  • can
    包含can收can发,进行与上位机的交互。
  • flash
    包含flash的架构划分,flash的擦除和写入。
    另外要实现的就是跳转功能

2 启动原理

这部分在 MPC5744PRM 中写的很详细。
5744有2种启动模式:

  • SCL
  • SBL

这里我们主要看SC(single chip)模式,具体可以看56.4.5节。
在FLASH的一些sector,是boot location。芯片可以从这里启动。
复位后,PC指针不会再需要固定在一个固定的位置,比如stm32的0x8000000地址,mpc5744支持修改到不同的boot loaction。这个是在.ld文件中指定的。这个应该是cotex-m3内核和powerPC的区别。

2.1 启动分区地址

究竟哪些地址可以作为启动分区?在flash map中有列出。

Small flash
0x00F98000~0x00F9BFFF 16kb boot location 0
0x00F9C000~0x00F9FFFF 16kb boot location 1
Medium flash
0x00FA0000~0x00FAFFFF 64kb boot location 2
0x00FB0000~0x00FBFFFF 64kb boot location 3
Large flash
0x01000000~0x0103FFFF 256kb boot location 4
0x01040000~0x0107FFFF 256kb boot location 5
0x01080000~0x010BFFFF 256kb boot location 6
0x010C0000~0x010FFFFF 256kb boot location 7

以上8个分区可以作为启动分区。

2.2 寻找启动分区

芯片内部有8个分区可以做为启动分区,那系统如何去寻找?如何知道从哪个分区启动?

芯片从低到高去找对应的boot location,以找到 boot ID为准。
【5744】MPC5744入门笔记(4)基于Can的bootloader实现_第1张图片
每一个启动分区boot sector都在0偏移地址是RCHW(Reset Configuration Half-Word)。
RCHW的定义如下:
【5744】MPC5744入门笔记(4)基于Can的bootloader实现_第2张图片

如果BOOT_ID有0x5A,则说明可以用这个分区启动。
VLE是标明代码格式是否是VLE的,不太懂,略过。

找到了系统启动分区,PC指针是如何移动的,RPM也给了介绍:
在这里插入图片描述
一旦设备找到启动分区,就会从偏移为4的地方取出地址数据,跳转过去。

2.3 实际测试

我们的.ld文件声明如下:

MEMORY
{
    flash_rchw : org = 0x00FA0000, len = 0x4
    cpu0_reset_vec : org = 0x00FA0000+0x04, len = 0x4

    m_text : org = FLASH_BASE_ADDR, len = FLASH_SIZE
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
    local_dmem : org = LOCAL_DMEM_BASE_ADDR, len = LOCAL_DMEM_SIZE
}

单步调试过程中,去查看内存,可以看到:
整个bin是load到0x00FA0000地址的
【5744】MPC5744入门笔记(4)基于Can的bootloader实现_第3张图片

可以看到偏移地址为0的地方是0x5A00,确实是启动分区。
偏移位置为4的地方是启动地址,0x01000000。
跳转看一下,确实代码数据在这里
【5744】MPC5744入门笔记(4)基于Can的bootloader实现_第4张图片

和生成的二进制bin文件对比了一下,确实是一致的。

3. 制作bin文件

这一步操作和之前S32K144的操作是一致的(毕竟都是S32DS的开发环境)

  1. 在工程属性中使能Create flash image工具:
    选中应用工程右键–>Properities(属性)—>C/C++ Build—>Settings —>Tool Settings/ Croos settings–>勾选Create flash image,此时再编译会生成一个.srec后缀的文件,就是s19文件。
  2. 在general中选择对应的image格式,此时再编译,就会出现bin结尾的编译文件。

4. 升级

4.1 flash划分

BOOT

MEMORY
{
    flash_rchw : org = 0x00F98000, len = 0x4
    cpu0_reset_vec : org = 0x00F98000+0x04, len = 0x4

    m_text : org = 0x00F99000, len = 92k
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
    local_dmem : org = LOCAL_DMEM_BASE_ADDR, len = LOCAL_DMEM_SIZE
}

APP

MEMORY
{
    flash_rchw : org = 0x01000000, len = 0x4
    cpu0_reset_vec : org = 0x01000000+0x04, len = 0x4

    m_text : org = 0x01000400, len = 2047K  
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
    local_dmem : org = LOCAL_DMEM_BASE_ADDR, len = LOCAL_DMEM_SIZE
}

4.2 升级协议

在设计can升级的过程中,我并没有找到类似串口的Xmodeml,Ymodem,Zmodem这样成熟的协议,所以就自行设计了一种很简单的。
系统分成命令包,应答包,升级包等几种,利用第一个字节来划分。
将整个升级的bin包切分成若干个1k包,每个1k又切分成177帧can报文(每条报文有6字节的有效数据),加入每个1k包的应答重传等机制,1k包确认无误后写入flash。
全部完成后,做CRC校验,CRC校验通过,完成升级。

4.3 升级机制

升级实现我是用状态机来做的,这部分看不同的代码习惯。
升级过程每个过程有明确的状态,根据收到不同的上位机报文来做事件触发状态迁移。
状态迁移有明确的交互报文来做确认。

static FsmTable_t g_MvIapFsmTable[] =
{
	{FSM_NULL,					EVENT_NULL,						FSM_NULL,					NULL},
	{FSM_NULL,					NO_REQ,							FSM_NO_UPDATE,				Jump2App},
	{FSM_NULL,					REC_DETECT_REQ,					FSM_DETECT_ACK,				HandleDetectReq},
	{FSM_DETECT_ACK,			REC_UPDATE_REQ,				FSM_UPDATE_ACK,				HandleUpdateReq},
	{FSM_UPDATE_ACK,			REC_UPDATE_REQ,				FSM_UPDATE_ACK,				HandleUpdateReq},
	{FSM_UPDATE_ACK,			REC_UPDATE_DATA,			FSM_UPDATE,						HandleUpdateData},
	{FSM_UPDATE,				REC_UPDATE_DATA,			FSM_UPDATE,						HandleUpdateData},
	{FSM_UPDATE,				REC_UPDATE_OVER,			FSM_UPDATE_OVER,			HandleUpdateOver},
};
  1. 初始状态是NULL,如果无事件,不迁移。
  2. 如果300ms没收到扫描报文,则是NO_REQ事件,跳转到FSM_NO_UPDATE状态,同时执行跳转APP动作Jump2App。
  3. 如果收到扫描报文(REC_DETECT_REQ),进入应答扫描包状态,同时处理报文,上报自身的ID,当前版本等信息。
  4. 扫描交互完成后,如果收到升级包请求(REC_UPDATE_REQ),进入应答请求包状态,接收整个升级包的信息(长度,CRC等)
  5. 升级请求应答完成后,如果收到升级包数据,则真正进入升级状态。
  6. 升级完成后,收到升级结束的报文(REC_UPDATE_OVER事件),开始校验数据是否有错,没问题修改启动相关标志,下一次启动跳转新的APP即可。

5. 遇到的问题

  • 无法实现跳转运行
    使用开发板进行实际调试(调试器openSDA)过程中,在烧录boot时,烧录器会把App擦除,需要添加对应的保护,否则无法跳转。
    【5744】MPC5744入门笔记(4)基于Can的bootloader实现_第5张图片

  • 跳转后Can无法正常运行。
    之前怀疑是bootloader里用了can,没有关干净导致的,或者是app的中断不能正常。
    但测了,都不是。
    这部分还在查,有结果后我会更新上来

  • Mpc5744生成的bin太大了。
    功能差不多的代码,MPC5744做出来的bin比st的我感觉要大出来3~4倍。不知道是不是优化选项的问题。
    暂时还没找到解决方法。

6. 参考链接

MPC5744 官网 PRM

7. 系列文章

【5744】MPC5744入门笔记(1)开发环境搭建
【5744】MPC5744入门笔记(2)CAN实验
【5744】MPC5744入门笔记(3)Flash实验

你可能感兴趣的:(【5744】MPC5744入门笔记(4)基于Can的bootloader实现)