对于嵌入式开发而言,Bootloader几乎与操作系统同等重要,它可以让我们摆脱MCU官方工具,定制自己的烧录工具,不仅提高产品辨识度,同时也大大减少了对外引脚数量(例如兼容通信的Uart或CAN等,而不需要另外接JTAG)。
要开发Bootloader,相对于普通程序,是有一定难度的,这其中涉及到MCU的工作原理、内部存储结构等,而且仅仅依靠C语言可能无法完成,有时需要配合汇编来精确执行特殊指令(例如Flash擦写)。
一般MCU的机器码都是存储在Flash中,MCU启动时PC指针会从内部Flash第一个地址开始读取指令运行,这个过程我们一般无法干涉。但由于我们写的代码存于Flash中,所以一旦从Flash启动,后续操作就完全可以由我们来指定,我们可以指定程序执行位置。
对于低端MCU来说,我们可以通过在Flash初始的位置设置指令,来启动内部不同flash区域的程序,以及烧写程序到这些flash区域,这些操作集合叫做Bootloader。Bootloader承担着用户程序的烧写以及跳转。
对于高级MCU或者CPU来说,可以轻松映射外部存储(外部Flash、U盘、硬盘等),MCU启动后,我们可以指定其从哪个存储启动,甚至通过通信接口接收数据存储到这些外部存储。这些操作集合在嵌入式操作系统中一般称之为UBoot,在PC中称之为BIOS,外部存储一般存放的是操作系统。
实际上上述两种功能是一样,后者相对复杂一点,此处我们着重讲述前者。
下图为通用MCU带Bootloader程序和用户程序的Flash存储结构:
常规Bootloader逻辑是这样的:
1、开机Goto到Bootloader的Main函数
2、判断是否有按键按下或者是否接收到通讯命令
3、若有操作,则停留在Bootloader,执行后续操作,例如烧录程序
4、若超过一定时间未有操作或者命令,进入用户程序
注意:
1、Bootloader应从Flash第二页之后开始,避免擦除编程中断向量表时,导致Bootloader缺失故障。
2、Bootloader中不要使用中断,因为Bootloader和用户程序共用中断向量表,更新用户软件会重新修改IVT。
以下详细介绍dsPIC33E系列Flash操作。
对于dsPIC33E系列,内部Flash存储如下,对于部分低端MCU,部分区域(例如附属闪存)是没有的,详细参考该MCU的Datasheet:
而以dsPIC33EP256GP506为例,很多空间被阉割了,实际flash结构如下:
下面讲讲如何在MCU运行时,对内部Flash进行擦除、编程(注意,建议不要对当前程序运行区域进行擦写,会导致运行异常)。
Flash编程相比于EEPROM,要麻烦不少。
Flash编程采用的方式是与模式,即编程时,将数据与Flash地址上的数据与操作。因此,如果一个地址上的数据位不是全都为1,那么编程该地址的结果就是错误的,所以我们在操作Flash时要有一个共识,即,同一个地址不应该被编程超过2次。我们可以在第二次编程前,将该地址所有数据位全部置1。
我们该如何在编程前将对应地址的数据位全部置1呢?
那就是擦除,Flash擦除会把对应区域的数据位全部置1。但是。。。擦除不能仅擦除一个地址的数据,而是必须擦除一页的数据,那么一页的大小是多少呢?是1024个指令字,一个指令字为32位(实际24位,高8位为虚字节,始终保持为0),由于dsPIC33E系列都是16位单片机,因此每个指令字占2个16位数据,占2个地址,实际擦除的地址跨度为2048,即0x800。假设我们擦除0x000000,实际会擦除0x000000-0x0007FF,擦除其中任意地址,都会擦除该页。
基于以上原因,若是我们要编程某部分flash数据,需要先将该页内所有数据读出来,然后擦除flash页,再修改读出来的数据,最后重新写入该页所有数据。
dsPIC33E系列编程功能体现在闪存控制寄存器NVMCON的NVMOP<3:0>中。通用功能如下,实际功能可能会有所阉割,参考对应数据手册。
编程时可以进行行编程、字编程、单个配置寄存器字节编程,一行为128个指令字,字编程为2个指令字,单个配置寄存器字节编程比较特殊,不需要擦除,可以直接编程,但需要注意的是,编程配置字时,时钟只能是FRC,不能带PLL。能否进行行编程依赖于写锁存器长度,写锁存器在0xFA0000处,部分长度只有2个指令字,所以无法进行行编程。
针对我们使用的示例单片机,dsPIC33EP256GP506,参考Datasheet我们发现:
这款单片机功能阉割较多,只支持也擦除和双字编程,其写锁存器只有2个指令字。同时,这款单片机的无法编程配置字,所以在更新用户程序时,不能通过Bootloader烧写配置字。
最后,需要提醒的是,由于配置字在用户存储区域最后一页,擦除最后一页会触发代码保护,所有地址数据全部清零。以dsPIC33EP256GP506为例,0x02A800之后的地址不能擦除。
本节到此结束,下一节将剖析dsPIC33E系列程序编译后的Hex文件。
上一篇:【PIC32MZ】PWM呼吸灯
下一篇:【dsPIC33E】Bootloader(二)Microchip的Hex文件结构介绍
推荐阅读最新更新时间:2024-11-12 18:00
设计资源 培训 开发板 精华推荐
- TCR5SB33U、200mA、3.3V输出电压CMOS低压降稳压器的典型应用
- AM6TW-2407SZ 7.2V 6 瓦单路输出 DC-DC 转换器的典型应用
- LTC4156 的典型应用——具有 I2C 控制和 USB OTG 的双输入电源管理器/3.5A LiFePO4 电池充电器
- 【训练营】立创仿生机械狗设计
- 使用 ON Semiconductor 的 LM337M 的参考设计
- OPENMV专用扩展板,官方开源工程扩展板
- klipper_TOOLHEAD_USB
- 【灯条】12V 8W 40cm双色灯条
- LT1170HVCQ、-28/5A 负升压稳压器的典型应用
- STEVAL-ISA141V2、2A、高效、单电感降压-升压 DC-DC 转换器 &基于 STBB3JCC 的高亮度白光 LED 驱动器评估板