HCS12加载RAM并执行Bootloader用户指南

需要实现远程升级单片机,正好在网上找到了官方提供的Bootloader程序及其对应的文档,赶快弄下来学习研究,这是对其文档的翻译。

翻译的资料是公开的,在这里下载https://www.nxp.com/products/microcontrollers-and-processors/additional-processors-and-mcus/8-16-bit-mcus/16-bit-s12-and-s12x-mcus/ultra-reliable-s12xe-high-performance-automotive-and-industrial-microcontrollers:S12XE?tab=Documentation_Tab,我想应该不会有什么版权问题,如涉及版权问题,请联系我删除文章。另感谢NXP提供的学习资料。


HCS12 Load RAM and Execute Bootloader User Guide

by:Martyn Gallop
Joanne McNamee

译者注:译者博客(http://blog.csdn.net/lin_strong),转载请保留这条。此为官方文档AN2546,仅供学习交流使用,请勿用于商业用途。

介绍

这篇用户指南介绍了一个为飞思卡尔HCS12微控制器家族开发的加载RAM并执行(LRAE)bootloader。

LRAE Bootloader综述

LRAE bootloader可以很方便地实现生产中编程或者“在线系统(in-system)”编程,特别是应用于那些 无法使用HCS12背景调试接口(BDM)的场合。用户必须在生产准备阶段或在编程供应商那预编程HCS12。Bootloader的实现使它能够留存在MCU中以供未来使用。

这个bootloader实现 支持通过CAN或SCI串口将用户软件下载进MCU的RAM中。bootloader会轮询CAN和SCI端口以等待消息。当收到了一条消息,bootloader会尝试用多个可能的波特率与进入的通信进行匹配。当用户软件被下载入RAM后,就会运行放在RAM中的代码。

bootloader软件是使用模块化的方式开发的,这使得它能被很方便地移植到不同的HCS12设备上,不同的设备上的编程方式是不同的。LRAE bootloader最初在以下飞思卡尔HCS12设备上进行了测试:
D32、D64、Dx128、Dx256、DP512、A32、A64、A128、A256、A512、C32、C128、E128和 B128。这其实最初是一个对 地址映射部分 的资源分配的练习。

缩略词

缩略词 英文全名 中文全名
CAN controller area network 控制器区域网络
LRAE load RAM and execute 加载RAM并运行
LSB least significant byte 最低有效字节
MCU microcontroller unit 微控制单元
MSB most significant byte 最高有效字节
RAM random access memory 随机访问内存
SCI serial communications interface 串行通信接口
UART universal asynchronous receiver transmitter 通用异步收发器
Tq CAN time quanta CAN 时间量子

功能描述

运行

bootloader默认会在上电重置后操控MCU;重置向量会指向bootloader代码地址。

首先,bootloader会检查在FLASH地址0xC000-0xC001处的这个word。如果这个word被擦除了,bootloader就会开始执行,并轮询CAN和SCI端口以等待消息。但是如果,这个word被设置过了,bootloader就会跳转到这个word指向的那个地址,并运行这个位置的应用程序。

如果你不需要bootloader功能,你必须在重新编程FLASH前擦除包含bootloader代码的FLASH内存区域以及重置向量。默认的,bootloader代码的FLASH保护没有启用。

应用程序启动向量

如果你想要在你的应用中保留bootloader,你必须修改地址0xC000-0xC001处的word为你的应用程序的起始地址。

在使用了这个bootloader并且把一个应用编程入FLASH后,实际的应用程序启动向量放在0xC000–0xC001。

地址映射

bootloader被放在了FLASH分页0x3E中。bootloader的起始地址是0x4000。默认的,MCU重置向量编程在这个地址。

在一些情况下,你可能想要重编程MCU FLASH内存的0x3F页,擦除MCU向量。为了保留bootloader的功能,你必须修改MCU的上电重置向量为bootloader的起始地址(0x4000)。

如果应用程序启动向量没有被编程过,bootloader会在启动LRAE下载前重映射设备内存资源。

不同HCS12 MCU上的RAM有着不同的大小,并且,默认情况下,会被映射到内存地址的最低16K字节(0x0000–0x3FFF)的顶或底。

bootloader会如 表 1. LRAE Bootloaer RAM重映射 中定义的那样重映射RAM块到个位置,这是通过初始化INITRM寄存器为0x39实现的。

寄存器块还在默认位置,起始于0x0000(INITRG中写入了0x00)。

在拥有用户EEPROM的设备中,EEPROM被重映射为 自0x0800起始(INITEE中写入了0x09)。

表 1. LRAE Bootloaer RAM重映射

设备 RAM大小 RAM重映射 用于下载的RAM
D32 2K 0x3800-0x3FFF 0x3800-0x3FCF
D64 4K 0x3000-0x3FFF 0x3000-0x3FCF
D128 8K 0x2000-0x3FFF 0x2000-0x3FCF
D256 12K 0x1000-0x3FFF 0x1000-0x3FCF
D512 14K 0x0800-0x3FFF 0x0800-0x3FCF
A32 2K 0x3800-0x3FFF 0x3800-0x3FCF
A64 4K 0x3000-0x3FFF 0x3000-0x3FCF
A128 8K 0x2000-0x3FFF 0x2000-0x3FCF
A256 12K 0x1000-0x3FFF 0x1000-0x3FCF
A512 14K 0x0800-0x3FFF 0x0800-0x3FCF
C32 2K 0x3800-0x3FFF 0x3800-0x3FCF
C128 4K 0x3000-0x3FFF 0x3000-0x3FCF
E128 8K 0x2000-0x3FFF 0x2000-0x3FCF
B128 4K 0x3000-0x3FFF 0x3000-0x3FCF

0x3FD0-0x3FFF这段地址范围是预留给bootloader的栈和变量使用的。如表一所定义的所有剩下的RAM都可以用于下载代码。

当开始执行下载下来的代码后,bootloader 就失业了,这时预留的RAM就可以被下载下来的代码用作放数据的RAM了。

表 2.LRAE Bootloader代码映射 展示了各个设备上为bootloader保留的FLASH地址范围。

表 2.LRAE Bootloader代码映射

设备 FLASH地址
Dx512 0x4000-0x4400
Dx256 - 2 CAN 0x4000-0x4400
Dx256 - 3 CAN 0x4000-0x4400
Dx128 - 2 CAN 0x4000-0x4400
Dx128 - 3 CAN 0x4000-0x4400
Dx64 0x4000-0x4400
D32 0x4000-0x4400
A512 0x4000-0x4200
A256 0x4000-0x4200
A128 0x4000-0x4200
A64 0x4000-0x4200
A32 0x4000-0x4200
B128 0x4000-0x4400
C32 0x4000-0x4400
C128 0x4000-0x4400
E128 0x4000-0x4200

通信速度

bootloader会尝试匹配从CAN和SCI进来的通信的波特率,同时考虑了多种晶振频率。bootloader被设计用于4MHz、8MHz和16MHz这三种晶振频率。下表给出了各个晶振频率下,bootloader会尝试匹配的可能的CAN和SCI总线速率。

对于CAN总线,接收和传输缓冲会使用标准ID长度(11 bit)。

每个CAN比特率都是为大约42,000总线时钟周期选择的(约5ms @ 16MHz)。

表 3. CAN端口配置值

配置 1 2 3 4 5 6 7 8 9 10 11
Prescaler 1 1 2 4 8 4 8 16 5 10 20
Tseg1 5 13 13 13 13 9 9 9 13 13 13
Sync seg 1 1 1 1 1 1 1 1 1 1 1
Tseg2 2 2 2 2 2 2 2 2 2 2 2
Jump width 2 2 2 2 2 2 2 2 2 2 2
Tq/bit 8 16 16 16 16 12 12 12 16 16 16

表 4.CAN配置选项
CAN配置选项

对于SCI总线,bootloader会尝试使用列在 表 5.SCI端口波特率 中的预分频值来通信。这些SCI波特率会被选为最接近标准波特率的那个,这取决于HCS12预分频的实现。

实际的HCS12波特率 = SCI模块时钟频率 / (Prescaler * 16)

其中,SCI模块时钟频率 = 晶振频率 / 2

SCI通信总时间误差应该<3.9%。这可以通过使用常用的UART波特率(用括号括起来的)来实现。主机可能支持更高的波特率,但不适用常用UART通信设置。

bootloader会尝试在每个波特率接收同步字节两次,然后再换到下一个。

对于SCI总线,数据格式是:1起始位、8数据位、1停止位、无校验位。

用户需要保证用其中一个波特率进行通信。

表 5.SCI端口波特率
SCI端口波特率

使用的通信模型

bootloader会尝试与多个CAN和SCI端口通信,当然这要看具体设备。通信模型支持CAN0、CAN1、CAN4、SCI0和SCI1。

所有的通信模型都使用默认的I/O赋值。bootloader不修改module rerouting寄存器的值。

硬件兼容性

bootloader会尽量避免与现存的应用硬件竞争。HCS12上的I/O引脚默认是用于输入(其中一些会使能内部上拉设备)。

CAN和SCI总线端口引脚都被配置为运行于一般(push-pull)模式、全功率驱动、没有使用内部上拉设备。

对于SCI总线,一开始只使能了接收器。SCI发送引脚只在从主机探测到同步字节后才会被使能为输出。

在初始化一个CAN模块之前,bootloader会先测试以确保:
1. Tx引脚被上拉到5V
2. Tx引脚可以被驱动为低电平
3. Tx上的低电平会被Rx引脚探测到(对于16MHz晶振,在约3us后)。

如果其中之一的测试失败了,CAN模块就不会被初始化,对应的引脚仍然是输入方向。

Bootloader工作流程

启动:
如果0xC000-0xC001被赋予过值(即FLASH应用起始地址)的话,跳转去执行应用
配置MCU资源
LRAE 初始化:
    for each(CAN模块):
        if(探测到CAN物理接口)
            配置初始比特率
        if(CAN物理接口与总线同步 (= 活跃))
            CAN进入睡眠模式
    for each(SCI模块):
        配置首个SCI模特率
        使能Rx
主循环:
    for each(激活的CAN模块):
        if(CAN模块被唤醒了)
            if(已经接收到了地址指针信息)
                完成从CAN模块的下载,并跳到下载的代码
            elseif(数据没收到且已超时)
                切换到下一个比特率
            elseif(数据没收到但没超时)
                递增模块超时计数器
    for each(SCI模块):
        if(已经收到了数据字节)
            if(数据是有效的同步字符)
                答复确认字节
                完成从SCI的下载并跳到下载的代码
            elseif(数据字节连着两次不是同步字节)
                切换到下一个波特率
跳回 主循环

CAN通讯结构

CAN总线协议有消息应答机制。因此,主机的程序流可以简单地照着 图1.CAN通讯流 那样设计,在继续之前检查有没有CAN错误。bootloader支持通过CAN总线发送以下命令。

通过使用上面的CAN消息,主机必须发送CAN消息到MCU,如 图1.CAN通讯流程 中流程图列出的那样。

首先,主机需要设置地址指针。bootloader在探测到有效的设置地址指针消息之前是不会与总线同步LRAE比特率的。

然后应该发送程序数据,最后跟着校验码。MCU返回给主机对校验码的确认。这样主机就知道是否有校验错误。

因为LRAE校验码是在每次收到 设置地址指针消息 时被初始化的,主机实现可以支持重新发送数据或者不连续的数据。

当所有的数据都被成功地下载了,主机可以发送一个 执行命令消息 以开始代码执行。

CAN通讯 — 基础主机

CAN通讯流程
图 1.CAN通讯流程

SCI通讯

SCI从主机到MCU的消息通讯被列在流程图 图 2.SCI通讯流程图 中。为了匹配波特率,主机必须:
1. 传送同步消息(0x55)
2. 等待 10bit的时间以传输0x55+ 约1ms的延时 + 10bit的时间以等待一个0xAA答复。
3. 重复直到收到一个同步确认消息(0xAA)。

一旦收到了同步确认字节,MCU就建立了正确的通讯速率。

主机软件必须发送消息以设置MCU的地址指针,紧接着发送 描述会传输多少字节数据的消息。在这之后,就可以发送编程数据到MCU去了。

bootloader然后就会请求主机发送一个校验码。校验码是从地址指针(含)到程序数据最后一个字节的所有字节的和(模 256)。如果校验正确,MCU就会发送回校验和确认字节(0x80)并开始执行下载到RAM中的代码。如果校验和校验错误,bootloader就会停止并等待外部重置。主机应该实现在校验和请求之后的超时处理。

SCI通讯结构 — 主机

图 2.SCI通讯流程图 中列出了主机到SCI通讯的流程图。

SCI通讯流程图
图 2.SCI通讯流程图

限制与思考

这个bootloader由于是通用的,它不为特定的用户应用开发。这导致了一些妥协和限制,你应该要意识到它们。
1. 这个bootloader并没有FLASH存储器的编程例程。可以从Freescale的官网 http://www.freescale.com 上找到用于HCS12嵌入式应用的FLASH编程驱动以及BDM编程工具”HCS12 SGF NVM Standard Software Driver” (HCS12SGF25NVMSSD)。想找到它们的话,进入 Support/Design Tools 并选择 Microcontrollers然后选择Device Drivers。开发一个可以通过bootloader下载并执行的FLASH的编程应用可能十分有用。
2. 这个LREA bootloader不在重置后改变任何I/O口的状态,除了与对应CAN和SCI外设相关的那些。应该要在设计时考虑一下哪个端口默认使用内部上拉以及哪个默认是高阻抗输入以评估在不同设备上使用时的默认状态兼容性。
3. 这个bootloader没有启用COP看门狗定时器。如果下载代码需要COP功能,那么必须启用它。
4. 这个bootloader不提供外部看门狗设备的支持。应该要不设计一个禁用功能,要不在重置后有个足够长的超时时间以让代码下载完毕并启动看门狗。下载时间与实际的同步时间、代码大小和数据率相关。
5. 并没有启用对包含bootloader代码的FLASH扇区的保护。当修改FLASH内存时,要小心别改到bootloader里了。
6. bootloader没有使用PLL,因此最高SCI波特率受限,如 通信速率 那部分所述。依赖于主机的实现,一旦RAM中的代码下载完毕,RAM中的代码可能可以使能PLL并切换到个更高的速率(得益于更高的总线速率)。这取决于主机实现。
7. 当使用下载编程算法把程序编程进FLASH存储器时总是有风险的,可能外部干扰会损坏程序。
不是所有情况下都能恢复的。一些措施可以降低崩溃的风险。修改以下东西的操作存在较大风险:
a. MCU重置向量。当重置向量被擦除后,重置将不会重启bootloader。如果需要保留bootloader,那么在擦除重置向量后立刻编程它能够最小化可能导致bootloader函数损坏的时间窗口。
b. 应用启动向量。由于留着bootloader,一旦应用启动向量被编程,重置后就不会使用bootloader的LRAE函数了。如果过早地重置,或者写FLASH发生了问题,那么重置时就会跳到个不完整的应用中。把编程应用启动向量作为下载程序的最后一步可以降低这种风险。
c. bootloader代码。如果,由于某种原因,需要修改FLASH中的bootloader代码,那么要是发生过早地重置或者FLASH编程错误,就会导致无法正确地重启LRAE进程。

以上三种状况都可以通过设计MCU连接BDM的外部接口来进行恢复。