Westbrook
认证:VIP会员
所在专题目录 查看专题
dsPIC33 BootLoader(1)-简介
dsPIC33 BootLoader(2)-Flash程序存储空间
dsPIC33 BootLoader(3)-构建中断重映射表
dsPIC33 BootLoader(4)-基于MCC配置Boot区
dsPIC33 BootLoader(5)-基于MCC生成应用程序
Bootloader演示
作者动态 更多
10分钟教你快速完成数字电源的闭环控制
2022-04-02 17:26
数字电源学习板演示
2022-02-19 13:36
手把手教你学数字电源系列视频(22)- 数字控制的软件流程
2022-02-19 13:28
手把手教你学数字电源系列视频(21)- 设计数字补偿器(LDE执行)
2022-02-19 13:28
手把手教你学数字电源系列视频(20)- 设计数字补偿器(AB系数计算)
2022-02-19 13:27

dsPIC33 BootLoader(2)-Flash程序存储空间

dsPIC33C 器件具有4M x 24位的程序存储器地址空间,下面是Flash大小为256KB的程序存储器地址的映射关系。

整个Flash结构分为活动区域和非活动区域,用户可用的是活动区域,而活动区域可分为用户程序存储区和器件配置,其中前两个字节0x000000~0x000002为复位入口向量,0x000004~0x0001FE为中断向量表IVT,0x000200为主程序的入口地址,正常情况下代码从此处开始存放。

用户程序存储空间(User Application Firmware,0x200开始)分配一般是把Bootloader部分放在前,应用程序放在后的结构。这首先是实际的引导加载程序空间,是Bootloader代码所在的位置,包括IVT和AIVT。引导加载程序空间只能通过对新的BootLoader程序进行编程来修改。第二个存储空间是应用程序存储空间或应用程序代码所在的位置。应用程序存储空间的一部分包括重新映射的中断向量(Remapped Applicartion IVT)。该内存映射显示在下面的程序内存使用情况中。通过使用引导程序将代码从外部设备传输到此存储区域,可以在此处对应用程序代码进行重新编程。 MCU在上电和复位都是从Bootloader开始执行,BootLoader运行后判断当前是否需要进入升级状态。如果不需要升级,就直接运行Flash原有的应用程序;如果需要升级,则进入升级状态。

Bootloader程序存放时,是按照正常情况下从0x000200开始存放。但是存放Bootloader程序的空间起始地址不应该紧接着此地址,因为如果这样擦除第一个闪存存储页也会擦除Bootloader的程序。因此,自举程序的起始地址必须为0x800,为什么是0x800?

因为dsPIC33C一页有1024指令字,一行有128指令字,一个指令字为32位(实际24位,高8位为虚字节,始终保持为0),由于dsPIC33C系列都是16位单片机,因此每个指令字占2个16位数据,占2个地址,实际擦除的地址跨度为2048,即0x800。

下面是dsPIC33C 单分区闪存代码存储区大小的情况。

Flash为256KB大小的具有90112指令字,704行,88页,下面是具体页的分布情况。

所以弄清楚了页的分布后,对Bootloader程序空间分配完毕之后,应用程序的存放需要添加相应的偏移量(可对照此表)。

定义存储空间的大小和位置主要涉及确定当前BootLoader的大小以及将来容纳新功能所需的任何可用空间。 在最终确定此空间的大小之前,提供额外空间非常重要。 如果将来需要更改分配的BootLoader闪存空间的大小,则需要同时更改应用程序的启动位置,然后重新映射中断向量表的位置也需要更改。 对应的两个更改处意味着该应用程序将无法与较早的引导加载程序一起使用。 必须在项目开始时就保留足够的空间,以便将来提供额外的增长空间。 一旦确定了为引导加载程序分配的闪存大小,即可将其余的闪存分配给应用程序和重新映射的中断向量表。

BootLoader程序空间的大小必须是设备页面大小的倍数。 对于页面大小为512条指令(1024个字)的设备,页面大小必须为0x400的倍数。 同样,对于具有1024条指令(2048个字)的页面大小的设备,页面大小必须为0x800的倍数。

比如Bootloader程序地址入口为0x800,分配2k指令字的大小,同时由于应用程序也不可紧跟自举程序之后,它必须从下一个闪存存储页的开始处开始存放,那么应用程序的入口地址为0x1800.


TBLRDx和TBLWTx指令提供了读或写程序空间内任何地址的最低有效字和最高有效字的直接方法,非常适合某些应用。

对于表指令,程序存储器可被视为并排放置的两个16位字宽的地址空间,每个地址空间都有相同的地址范围,由于程序存储器只有24位宽,所以后一个空间的高字节不存在(尽管它是可寻址的),被称为“虚拟字节”。低位字的地址始终为偶数,而高位字的地址为奇数。

由于程序存储器地址始终在低位字处按字对齐,所以在代码执行的过程中地址将递增或递减2。这种寻址模式也与数据存储空间寻址兼容,且为访问程序存储空间中的数据提供了可能。下图是一个取值示例,PC<22:1>指针递增1相当于PC<22:0>加2.


在MCU运行时,对内部Flash进行擦除、编程(注意,建议不要对当前程序运行区域进行擦写,会导致运行异常)。

Flash编程采用的方式是"与"模式,即编程时,将数据与Flash地址上的数据"与"操作。因此,如果一个地址上的数据位不是全都为1,那么编程该地址的结果就是错误的,所以我们在操作Flash时要有一个共识,一个程序存储字可以在擦除之前被编程两次,但仅限于(1)两次编程操做使用相同的数据或(2)包含1的位被设置为0,但为0的位不能设置为1;所以一般不建议在不擦除的情况下对数据进行第二次编程,应该将该地址所有数据位置1.我们该如何在编程前将对应地址的数据位全部置1呢?

那就是擦除,Flash擦除会把对应区域的数据位全部置1。但是擦除不能仅擦除一个地址的数据,而是必须擦除一页的数据,假设我们擦除0x000000,实际会擦除0x000000-0x0007FF,擦除其中任意地址,都会擦除该页。所以dsPIC33C擦除操做是按页擦除,按行进行写。或者可以先将该页内所有数据读出来,然后擦除flash页,再修改读出来的数据,最后重新写入该页所有数据。

需要提醒的是,由于配置字在用户存储区域最后一页,擦除最后一页会触发代码保护,所有地址数据全部清零。以dsPIC33CK256MP506为例,0x02BF00~0x02BFFC为配置字存放的地方,所以0x02B800之后的地址不能被擦除。


dsPIC33系列器件支持一种单分区闪存模式和两种双分区闪存模式(双分区模式下Flash大小必须为64KB及以上)。双分区闪存模式允许通过两个单独的应用程序对器件进行编程,便于引导加载,或允许应用程序在运行时进行编程,而无需暂停CPU。

在双分区闪存模式下,器件的存储器均分为两个物理部分,称为分区1 和分区2。每个分区都包含自己的程序存储器和配置字。在程序执行期间,只可执行其中一个分区中的代码,该分区为活动分区。另一个非活动分区不可用于执行但可进行编程。

支持的三种擦除工作分别是:批量擦除,非活动区域擦除和页擦除。

批量擦除是擦除用户所有存储区。

非活动分区擦除操作可以在运行时从活动分区执行。它将擦除非活动分区中的所有用户存储区和闪存配置字。非活动分区擦除命令仅在器件处于双分区闪存模式之一时有效。这个功能在做Liveupdate时非常有用,当活动区处于工作时,这时可以对非活动区进行擦写修改某些内容,然后实现活动区与非活动区的无缝切换,对MCU实现不掉电升级,此类应用在服务器电源应用中比较多。

后面的BootLoader实现均是在基于单分区模式下。

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 3
收藏 7
关注 823
成为作者 赚取收益
全部留言
0/200
  • dy-usQfCly3 09-02 18:38
    能有偿帮我处理一下吗?
    回复