本帖最后由 一路向北lm 于 2021-5-9 21:53 编辑
#申请原创#
当我们玩单片机到一定境界的时候,一些稀奇古怪的想法便会油然而生
固件升级到底如何实现的?为什么人家使用单片机开发的设备可以支持固件升级,而我完全不知道怎么回事?
@21小跑堂 @21小管家 你们知道吗?
开始科普(以STM32为例)
1. 我们写的代码程序被烧写到哪里?
这个问题很简单,我们大家都知道我们写的代码被烧写到了芯片内部的Flash里面。
2. 芯片内部的Flash有多大?是否有剩余的空间?
关于芯片内部的Flash有多大这个问题大家需要去参考芯片手册,我们熟悉的STM32F103C8 内部Flash是64k,而STM32F103ZE 内部Flash达到了256k;如果我们只是在STM32F103ZE 里面点一个灯,那256k的Flash岂不是给浪费了。
3.我们来简单的看一下,点一个灯,究竟占据Flash多少的空间?
双击C8T6的LED工程:Template,即可打开Template.map文件。
定位到Memory Map of the image,通过内存映射我们可以看到Falsh的基地址是0X0800 0000,最大可存储0X10000(64K),LED工程大小只占据了0X52C (不到2K),剩余的62K白白浪费了。
4.Falsh怎么被合理的利用呢? 有人提出:可以把需要储存的参数信息写入到芯片内部的Falsh,不再需要外部扩展Flash和EEPROM啦; 也有人提出:可以把写的程序烧录两份到内部的Falsh中,其中一份作为备用和更新。 也有人提出: 我们是否可以建立分层的思想,将内部Falsh划分为四大区域:Boot区域、APP运行代码区域、备份升级代码区域、参数存储区域,这个想法,我拍手叫绝。
开始实战(以STM32F103C8为例)1、 如何分配STM32F103C8 的boot和app的空间? 2、 怎么从boot跳转到app? 3、 怎么设置App的中断向量? 如何分配STM32F103C8 的boot和app的空间: stm32f103c8t6的flash的大小是64k,所以把它分成如下所示: 0x08000000 ---0x0800 33FF分配给bootloader使用,大小是13k 0x0800 3400----0x080097FF分配给第一个APP的使用,大小是25k 0x08009800----0x0800 FBFF分配给升级备份的APP的使用,大小是25k 0x0800FC00----0x0800 FFFF 分配给参数存储使用,大小是1k
Boot中ROM大小设置: App1中ROM大小设置: App2中ROM大小设置:
如何从boot跳转到app?
跳转函数如下: #define RUN_CODE_ADDR 0x08003400 //RunCode Start Adress 0x08003400~0x080097FF 25K
typedef void (*pfun) (void); //函数指针类型定义
void go_to_app(void)
{
pfun Jump_To_Application;
__IO uint32_t JumpAddress;
ENTER_CRITICAL();
if (((*(volatile uint32_t*)RUN_CODE_ADDR) & 0x2FFFE000 ) == 0x20000000)
{
/* 地址要偏移4 */
JumpAddress = *(volatile uint32_t*)(RUN_CODE_ADDR + 4);
Jump_To_Application = (pfun)JumpAddress;
/* 使用app的栈 */
__set_MSP(*(volatile uint32_t*)RUN_CODE_ADDR);
/* 跳转到用户函数入口地址 */
Jump_To_Application();
}
}
跳转函数解释如下:
|