苏州溥秋智能科技有限公司
请选择 进入手机版 | 继续访问电脑版

QQ登录

只需一步,快速开始

微信登录

扫一扫,访问微社区

查看: 6335|回复: 2

STM32F103 串口-IAP程序升级

[复制链接]
  • TA的每日心情
    奋斗
    2017-11-24 21:31
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    147

    主题

    78

    帖子

    753

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    753
    发表于 2016-4-14 15:09:16 | 显示全部楼层 |阅读模式
    活动类型:
    自驾出行
    开始时间:
    2016-4-14 15:08
    活动地点:
    布里斯班
    性别:
    不限
    已报名人数:
    0
    剩余名额:
    5 人
    报名截止:
    2016-4-30 15:08
        通常情况下我们给STM32系列的单片机烧录程序文件的时候,使用SWD、J-link或者通过设置BOOT引脚后,使用串口进行程序下载,这样的方式直接一次性将程序文件下载到单片机的flash中,比较适合绝大部分的应用。但是有些应用中产品装配完成后,下载口不便引出的情况下,或者是某些设备需要具有远程更新程序情况下,使用串口IAP的方式将会更加便捷。
        一般我们常见的51单片机内部的flash空间,只能使用下载器进行烧录程序。芯片自身无法擦写内部flash空间。这样的情况下,如果我们后期需要升级芯片中的程序时,只能到现场使用下载器重新烧录程序,这样比较繁琐。但是STM32单片机内部的flash可以在程序中让单片机自身去擦写编程,同时官方也提供了相应的操作函数固件库。这样就可以实现单片机程序的远程升级,通过芯片外设的某种通信接口(一般常用串口),将程序文件发送给芯片,让芯片自身把程序文件写入内部flash,实现程序的远程升级操作。如果要实现让单片机自身去升级程序,就必须要将内部flash空间进行划分,分不同的区域写入不同工程的程序代码,才能实现该功能。
        一般情况下,我们将单片机的内部flash空间划分为两大区域,为了方便理解,我们叫做bootloader区域和app区域(这里的bootloader和app为自定义名称,也可叫做其他名称)。分为两大区域的原因是,我们要给一块芯片(单片机)写入两个不同的工程文件,这个两个工程分别是“程序升级工程(bootloader)”和“应用程序工程(app)”。两个工程的区别是:
        “程序升级工程”存放在flash的bootloader区域。它的作用:接收新版本的程序文件,将收到的文件写入内部flash的app区域中。这个工程的任务比较单一,所以它只占用较小的一部分flash空间”。
        “应用程序工程”存放在flash的app区域。它的作用:执行真正的功能操作。如数据采集、执行一些运算等操作。也是单片机实际发挥作用的程序。升级程序的方式是,可以灵活应用,主要看开发人员的编程思路,在这里我们使用上电检测的方式进行程序的更新。
        单片机上电后,首先在bootloader区域运行程序升级函数,检测是否有新版本的程序需要升级,如果需要升级时,就将接收的新版本程序数据写入app区域,之后跳转到app区域去运行正在的应用程序函数。如果不需要升级程序时,就直接跳转到app区域去执行程序。流程如下:
    1.jpg
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-11-24 21:31
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    147

    主题

    78

    帖子

    753

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    753
     楼主| 发表于 2019-7-22 16:23:33 | 显示全部楼层
    串口IAP程序的操作方式是,分时切换flash区域进行执行不同功能的函数,而不是两个区域中的程序都在运行。任何时候,单片机都不能同时执行两个工程代码,我们将flash空间划分如下(以STM32F103CB为例)flash的总大小是128Kb,划分bootloader区域大小为8Kb,app区域为120Kb。示意图和相关地址如下:
    2.jpg
    如果想要将程序按照如上图所示的flash空间存放的话,就必须对编译环境进行一些设置,才能到达我们的目的,不再使用默认的编译设置。bootloader工程设置在编程软件keil5中设置如下:
    3.jpg
    app工程设置在编程软件keil5中设置如下: 4.jpg







    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-11-24 21:31
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    147

    主题

    78

    帖子

    753

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    753
     楼主| 发表于 2019-7-22 16:23:33 | 显示全部楼层
    在app工程的程序代码中除了设置工程代码的编译地址之外,还要将中断向量表偏移寄存器的值进行相对应的设置。设置中断向量表偏移寄存器的方法有两种:
        ①→可以在app应用程序的主程序while循环之前设置,设置格式为:
            CB->VTOR = FLASH_BASE | 0x2000;
        ②→还可以在官方的固件库设置,在固件库system_stm32f10x.c文件中,第267行使用了如下的设置: 5.jpg
    而上述表达式中的“VECT_TAB_OFFSET”在该固件库文件的第128行进行了声明和初值定义:
    6.jpg
       可以看出,默认情况下,“VECT_TAB_OFFSET”的值等于0。也就是不进行偏移,我们在进行IAP编程的时候,可以将此处的初值改为对应的偏移量即可。通常我们不对官方固件库进行更改,所以常用第一种方式进行设置中断偏移量。在这里要注意的是,偏移量不能随意任意设置,由于ARM Cortex®-M3内核规定,中断向量表必须对齐原则。因此中断偏移量的值必须是0x200的倍数。
    IAP代码中关于跳转部分的详解:
        在编程中我们要清楚的知道,单片机任何时候只能运行一个代码工程,并不是两个区域的代码都在运行。所以就必须使单片机要在两个区域(bootloader区域和app区域)或者是两个工程代码之间进行跳转。跳转之前除了要将app工程代码中的中断偏移量进行相对应的设置外,还要在单片机跳转时,设置app区域代码的主堆栈栈顶地址。通过官方手册就可以知道,STM32默认启动地址是0x08000000,而这个首地址中保存的就是堆栈的栈顶地址,这个地址是在代码编译后,有编译器自动产生。同时根据相关手册可以看到STM32的程序存放规则和编译后的可执行文件的规则是,编译后的可执行文件中第一个字就是被下载到STM32内部flash中的第一个存储单元中,而这个就是我们需要的堆栈栈顶地址。
        重新设置STM32的堆栈栈顶地址是属于内核级别的操作,因此C语言无法进行内核操作,只能借助嵌入汇编的形式进行操作,一般是使用MSR指令进行操作的。MSR指令是用于访问内核中特殊功能寄存器(如堆栈栈顶寄存器)专用汇编指令。其编写形式一般为如下:
    7.jpg
    完成对工程的设置与程序代码的编写之后,我们还需要得到相应工程的BIN格式文件,keil软件自带输出BIN文件的功能,但是一般情况下我们不使用BIN文件,所以程序代码编译完毕后,软件默认是不输出BIN格式的文件。如想要keil在编译完成之后,同时输出BIN文件,则需要进行设置,设置方法是在工程管理的选项卡的User选项中的Run #1处编写命令“fromelf.exe --bin -o "$[url=mailto@L.bin]L@L.bin[/url]" "#L"”即可,如图:
    8.jpg
    最后说明:本次编写仅陈述出主要和关键的操作部分(因为细致的操作部分和程序的实现代码现在网络上都有很多),希望本次的编写对大家有一些帮助,如果文中有陈述错误之处,还请指正!谢谢。






    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    联系方式
    0512-67225095 周一至周日9:00 - 21:00
    公司地址:苏州工业园区仁爱路99号D602-40

    苏州溥秋智能科技有限公司2017年8月成立,专门为客户提供数字信息化和物联网化的产品和服务。

    Array  X3.4© 2013-2017 苏州溥秋智能科技有限公司

    Archiver|手机版|小黑屋|苏州溥秋智能科技有限公司 ( 苏ICP备18046360号-3 )

    GMT+8, 2020-9-23 08:19 , Processed in 0.139308 second(s), 30 queries .

    快速回复 返回顶部 返回列表