STM32 IAP example

发布者:Zhenxiang最新更新时间:2024-09-30 来源: cnblogs关键字:STM32  IAP 手机看文章 扫描二维码
随时随地手机看文章

1. 首先启用 Flash模式.

a)确认 stm32f7xx_hal_conf.h 中 启用了 #define HAL_FLASH_MODULE_ENABLED

b)在 Drivers/STM32F7xx_HAL_Drivers中确认添加了源码  stm32f7xx_hal_cortex/flash/flash_ex.c 三个文件.

2. 对flash进行分区.

512K 共 8个扇区. 擦除的时候只能根据删除擦除.

/* Base address of the Flash sectors Bank 1 */

#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */

#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */

#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */

#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */

#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */

#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */

#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */

#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */

我们的要求.

l  我们自己的 bootloader.  <16K

l  信息区. <16K.

l  程序区. 自己的程序 < 64K.

l  OTA升级区. < 64K.

所以设定

#define NDADDR_BOOT                 ADDR_FLASH_SECTOR_0  //SECTOR_0 16K

#define NDADDR_INFO                  ADDR_FLASH_SECTOR_1  //SECTOR_1 16K

#define NDADDR_FW_APP               ADDR_FLASH_SECTOR_5  //SECTOR_5 128K

#define NDADDR_FW_OTA               ADDR_FLASH_SECTOR_6  //SECTOR_6 128K

#define FW_MAX_SIZE                           ((uint32_t)0x00020000)  //固件最大 128K

3.      Flash 操作代码

#ifndef _FIRMWARE_OTA_CONF_INC_H_

#define _FIRMWARE_OTA_CONF_INC_H_

#include

#include

/* Exported types ------------------------------------------------------------*/

typedef  void (*pFunction)(void);

/* Base address of the Flash sectors Bank 1 */

#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */

#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */

#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */

#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */

#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */

#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */

#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */

#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */

#if 0

#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */

#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */

#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */

#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */

/* Base address of the Flash sectors Bank 2 */

#define ADDR_FLASH_SECTOR_12     ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */

#define ADDR_FLASH_SECTOR_13     ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */

#define ADDR_FLASH_SECTOR_14     ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */

#define ADDR_FLASH_SECTOR_15     ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */

#define ADDR_FLASH_SECTOR_16     ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */

#define ADDR_FLASH_SECTOR_17     ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */

#define ADDR_FLASH_SECTOR_18     ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */

#define ADDR_FLASH_SECTOR_19     ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */

#define ADDR_FLASH_SECTOR_20     ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes  */

#define ADDR_FLASH_SECTOR_21     ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes  */

#define ADDR_FLASH_SECTOR_22     ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */

#define ADDR_FLASH_SECTOR_23     ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */

#endif

#define NDADDR_BOOT                 ADDR_FLASH_SECTOR_0  //SECTOR_0 16K

#define NDADDR_INFO                 ADDR_FLASH_SECTOR_1  //SECTOR_1 16K

#define NDADDR_FW_APP               ADDR_FLASH_SECTOR_5  //SECTOR_5 128K

#define NDADDR_FW_OTA               ADDR_FLASH_SECTOR_6  //SECTOR_6 128K

#define FW_MAX_SIZE                           ((uint32_t)0x00020000)  //固件最大 128K

#define FW_PAGE_SIZE                ((uint32_t)0x00000800)  //写入的单位 2K.

/*

* 固件升级步骤.

* 确定当前的 FW的位置是那个, FW1/FW2, 确定完毕后就知道要写那个.

* YMODEM 获取满 2K 数据.  FMC_FLASH_PAGE_SIZE, 然后写入一个页中.

* 最后改写配置, 引导的 APROM 起始地址.

*/

void nd_FlashUnlock(void);

void nd_FlashLock(void);

bool ota_EraseSector(void);

bool app_EraseSector(void);

bool config_EraseSector(void);

bool nd_flash_write(uint32_t Address, uint8_t *pData, uint32_t size);

void nd_flash_read(uint32_t Address, uint8_t *pData, uint32_t size);

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

/* 出厂设置内容. 保证4字节对齐. */

typedef struct {

    uint32_t            fw_addr;    //最新有效的固件的flash地址. 

    uint32_t            page_cnt;  //最新有效的固件的页数   (2K计数)

    uint64_t                     sn;

}nd_ota_config_t;

extern nd_ota_config_t g_ota_conf ;

void load_factory_config(void);

void save_factory_config(void);

#endif //_FIRMWARE_OTA_CONF_INC_H_

Flash部分的封装 实现

#include 'main.h'

#include 'fw_ota.h'

void NVIC_SetVectorTable(uint32_t ApplicationFlashAddress)

{

  SCB->VTOR = ApplicationFlashAddress;

}

//Unlocks the Flash to enable the flash control register access.

void nd_FlashUnlock(void)

{

  HAL_FLASH_Unlock();

  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR);

}

void nd_FlashLock(void)

{

  HAL_FLASH_Lock();

}

/*对指定地址上写入4字节数据.

  Address + data 必须 4字节对齐.  写完之后下次写入的 Address 和 data 都要+4.

  * @retval true: Data successfully written to Flash memory

  *         false: Error occurred while writing data in Flash memory

  */

static bool flash_Write_Word(uint32_t Address, uint32_t *Data)

{

  return (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, *Data));

}

static bool flash_Write_HalfWord(uint32_t Address, uint16_t *Data)

{

  return (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, *Data));

}

bool nd_flash_write(uint32_t Address, uint8_t *pData, uint32_t size)

{

  if ((size % 4) != 0) return false;

  uint32_t nbWrites = size / 4;

  uint32_t idx;

 

  for (idx = 0; idx < nbWrites; idx++) {

    if (false == flash_Write_Word(Address, (uint32_t *)pData)) 

      return false;

    pData+=4;

    Address+=4;

  }

  return true;

}

//读 不需要做 unlock.

void nd_flash_read(uint32_t Address, uint8_t *pData, uint32_t size)

{

  uint32_t idx;

  for (idx = 0; idx < size; idx++)  {

    *pData = *(__IO uint8_t *)Address;

    pData++;

    Address++;

  }

}

///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////

[1] [2]
关键字:STM32  IAP 引用地址:STM32 IAP example

上一篇:Stm32空指令使用
下一篇:STM32 UART/USART 的差别

推荐阅读最新更新时间:2026-03-19 11:51

STM32 IAP example
1. 首先启用 Flash模式. a)确认 stm32f7xx_hal_conf.h 中 启用了 #define HAL_FLASH_MODULE_ENABLED b)在 Drivers/STM32F7xx_HAL_Drivers中确认添加了源码 stm32f7xx_hal_cortex/flash/flash_ex.c 三个文件. 2. 对flash进行分区. 512K 共 8个扇区. 擦除的时候只能根据删除擦除. /* Base address of the Flash sectors Bank 1 */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Bas
[单片机]
STM32IAP方案
简介:本文将讲述一个STM32的综合性应用示例,该示例将涉及到STM32微控制器的时钟系统、GPIO、定时器、中断系统、异步串口以及内置可编程flash等设备的应用,作为一个综合性实验的同时还具有很强的“实用”意义。这个示例就是STM32的IAP方案。 几乎所有的同类书籍都介绍综合性的应用示例如“万年历 +温度显示+闹钟响铃+计时表”这样的一个实时时钟范例或“STM32 +音频解码+大容量存储方案”这样的MP3播放器范例。这些综合性实例的目的在于引领读者进行综合性实验,达到把单片机的基础模块整合运用的目的。这些实例普遍存在一种共同点,即“练手”意义要大于“实用”的意义。本文将讲述一个STM32的综合性应用示例,该示例将涉及到S
[单片机]
关于STM32IAP总结
最近有项目要用到IAP的功能,于是调试了下STM32的IAP,可能因为个人水平的原因吧,也颇 费了一般周折 现在返回头来想,其实还是蛮简单的. 整个过程按照如下步骤: 1.解锁 2.判断是否保护,有保护的话要先关闭保护 3.擦除 4.编程 5.复位进入应用程序区 关于解锁:看资料的时候说的神乎其神,有个读/编程控制器叫”FPEC 有几个寄存器,专门负责Flash的,对这几个寄存器以一定得顺序访问并设置即可成功解锁Flash,至于怎么访问,谁先谁后,数据手册上写的头晕,直接来个快刀斩乱麻Flash_UnLock()函数封装了这一系列的操作,有一点要注意,如果你是自己操作寄存器的话,如果操作的方法或者顺序不对都会造成Flash
[单片机]
怎么使用stm32IAP的bootloader和APP
Stm32的bootloader和App的编写注意事项 1、 怎么分配bootloader和app的空间 2、 怎么得到数据和写入flash 3、 怎么从bootloader跳转到app 4、 怎么设置App的中断向量 5、 App中怎么生成bin文件 6、程序执行的流程 1、怎么分配bootloader和app的空间 因为我用的是stm32f103c8t6,它的flash的大小是64k,所以把它分成如上所示 0x08000000 —0x0800 33FF分配给bootloader使用,大小是13k 0x0800 3400----0x080097FF分配给第一个APP的使用,大小是25k 0x08009800----0x080
[单片机]
STM32高级开发(9)-学习与编译libopencm3-example
在前面的几篇中我们为大家介绍了在Linux下stm32开发环境的新特性和使用方式,可能大家觉得,我怎么写一个工程还要自己写链接文件和启动文件,是不是太不方便了点。那么这篇中我会告诉大家其实并不是这样的。在我们日常的一些小规模工程下我们是可以使用一个叫做libopencm3的cortexM核的通用驱动库来配置我们的工程。那么大型的工程呢?有童鞋还会问道。对于大型的工程,我想:自己去改写链接文件和启动文件,使得你对整个系统的启动及运行流程更好的把控绝对是物有所值的,在这两个文件上付出的短短的时间绝对会为我们带来超出他们花费的价值。 Libopencm3简介 libopencm3项目(以前称为libopenstm32)旨在创建一个适
[单片机]
<font color='red'>STM32</font>高级开发(9)-学习与编译libopencm3-<font color='red'>example</font>
STM32 IAP相关知识
最近因项目需求要实现STM32的在线升级即IAP功能,先将这几天的学习体会和IAP的具体实现总结出来,分享给大家,希望对同样实现IAP的童鞋有所帮助,文中最后会上传名为STM32_Update.zip的压缩文件里面包含了STM32_App、STM32_MyBoot_V1.0和升级软件STM32_UpdateSoftware的源码文件供大家参考。所有程序都经过测试,可以直接在原子哥的 开发板 上跑,上位机的升级软件大家可以直接打开 STM32_UpdateSTM32_UpdateSoftwareReleaseSTM32_UpdateSoftware.exe来升级,如果需要查看源码请用VS2010打开工程文件。 最终要实现的是: 单片
[单片机]
<font color='red'>STM32</font> <font color='red'>IAP</font>相关知识
基于STM32的串口环形队列IAP调试心得
IAP很常见了,我这里主要是记录一下我所使用的方法,调试也花了两天时间。我所用的型号是STM32F103C8T6,这个片子估计是目前性价比最高的了,所以平时也都是用的这个。这个IC有64KFlash和20K的RAM,也有小道说有后置隐藏的64K,也就是说其实是有128K,我一直也没有测试,有空测测,有大神这样说,估计是可以的。这里重点记录一下我写的IAP思路和代码以及细节和遇到坑的地方。先大体的概述一下,最后贴上我认为重点的代码。 在概述之前先要解决一个问题,那就是sram空间和flash空间的问题,sram只有20K,flash有64k。 解决的办法有很多: 1)最常见的就是自己写上位机软件,通过分包发送,期间还可以
[单片机]
基于<font color='red'>STM32</font>的串口环形队列<font color='red'>IAP</font>调试心得
STM32串口IAP实验详解
一、关于IAP的简介 关于STM32的常用编程方式分为以下两种: 在线编程(ICP);通过SWD/JTAG协议下载应用程序到微控制器中。 在程序中编程(IAP);通过一种通信接口(UART、USB、SPI等)将程序下载到应用数据存储器中。 IAP(In Application Programming),在应用中编程,目的是为了在线升级使用,在产品发布后可以通过预留的通信接口将更新后的程序下载到数据存储器中。(更新的数据可以使用上网的模块从服务器上获取数据实现远程更新) 二、IAP的原理 IAP其实将传统的程序分为了两个部分,一个称为BootLoader区,另一个称为APP区域(用于存放用户升级的程序)。 其中
[单片机]
<font color='red'>STM32</font>串口<font color='red'>IAP</font>实验详解
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved