参考原文地址:https://blog.csdn.net/lin_strong/article/details/78383916
需要实现远程升级单片机,正好在网上找到了官方提供的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提供的学习资料。
实测在MC9S12XEP100上可以使用,但是对我来说需要修改了一个小地方:
可能是由于这个程序的版本太老,PARTID没有考虑到我手头上这个XEP100的PARTID(0xCC95),这个PARTID甚至在芯片手册中都没有提到,不过问题也不大,测试后发现只要和0xCC94一样的处理方法即可了。想知道自己设备的PARTID是多少可以直接去看地址在1A-1B的这两个字节的值是多少。
修改方式为:
首先在PARTID.h中添加一个宏
……
//S12XE:
#define MASK_0M48H 0xCC90 //1024k flash
#define MASK_1M48H 0xCC91
#define MASK_2M48H 0xCC92
#define MASK_3M48H 0xCC93
#define MASK_4M48H_5M48H 0xCC94
#define MASK_5M48H 0xCC95 // 添加的
……
然后在main.c 中的EraseFlash和ProgramFlash两个函数中的switch语句中分别添加一行case。
……
//S12XE 1024k flash
case MASK_0M48H: //Falling to next case
case MASK_1M48H: //Falling to next case
case MASK_2M48H: //Falling to next case
case MASK_3M48H: //Falling to next case
case MASK_4M48H_5M48H:
case MASK_5M48H: // 添加的
if (!((ProgSRec.LoadAddr >= 0x700000UL) && (ProgSRec.LoadAddr <= 0x7FEFDFUL)))
return(SRecRangeError);
break;
……
然后就能按照指南正常运行了。
by: Lukas Zadrapa and Ladislav Makovic
Technical Information Center
Roznov
Czech Republic
译者注:译者博客(http://blog.csdn.net/lin_strong),转载请保留这条。此为官方文档AN4258,仅供学习交流使用,请勿用于商业用途。
这篇应用笔记介绍了为 基于180nm技术的 S12和S12X微控制器家族 编写的一个bootloader程序的运行和使用。
使用这bootloader可以很方便地实现生产中编程或者“在线系统(in-system)”编程,特别是应用于那些 无法使用HCS12背景调试接口(BDM)的场合。用户必须在生产准备阶段或在编程供应商那把bootloader预先烧写进S12(X)。Bootloader会留存在MCU中以供未来使用。
这个bootloader实现支持通过SCI串口将用户软件下载进MCU flash内存中。
这篇文档中描述的bootloader只是一个示例,由其产生的任何后果我们概不负责,并且我们不提供技术支持。
有两个版本的bootloader:
除非特别标注,这篇应用笔记中的内容适用于所有两个版本。
这个bootloader没有为最小的设备进行优化。因此,不支持MC9S12GN16。
当前不支持对D-Flash或说EEPROM的编程。
为了成功运行这个bootloader,需要满足一些需求。
有许多种方式确定是要启动bootloader还是用户应用程序。比如可以选择通过判断输入引脚的状态、通过EEPROM内存中的某个变量的状态或者通过从通讯接口收到的命令。
这个bootloader使用第一种方式。在重置之后,bootloader会使能PP0引脚的上拉寄存器并且读取PP0引脚的状态以确定是否你想要运行bootloader。
可能这个引脚的外部电路是这样的:一个开关、跳线或者一个按钮与可选的上拉电阻器。
所有的S12(X)微控制器都有集成串行通信接口。注意,需要RS232电平转换器以与PC通信。
默认的,串行通信会设为这个格式:
默认的波特率是9600。可以在bootloader的菜单中修改其为38400、57600或115200 bps。
可以使用串口调试助手来与PC通信。这个串口调试器必须支持串行COM口通信、Xon/Xoff流控制以及必须支持发送文本文件。
S12微控制器不需要外部晶振。bootloader会使用S12微控制器内部的一个1MHz的RC震荡电路。Bootloader设置总线频率为25MHz以支持高速率通信。
S12X微控制器需要晶振或者外部振荡器。在bootloader内配置PLL以达到40MHz的总线时钟频率。这是为了提高通信速率以加快代码下载速度。
bootloader的运作方式很直白。这个部分仅描述了最重要的和最特殊的那些。
bootloader会处理所有的重置向量。在重置后,会调用bootloader的startup例程。首先,bootloader会读取PP0引脚的状态。如果引脚值为逻辑0,bootloader就会开始工作。如果是逻辑1,就会调用用户应用程序的startup例程。如果用户应用的重置向量不可用(地址0xEFFE-0xEFFF上的字被擦除),那不管怎么样bootloader都会开始运行。用户可以重写这个代码以更改启动条件。
在用户应用用到了中断的情况下,需要使用IVBR寄存器重定位中断向量表。bootloader被放在最高的一个地址块中,地址0xF000-0xFFFF。这个区域是受保护的,所以用户的应用程序不能把中断向量表放在默认的地址0xFF10-0xFFFF。这种方案的优点是bootloader不会受到电源故障的影响,这可能会在重写中断和重置向量时发生。
每个硅掩码组都有一个特定的part ID,位于两个8位寄存器中,PARTIDH和PARTIDL中,地址在0x001A和0x001B。
当要把s-record编程到flash内存中去时,bootloader会检查是否地址位于物理flash内存上。当地址无效时,会返回一个错误。
在bootloader工程的PartID.h文件中可以找到当前支持的掩码组和part ID。
这个部分描述了使用这个bootloader的每一步。
你必须确保用户应用程序不会碰到bootloader的地址范围(0xF000-0xFFFF)。
1. 在CodeWarrior for S12(X)集成开发环境中创建一个新工程。
2. 打开.prm文件
3. 把segment ROM_C000从原来的0xC000-0xFEFF改成0xC000-0xEFDF。这是因为地址0xF000-0xFFFF会放着bootloader,而0xEFE0-0xEFFF会用作用户应用的重置向量。
如果使用了中断:
4. 把segment ROM_4000从原来的0x4000-0x7FFF改成0x4000-0x7F0F。0x7F10-0x7FFF会被用于重定位中断向量表。
5. 如附件示例应用那样创建一个中断向量表,并对应的设置IVBR寄存器。IVBR设置中断向量表的基地址,这种情况下必须被设置为0x7F。
bootloader接受使用全局(线性)地址的s-records。所有的records必须被对齐为32字节,长度也必须是32字节。
1. 打开SRecCvt工具(SRecCvt-GUI.exe)
2. 选择使用的MC9S12设备(取决你用的是哪个),选择Memory为Flash,选择Operation为Convert File。
3. 选择输入文件格式为Banked,输出文件格式为Linear。
4. 设置S-Record Size为32.
5. 浏览输入文件(由CodeWarrior生成的S19文件)并选择输出文件。
6. 点击Convert按钮。
图 7.SRecCvt
用户应用可以被独立地开发,或说,不带有bootloader。用户应用可以被加载进微控制器并可以由BDM设备来直接的调试。然而,出于生产目的,将用户应用与bootloader合并到一起是很有价值的,这样就可以在单个s-record文件中把所有东西都下载进微控制器了。
这是推荐的流程:
1. 打开按照第6章“怎么写用户应用程序”中所述那样创建的用户应用程序。
2. 把一个用户应用程序重置向量放到地址0xEFFE,这样bootloader就可以使用这个向量了。拷贝以下三行到main.c中:
这个bootloaders在这些开发板上测试成功过:
所有提到的工程和工具都在这篇应用笔记相关的zip文件中。