STM32 BootLoader升级固件

发布者:runaway2000最新更新时间:2018-08-19 来源: eefocus关键字:STM32  BootLoader  升级固件 手机看文章 扫描二维码
随时随地手机看文章

关于Bootloader,从书上的文字描述,很难理解这个名词是什么,有什么用。这次用到了,算是有了更进一步的认识。

一、知识点

  • 1、BootLoader就是单片机启动时候运行的一段小程序,这段程序负责单片机固件的更新,也就是单片机选择性的自己给自己下程序。可以更新,也可以不更新,更新的话,BootLoader更新完程序后,跳转到新程序运行;不更新的话,BootLoader直接跳转到原来的程序去运行。

  • 2、BootLoader更新完程序后并不擦除自己,下次启动后依然先运行BootLoader程序,又可以选择性的更新或者不更新程序,所以BootLoader就是用来管理单片机程序的更新。

  • 3、在实际的单片机工程项目中,如果加入了BootLoader功能,就可以给单片机日后升级程序留出一个接口,方便日后单片机程序更新。当然,这就需要创建两个工程项目,一个为BootLoader工程,一个为APP工程。

  • 4、BootLoader工程生成的.hex或者.bin文件通常下载到ROM或Flash中的首地址,这样可以保证上电后先运行BootLoader程序。而APP工程生成的.hex或者.bin文件则下载到ROM或Flash中BootLoader后面的地址中。也就是说,存在ROM/Flash中的内容是分为两部分的。

  • 5、要实现在同一个ROM/Flash中保存两段程序,并且保证不能相互覆盖,则需要在下载程序时指定地址。如在Keil下,可以进行如下的调整。

这里写图片描述

  • 6、实际上,在STM32系列的单片机中,Flash本身就是分扇区的,一个扇区16KB的样子,具体可以查看手册。那么就可以用从第一个扇区的首地址开始下载BootLoader的程序,而从第二个扇区的起始地址开始下载APP程序。如下为STM32F4系列芯片的Flash模块。

这里写图片描述

  • 7、单片机上电之后开始执行BootLoader程序,这是单片机会检测用户是否有升级应用程序(APP)的请求,具体表现有很多种,例如检测内存卡,Nand Flash中是否包含升级文件,串口/I2C/SPI等外设接口是否传来升级文件。据说还有使用GSM来升级的。

  • 8、所谓的升级,就是将ROM/Flash中存储APP程序的扇区内容擦除并写入新文件。例如一次固件升级的过程可以是:1、单片机上电执行BootLoader,2、BootLoader查找升级文件,3、若找到文件,擦除Flash中的部分扇区(存APP的),4、在擦除的扇区写入升级的文件,5、写入完成,读取数据检验是否出错,6、若数据一致,升级成功,删除升级文件,7、BootLoader程序跳转到APP程序执行。删除升级文件是为了下次上电后不再进行升级。

  • 9、所谓的跳转,可以理解程序指针的改变,变为指向APP程序扇区的起始地址。

二、部分代码


1、主函数

int main(void)

{

    HAL_Init();//STM32初始化

    SystemClock_Config();//时钟配置

    System_GPIOInit();//IO口配置


    #ifdef BOOTLOAD_DISPLAY_ENABLE

    SystemColorInit();//显示屏配置

    #endif


    System_LoadUpdateFile();//升级函数

    while (1)

    {


    }

}


2、升级函数

void System_LoadUpdateFile(void)

{

    uint8_t res;    

    if(bNandFlash_Error)//如果NandFlash错误,串口打印错误信息,跳转到用户程序

    {

        d_printf("NandFlash_Error jump\n");

        BootLoad_Jump();//跳转函数

        return;

    }

    if(bNo_FileSystem)//如果没有文件系统,串口打印错误信息,跳转到用户程序

    {

        d_printf("no file system jump\n");

        BootLoad_Jump();//跳转函数

        return;

    }

    if(f_open(&File, (char *)UPDATE_FILE_PATH, FA_READ)==FR_OK)//如果存在升级文件,开始执行升级

    {

        d_printf("update\n");

        if(BootLoad_Program())//是否写入成功

        {

            f_close(&File);//关闭升级文件

            res=f_unlink((char *)UPDATE_FILE_PATH);//删除升级文件

            d_printfhex(res);d_printf("\n");

            res=f_unlink((char *)UPDATE_DIR_PATH);//删除升级目录

            d_printfhex(res);d_printf("\n");


            BootLoad_Jump();//跳转函数

        }

        else

        {

            HAL_FLASH_Lock();//锁定Flash

            d_printf("update fail\n");

            f_close(&File);//关闭升级文件

            BootLoad_Jump();//跳转函数

        }       

    }

    else

    {

        d_printf("jump\n");

        f_close(&File);

        BootLoad_Jump();

    }

}


3、重写Flash函数

uint8_t BootLoad_Program(void)

{

    uint32_t BaseAddress=APPLICATION_ADDRESS;//APP地址

    uint32_t i,br,datacnt=0;

    uint8_t data8;

    GlobalPtr32=(uint32_t *)BootBuff;

    HAL_FLASH_Unlock();//解锁Flash

    if(BootLoad_Erase()==false)//擦除Flash

    {

        return false;

    }

    d_printf("size:");d_printfhex32(File.fsize);d_printf("\n");

    while(1)

    {

        f_read(&File,BootBuff,8192,(void *)&br);//读取升级文件

        for (i=0;i<(br>>2);i++)

        {

            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BaseAddress, GlobalPtr32[i]) == HAL_OK)//写入升级文件

            {

                BaseAddress = BaseAddress +4;

            }

            else

            { 

                d_printf("program err\n");

                return false;

            }

        }

        datacnt+=br;

        if(datacnt>=File.fsize)//写入完成

        {

            break;

        }

    }

    d_printf("verify\n");       //验证Flash中的内容与升级文件是否一致

    f_lseek(&File,0);           //若一致代表升级成功

    datacnt=0;                  //若不一致代表升级失败

    BaseAddress=APPLICATION_ADDRESS;

    while(1)

    {

        f_read(&File,BootBuff,8192,(void *)&br);

        for (i=0;i

        {

            data8 = *(__IO uint8_t*)BaseAddress;

            if (data8 != BootBuff[i])

            {

                d_printf("error!\n");

                return false;

            }

            BaseAddress ++;

        }

        datacnt+=br;

        if(datacnt>=File.fsize)

        {

            break;

        }

    }

    HAL_FLASH_Lock();//锁定Flash

    return true;

}


4、跳转函数(从BootLoader中跳转到APP的main函数)

void BootLoad_Jump(void)

{

    /* 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)

    {

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

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

    HAL_Delay(100);

    Jump_To_Application = (pFunction) JumpAddress;

    /* Initialize user application's Stack Pointer */

    __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

    Jump_To_Application();

    }

}


关键字:STM32  BootLoader  升级固件 引用地址:STM32 BootLoader升级固件

上一篇:STM32CubeMX Hal库的一些坑
下一篇:stm32最简单的实现BootLoader

推荐阅读最新更新时间:2024-03-16 16:11

STM32固件库文件分析
1-汇编编写的启动文件 startup_stm32f10x_hd.s:设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、对用C库函数_main最终去到C的世界 2-时钟配置文件 system_stm32f10x.c:把外部时钟HSE=8M,经过PLL倍频为72M。 3-外设相关的 stm32f10x.h:实现了内核之外的外设的寄存器映射 xxx:GPIO、USRAT、I2C、SPI、FSMC stm32f10x_xx.c:外设的驱动函数库文件 stm32f10x_xx.h:存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明 4-内核相关的 CMSIS - Cortex 微控制器软件接
[单片机]
STM32的FLASH模拟EEPROM
1. Flash.h /* ******************************************************************* ** ** @Brief : STM32 FLASH 模拟EEPROM ** @Cpu : STM32F103ZET6 ** @Flash : 512K 字节 ** @Note : 源码来自正点原子stm32 教程 ******************************************************************* */ #ifndef __STMFLASH_H__ #define __STMFLASH_H__ #incl
[单片机]
STM32定时器时钟配置问题说明SystemCoreClock
在研究STM32L476的通用定时器时,遇到了一个关于SystemCoreClock值=4000000U的问题,琢磨了好久,终于弄明白了,这里记录一下。 1、定时器初始化函数中 2、其中的SystemCoreClock是在system_stm32l4xx.c文件中定义的一个变量 3、其实这个值在此处只是一个变量定义时的初始值,系统在时钟初始化时会使用上面的方法3进行更新的。在SystemClock_Config中会调用HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3)函数更新系统时钟。 4、在HAL_RCC_ClockConfig 5、在HAL_RC
[单片机]
<font color='red'>STM32</font>定时器时钟配置问题说明SystemCoreClock
意法与厦门大学合作研发32位嵌入式系统
        微控制器设计开发的厂商意法半导体协同其增值服务商深圳市博巨兴,宣布与厦门大学签订合作协议,成立“ST嵌入式系统联合实验室”,并举行实验室揭牌仪式。意法半导体持续推动校园合作计划,与中国的大学携手开发嵌入式应用技术和培训电子工程专业学生,再迈出重要的一步。   作为32位微控制器的主导厂商之一,意法半导体将向厦门大学提供先进的基于32位ARM CORTEX-M3的STM32微控制器及其开发工具,信息科学与技术学院(通信工程系、电子工程系、自动化系、计算机系及智能科学与技术系)的本科生及研究生将参与意法半导体的实际项目的开发。此外,意法半导体将提供所需的全部培训和技术支持,从事教学和学术研究,协助大学院校及产业
[单片机]
STM32入门经历
现在STM32初学入门,写些关于入门的帮助,也算答谢帮助过我的人.希望象我这样想学STM32的朋友不用迷茫.(本入门只适合低手,高手不要见笑). 1.硬件平台. 现在可以买到学习有的有英蓓特的MCBSTM32 和万利的EK-STM32F,反正这两个板我都买了399元和199买的.实惠,如果你自己开板做,成本还比这高.学会了才自己做自己的板子吧. 2.软件平台. 现在流行的有Keil MDK 3.15b和 IAR EWARM 4.42A. 购买评估板时,里面的光盘已经带了.为什么选这两个平台,用的人多,你以后遇到问题,可以找人解决的机会就大.英蓓特的MCBSTM32用的是Keil MDK平台, 万利的是 I
[单片机]
STM32 FSMC机制flash拓展
STM32是ST(意法半导体)公司推出的基于ARM内核Cortex-M3的32位微控制器系列。Cortex-M3内核是为低功耗和价格敏感的应用而专门设计的,具有突出的能效比和处理速度。通过采用Thumb-2高密度指令集,Cortex-M3内核降低了系统存储要求,同时快速的中断处理能够满足控制领域的高实时性要求,使基于该内核设计的STM32系列微控制器能够以更优越的性价比,面向更广泛的应用领域。 STM32系列微控制器为用户提供了丰富的选择,可适用于工业控制、智能家电、建筑安防、医疗设备以及消费类电子产品等多方位嵌入式系统设计。STM32系列采用一种新型的存储器扩展技术——FSMC,在外部存储器扩展方面具有独特的优势,可根据系统的
[单片机]
<font color='red'>STM32</font> FSMC机制flash拓展
STM32入门学习之GPIO(STM32F030F4P6基于CooCox IDE)
依然,直接上代码 #include stm32f0xx.h #include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_gpio.h int main(void) { //IOPAEN=1,使能GPIOA的时钟 RCC- AHBENR |= RCC_AHBENR_GPIOAEN; //设置IO口工作模式,GPIOA_MODER4=0x01,通用IO口 GPIOA- MODER |= GPIO_MODER_MODER4_0; GPIOA- MODER &= ~GPIO_MODER_MODER4_1; //设置输出类型,GPIO
[单片机]
STM32 CAN总线应用程序,调试通过仅供参考
1、打开STM32 CAN系统工作时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 2、开放系统中断,根据实际情况选择 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NV
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved