复旦微FM33LG045串口实现在线升级

复旦微FM33LG045串口实现在线升级

参考文档:

STM32单片机实现Bootloader跳转的关键步骤 - 知乎 (zhihu.com)

【笔记】复旦微FM33L026实现远程升级 - 知乎 (zhihu.com)

本文以FM33LG045为例,实现串口在线升级。

配置bootloader地址和app地址

app地址

app程序的起始地址为0x10000~0x30000

总大小为192KB

PS:这里需要器件的flash总大小,即不要地址越界了,我这个芯片的flash大小为256KB,即地址范围0x0~0x40000

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BootLoador地址

FM33中flash起始地址为0x00,故BootLoador的空间为0x0~0x10000,总大小64KB。

PS:在stm32中起始地址映射为0x8000000,根据不同的单片机选择合适的起始地址。

在这里插入图片描述

修改中断向量偏移

这里尤其要注意,需要修改APP程序的中断向量偏移,如果不修改偏移,APP程序里的中断就会跑到引导程序里面!!

找到文件system_fm33lg0xx.c,在 SystemInit() 中添加下列代码

SCB->VTOR = 0x00010000;

在这里插入图片描述

实现IAP跳转

下列代码即可实现bootloader程序到app程序的跳转

//.h文件
typedef void (*iapfun)(void);                   /* 定义一个函数类型的参数 */
#define FLASH_APP1_ADDR         0x00010000

//.c文件
iapfun jump2app;
uint32_t g_iapbuf[128];

void iap_load_app(uint32_t appxaddr)
{
        /* 用户代码区第二个字为程序开始地址(复位地址) */
        jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);

        /* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */
        __set_MSP(*(volatile uint32_t *)appxaddr);

        /* 跳转到APP */
        jump2app();

}

至此所有配置结束,在main函数中调用iap_load_app()即可实现app程序的跳转

生成app程序的bin文件

bin文件后续升级需要用到,keil需要配置后编译才能生成bin文件,具体配置如下

fromelf --bin --output 
./Objects/nx.bin         //生成目标文件位置和文件名
./Objects/FM33LC0xx_Tester.axf    //.axf的文件位置

在这里插入图片描述

APP程序升级

接下来就是向flash对应地址中写入bin文件数据了

本例中app起始地址为0x10000,我们只需要将串口接收到的app数据写入地址0x10000,全部写完后,再进行app跳转即可实现app程序的升级,如下图所示:

将串口接收到的数据写入flash参考代码

uint32_t g_iapbuf[128];       /* 2K字节缓存 */

/**
 * @brief       IAP写入APP BIN
 * @param       appxaddr : 应用程序的起始地址
 * @param       appbuf   : 应用程序CODE
 * @param       appsize  : 应用程序大小(字节)
 * @retval      无
 */
// 
void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
{
   uint16_t t;
   uint16_t i = 0;
   uint32_t temp;
   uint32_t fwaddr = appxaddr; /* 当前写入的地址 */
   uint8_t *dfu = appbuf;

   for (t = 0; t < appsize; t += 4)
   {
       temp = (uint32_t)dfu[3] << 24|(uint32_t)dfu[2] << 16|(uint32_t)dfu[1] << 8|(uint32_t)dfu[0];

       dfu += 4;               /* 偏移2个字节 */
       g_iapbuf[i++] = temp;
       if (i == 128)
       {
           i = 0;
           FL_FLASH_PageErase(FLASH, fwaddr);
           FL_FLASH_Program_Page(FLASH, fwaddr / FL_FLASH_MAX_PAGE_NUM, g_iapbuf);
           fwaddr += 512;     /* 偏移2048  16 = 2 * 8  所以要乘以2 */
       }
   }
   if (i)
   {
       FL_FLASH_PageErase(FLASH, fwaddr);
       for(int j=0;j<i;j++){
        FL_FLASH_Program_Word(FLASH, fwaddr, g_iapbuf[j]);
        fwaddr +=4;                           /* 将最后的一些内容字节写进去 */
       }

   }
}

以上代码将串口接收到的数据存入一个2K大小的数据,再一起写入flash,若数据量比较大的情况,可以配合上位机分批写入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值