打印
[应用相关]

浅析STM32 Bootloader设计

[复制链接]
1111|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
energy1|  楼主 | 2015-3-23 23:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

不需要拆机就能对产品进行固件升级是很多人想要的效果,不仅方便而且节省精力和成本。那么如何完成这项工作呢?接下来所介绍的Bootloader就可以完成这项工作,通过Bootloader引导程序完成固件的升级。下面来浅析STM32 Bootloader设计。

本文引用地址:http://www.**/article/174370.htm

  设计思想

  由Bootloader负责检测SD卡中是否有固件更新所需的BIN文件。如果检测到所需要的BIN文件,则开始复制文件更新固件。更新结束后跳转到指定的地址开始执行最新的程序。可以在论坛的ARM版块找到liklon的帖子:两份简单的 Bootloader 程序。链接为:http://forum.**/thread/238997/1帖子里已经共享了两份简单的STM32Bootloader程序,一份是利用znFAT进**上文件操作,第二份是利用FATFS进行文件操作。


沙发
energy1|  楼主 | 2015-3-23 23:28 | 只看该作者

知识要点

  STM32内部FLASH的起始地址为0X08000000,Bootloader程序文件就从此地址开始写入,存放APP程序的首地址设置在紧跟Bootloader之后。当程序开始执行时,首先运行的是Bootloader程序,此时Bootloader检测SD卡中的BIN文件并将其复制到APP区域使固件得以更新,固件更新结束后还需要跳转到APP程序开始执行新的程序,完成这最后这一步要了解Cortex-M3的中断向量表:

  程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,当复位中断程序运行完成后才跳转到main函数。由此可见,在最后一步的设计中需要根据存放APP程序的起始地址以及中断向量表来设置栈顶地址,并获取复位中断地址跳转到复位中断程序。接下来开始分析程序设计步骤。


使用特权

评论回复
板凳
energy1|  楼主 | 2015-3-23 23:28 | 只看该作者

Bootloader程序设计

  1.确定存放APP程序的首地址

  #define FLASH_APP_ADDR 0x08010000 //应用程序起始地址(存放在FLASH)上一句代码中是0X08010000可以看出,留给Bootloader程序的存储空间大小为64K。存放APP程序的起始地址为0X08010000。

  2.Bootloader检测是否有BIN文件

  gCheckFat = f_open(&FP_Struct,"/APP/LIKLON.BIN",FA_READ);//判读gCheckFat确定上面的代码是检测是否存在liklon.bin这个文件存在,其中liklon.bin文件就是固件升级所需要的BIN文件。


使用特权

评论回复
地板
energy1|  楼主 | 2015-3-23 23:29 | 只看该作者

3.复制文件到指定地址

  上一步中如果gCheckFat为0则表示存在所需BIN文件,则可以执行这一步。f_read (&FP_Struct,ReadAppBuffer,512,(UINT *)&ReadNum); //读取512个字节将512个字节转换为256个16位的数据存放在ChangeBuffer数组中,准备写入FLASH。FlashWrite(FLASH_APP_ADDR + i * 512,ChangeBuffer,256); //向指定地址写入读出数据向APP程序区写入512个字节的数据。按照这样读取写入,就可以完成对APP程序区的更新。

  4.跳转到新程序运行

  更新完程序后就需要跳转到新程序开始运行,具体实现看下面代码:

本文引用地址:http://www.**/article/174370.htm

  typedef void (*iapfun)(void); //定义一个函数类型的参数
  iapfun jump2app;
  __asm void MSR_MSP(u32 addr) //设置堆栈指针
  {
        MSR MSP, r0
        BX r14
  }
  //跳转到应用程序段
  //appxaddr:用户代码起始地址.
  void iap_load_app(u32 appxaddr)
  {
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
        {
              jump2app = (iapfun)*(vu32*)(appxaddr+4);//用户代码区第二个字为程序开始地址(复位地址),此处查看中断向量表可知
              MSR_MSP(*(vu32*)appxaddr);//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
              jump2app(); //跳转到APP,执行复位中断程序
        }
  }


使用特权

评论回复
5
energy1|  楼主 | 2015-3-23 23:32 | 只看该作者

 APP程序设计注意

  1.编译软件需要做出设置:

  在Bootloader程序中已经指定了APP程序存储的起始地址为0x08010000,所以在APP程序设计时需要将编译软件这里做出设置,修改起始地址和大小。

使用特权

评论回复
6
energy1|  楼主 | 2015-3-23 23:33 | 只看该作者

2.修改system_stm32f10x.c文件

  同样是针对于APP的起始地址改变而修改这里的偏移量,如上图所示。

  文中只是简单的介绍了关于Bootloader程序的设计,作为抛砖引玉,大家可以继续深入,添加数据校验和程序加密等。


使用特权

评论回复
7
energy1|  楼主 | 2015-3-23 23:34 | 只看该作者
今天做了个小实验,不使用mcuisp的自动控制,,手动使得boot0上拉。。
然后按下复位键,能下载

但是下载后 我还没有把boot0下拉呢。也没有复位,程序就正常运行了。
从这里是不是说明bootloader将程序下载结束后会自动的跳转到用户代码
呢??

那bootloader的流程应该是这样吧
while(1)
{
    if(有下载请求){
        下载程序;
       跳转到用户程序的入口
    }
}

使用特权

评论回复
8
ares_lan| | 2015-3-24 08:16 | 只看该作者
不错哦,是个不错的开始。我记得官网上有实例的。

使用特权

评论回复
9
longzhigu| | 2015-3-24 08:50 | 只看该作者
energy1 发表于 2015-3-23 23:34
今天做了个小实验,不使用mcuisp的自动控制,,手动使得boot0上拉。。
然后按下复位键,能下载 ...

量产下载确实遇到同样疑惑,boot0状态不影响程序正常下载,待解

使用特权

评论回复
10
飞翔浚流| | 2015-3-24 18:43 | 只看该作者
量产下载确实遇到同样疑惑,boot0状态不影响程序正常下载,待解

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

94

主题

422

帖子

10

粉丝