历史上的今天
返回首页

历史上的今天

今天是:2025年08月21日(星期四)

正在发生

2018年08月21日 | stm32实现iap远程固件更新

2018-08-21 来源:eefocus

前提

想来做iap升级了,应该不是什么新手。 
下面的程序需要用到一些简单的功能

  • 串口收发数据

  • 开关总中断


虽然本文标题是实现远程固件更新,但是具体远程方案本文不做详细说明,重点在于介绍mcu接收到新的固件后怎么保存更新,以及更新失败回滚等。下面简单说明一下远程的事情。 
stm32的通信方式有串口,spi,iic,以及sdio等。也就是说我们的固件可以通过这些方式传输到mcu,不过普遍常用的是串口或者用sdio(外接sd卡)这两种方式。个人觉得用sd卡来回copy也不怎么方便。简单点还是再加一个串口网络模块,然后把固件存到服务器,经由串口网络模块透传到mcu。比如用http协议把固件发送下来。远程下载就这么简单一说。接下来重点分析更新的事情。

固件生成

远程更新使用的固件和我们平时烧录程序用的固件格式有点区别,我们需要用二进制格式(.bin)文件。生成方式以mdk为例介绍一下,只需要添加一条命令行。 
这里写图片描述 
在mdk工程配置选项选择User,这个页面是让我们添加自定义命令行的,我们要添加的命令添加到第三个选项,即在编译完成后执行。下面是命令内容,需要注意的是 bin前面两个-,app1.bin就是生成的固件,名字可以自定义,**.axf是你工程实际的.axf文件,路径要正确。不知道你的axf在那在output页面查看。 

fromelf.exe --bin -o ../app1.bin ./**.axf 

现在我们就可以生成bin文件了,但是还差一点步骤。 
一般使用下mcu启动后会自动把0x0800 0000映射到地址0x0000 0000,然后取指令执行。但是现在我们程序可以理解成分成了两部分。 
这里写图片描述 
app就是我们实际实现各种功能的固件,BootLoader为控制更新的固件。可以看到加入iap升级功能后我们app的起始地址变了,所以对应工程也要做这部分修改 
这里写图片描述 
这里写图片描述 
如图,我这里把地址偏移了0x20000,同时在Linker中把“Use Memory Layout from Target Dialog”勾选,让我们的修改生效。 
如此设置以后就一些ok了 
这里写图片描述
图中上半部分是起始地址为0x800 0000 下半部分为起始地址0x802 0000,可以看到复位中断地址,以及下面一系列入口地址都相应变化了。 
关于固件有一点需要注意,因为起始地址修改了,所以导致我们的中断向量表也整体偏移了,所以需要在app程序起始添加一行代码,本文是偏移0x20000,根据实际使用做相应改动 

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000); 

固件保存

下载到板子的方式自选,下到板子后,我们需要把固件保存到内置flash对应的地址,

int writeToFlash(unsigned char *data, unsigned int len,unsigned int baseAddress )

{

    unsigned char i = 0;

    unsigned char pageNum = 0;

    FLASH_Status FLASHStatus;

    pageNum = len/FLASH_PAGE_SIZE+1;//求出总页数

    FLASH_Unlock();

    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

    for (i=0; i < pageNum; i++)

    {

        FLASHStatus = FLASH_ErasePage(baseAddress + FLASH_PAGE_SIZE*i);

        if (FLASHStatus != FLASH_COMPLETE)

        {

            FLASH_Lock();

            return -1;

        }

    }

    pageNum = (len+1)>> 1;

    for (i=0; i < pageNum; i++)

    {

        FLASHStatus = FLASH_ProgramHalfWord(baseAddress+i*2, *((unsigned short*)data+i));

        if (FLASHStatus != FLASH_COMPLETE)

        {

            FLASH_Lock();

            return -1;

        }

    }

    FLASH_Lock();

    return 0;

}

本文上面设置的偏移是0x2 0000,所以此处写入flash的地址也必须是0x802 0000(0x800 0000 + 0x2 0000) 

除了写入外,还应该加一些必要的文件完整性检查,比如使用校验等方式,这部分自行处理。然后在flash特定区域立一个flag,通知BootLoader程序更新固件。


固件更新


现在万事具备了,接下来就是更新的事情了,先简单说一下更新的思路。上电启动后运行BootLoader程序,在bootloader中检查是否是否需要更新,不需要的话就引导之前的app程序运行,需要更新就引导新的app程序。引导步骤大体就是重置栈顶指针,强制跳转app的reset复位中断。


#define APPLICATION_ADDRESS 0x08020000

typedef  void (*pFunction)(void);

int main(void)

{      

    SystemInit();

    BootLoad_Jump();

}

__asm void MSR_MSP(u32 addr) //设置堆栈指针

{

    MSR MSP, r0

    BX r14

}

void BootLoad_Jump(void)

{

    u32 JumpAddress;

    pFunction  Jump_To_Application;

    /* Check Vector Table: Test if user code is programmed starting from address 

    "APPLICATION_ADDRESS" */

    //d_printfhex32((*(__IO uint32_t*)APPLICATION_ADDRESS));d_printf("\n");

    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)

    {

    __disable_irq();

    JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS +4);

    //d_printfhex32(JumpAddress);d_printf("\n");

    Delay(100);

    Jump_To_Application = (pFunction) JumpAddress;

    /* Initialize user application's Stack Pointer */

    MSR_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

    Jump_To_Application();

    }

}


本文只贴出核心部分,也就是BootLoader直接引导app,没做其他判断。那些判断逻辑自行实现。 

顺带一提,BootLoader程序的flash地址不需要修改,即正常的0x800 0000,正常使用烧录工具下载。


完成


写博客也是对自己学习的一个记录,同时也分享一点自己一点东西给大家。如果你解决的本文对你有帮助,就支持一下作者吧。 


推荐阅读

史海拾趣

BERGQUIST公司的发展小趣事

随着产品技术的不断成熟和市场的逐步认可,BERGQUIST公司开始积极拓展市场。公司不仅在国内市场取得了显著成绩,还积极开拓国际市场,与众多知名电子企业建立了长期合作关系。通过不断提升产品质量和服务水平,BERGQUIST成功树立起了自己的品牌形象,成为热管理领域的佼佼者。

Compensated Devices Inc公司的发展小趣事

随着全球环保意识的日益增强,电子行业对环保的要求也越来越高。CDI积极响应这一趋势,将环保理念贯穿于产品研发、生产和销售的全过程。公司推出了一系列绿色环保型电子元件,并采用了环保材料和生产工艺。这一举措不仅赢得了客户的认可,还为公司的可持续发展奠定了坚实基础。

Corstat Containers公司的发展小趣事

为了提升竞争力,Corstat Containers公司不断创新服务模式。除了提供优质的电子产品包装解决方案外,公司还为客户提供定制化的服务,根据客户的需求量身定制产品。此外,公司还建立了完善的售后服务体系,为客户提供及时、专业的技术支持和售后服务,确保客户在使用过程中无后顾之忧。


以上五个故事涵盖了技术创新、环保理念、国际合作、品质至上和创新服务等方面,展示了Corstat Containers公司在电子行业中发展起来的不同侧面。然而,这些故事仅为虚构,实际情况可能有所不同。如需了解该公司的真实历史和发展情况,建议查阅相关资料或咨询相关人士。

ETERNA公司的发展小趣事

ETERNA公司起源于1856年,由格斯塔夫·罗斯切尔德和约翰·乌尔里希在瑞士的圣伊米尔创立。自成立之初,ETERNA便以精湛的制表工艺和不懈的创新精神闻名于世。公司不断推出具有划时代意义的腕表产品,其中最具代表性的是其“五点星座”设计,这一设计成为了品牌的象征,并引领了制表业的新潮流。ETERNA通过不断的技术创新和设计突破,逐渐在电子行业中崭露头角。

GarrettCom公司的发展小趣事

转折:2006年,GarrettCom迎来了一个重要的转折点——收购变电站网络产品领导者DYMEC公司。这一收购不仅增强了GarrettCom在变电站自动化领域的实力,还为其带来了更多的技术资源和市场份额。

影响:通过整合DYMEC的技术和产品,GarrettCom进一步巩固了其在变电站网络通信技术方面的领先地位。公司的产品和解决方案被广泛应用于全球各地的变电站项目中,为电力系统的稳定运行提供了坚实的通信保障。

EA Elektro-Automatik公司的发展小趣事

进入21世纪后,EA Elektro-Automatik加大了对研发的投入,致力于技术突破和产品创新。公司成功开发出一系列具有高精度、高可靠性和高性能的电力测试解决方案,如高速模拟稳压器、直流/交流源、并联操作设备等。这些产品不仅满足了市场对精密测试设备的需求,也进一步巩固了EA Elektro-Automatik在电子测量领域的领先地位。

问答坊 | AI 解惑

软件无线电架构设计组件选择策略

  当选择ASIC、FPGA或DSP时,设计人员应当考虑可程序性、整合度、开发周期、性能,以及功率等五项重要的选择准则, 上述准则中的任何一条都会对设计人员选择DSP、ASIC或FPGA产生直接的影响。 采用ASIC、FPGA和DSP组件设计 ...…

查看全部问答>

【转】如何用keil在C中嵌入汇编

本帖最后由 paulhyde 于 2014-9-15 03:44 编辑 有时候用到需要精确延时之类的子程序时,用C语言比较难控制,这时候就可以在C中嵌入汇编 比较常用的keil中嵌入汇编的方法如下所示: 如图一,在C文件中要嵌入汇编的地方用#pragma asm和#pragma end ...…

查看全部问答>

蚊子直升机

这种直升机您肯定没有见过吧,是不是很出乎您的想像,直升机还可以设计成这样,可以说我们的设计师在设计的见解上非常独特,他总是有许多不一样的想法。正因为他跳出了常规的设计思路,所以每次给大家展现的东西,都让我们眼前一亮。这种思维的跳跃 ...…

查看全部问答>

关于DDK开发中的Build SoftICE Symbols的问题,我编译的工程生成了.sys文件,但没有生成.nms等用于调试的文件,不知是否和下面的出错信息

以下是出错的内容,我不明白“Matching PDB file not found.”是什么意思,是不是说生成的.sys文件里面没有编译信息? --------------------Configuration: RepSample - Win32 Free-------------------- Compiling resources with DDK resource c ...…

查看全部问答>

linux内核移植到2440问题

按照网上的教程交叉编译了一个linux的内核,在下载到arm2440上运行不了。显示的输出信息为: Read chip id = ec76 Nand flash status = c0, NandAddr=1 buf address :0x30008000 Set boot params = root=/dev/mtdblock2  load_ramdis ...…

查看全部问答>

关于I/O的困惑!

因为想写一只关于SATA I/O的程序,这几天一直混在www.t13.org,但通读了ATA-1,并没有发现命令寄存器与端口(1f0-1f7)的对应关系.(文档中只解释了每个寄存器的含义)。根本没提及端口(1f0-1f7),只提到了针脚37对应的CS1FX。而CS1FX是什么东东 ...…

查看全部问答>

ARM的相关问题

我刚接触单片机,能不能请各位高手解释一下ARM和单片机的关系。…

查看全部问答>

PLC输出电路硬件互锁的漏洞与可怕的后果

在异步电动机的正反转控制的主电路中,两台接触器的主触点如果同时闭合,将会造成三相电源相间短路的事故,使熔断器熔断。 梯形图中的软件互锁电路并不保险,在电动机改变旋转方向的过程中,可能原来接通的接触器的主触点的电弧还没有熄灭,另一个 ...…

查看全部问答>