STM32CubeMx开发之路—移植easyflash

本文详细介绍了在STM32CubeMX环境下移植easyflash库的步骤,包括配置环境、添加源码、修改配置文件及实现接口函数,最后通过实例验证移植成功。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


运行环境

  • Windows10
  • STM32CubeMX Version 5.4.0
  • Keil5(MDK5) Version 5.28.0.0
  • 硬件开发板 F103RB-NUCLEO

简介

本例程主要讲解如何移植easyflash.


STM32CubeMx基本配置

基础配置过程请参考 STM32CubeMx开发之路—配置第一个项目


使用printf功能

重定向printf的过程请参考 STM32CubeMx开发之路—3发送USART数据和printf重定向

本例程不需要其他什么外设资源, 配置printf()主要是方便我们调试.

下载easyflash源码

下载EasyFlash源码

会得到一个源码的仓库, 如下图所示

注意: 源码的说明文档里面已经说明了如何使用这个库, 大家也可以参考这个说明进行移植, 我这儿根据自己的移植思路针对STM32使用HAL库做移植说明.


在自己的代码中添加easyflash所需要的文件

  • 将EasyFlash源码源码中的easyflash文件夹复制到自己的工程中, 如下图:

代码修改

  • 添加easyflash的资源文件夹, 如下图:
  • 添加下面4个文件文件
    easyflash/src/easyflash.c
    easyflash/src/ef_env.c
    easyflash/src/ef_utils.c
    easyflash/port/ef_port.c
  • 如图:
  • 添加路径, 如图
  • 添加好后, 如图:

  • 编译
  • 会发现有很多错误, 先不要慌, 出现错误是因为我们还没有进行配置的

  • 打开ef_cfg.h文件进行配置, 具体怎么修改见下图:

  • 随便写个版本本号, 我写的是0

  • 根据实际情况填写最小擦除粒度, 我是用的是F103rb所以我写的是1024, 如果你使用的是F103ze就应该填2048,根据实际情况进行填写
  • EF_WRITE_GRAN32(上面有注释,如果是stm32f4就要填8)
  • 填写easyflash的开始地址,我划分的分区是后面64K, 所以我填的是(64 * EF_ERASE_MIN_SIZE + 0x08000000)
  • ENV_AREA_SIZE填写(EF_ERASE_MIN_SIZE * 2)
  • #define LOG_AREA_SIZE因为我没有使用到, 所以我就把它注释掉了
  • 如下图:

  • 打开ef_port.c文件,就下来配置接口
  • 主要实现一下几个函数的接口
  • ef_port_init(如果使用FAL, 则需要配置,本例程不需要配置)
  • ef_port_read
  • ef_port_erase
  • ef_port_write
  • 下面我已经写好了, 大家可以直接复制使用

  • 1.添加头文件, 在最上面添加#include "main.h"

  • 2.添加读函数
EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) {
    EfErrCode result = EF_NO_ERR;

    /* You can add your code under here. */
    uint8_t *buf_8 = (uint8_t *)buf;
    size_t i;
    for (i = 0; i < size; i++, addr ++, buf_8++)
    {
      *buf_8 = *(uint8_t *) addr;
    }
    return result;
}

  • 3.添加擦除函数
EfErrCode ef_port_erase(uint32_t addr, size_t size) {
    EfErrCode result = EF_NO_ERR;

    /* make sure the start address is a multiple of EF_ERASE_MIN_SIZE */
    EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);

    /* You can add your code under here. */
    HAL_FLASH_Unlock();

    /* 擦除FLASH*/
    FLASH_EraseInitTypeDef FlashSet;
    FlashSet.TypeErase = FLASH_TYPEERASE_PAGES;
    FlashSet.PageAddress = addr;
    FlashSet.NbPages = (size + EF_ERASE_MIN_SIZE -1)/ EF_ERASE_MIN_SIZE;

    /*设置PageError,调用擦除函数*/
    uint32_t PageError = 0;
    HAL_FLASHEx_Erase(&FlashSet, &PageError);

    HAL_FLASH_Lock();
    return result;
}

  • 4.添加写函数
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) {
    EfErrCode result = EF_NO_ERR;

    /* You can add your code under here. */
    size_t i;
    uint32_t read_data;

    HAL_FLASH_Unlock();
    for (i = 0; i < size; i += 4, buf++, addr += 4)
    {
      /* write data */
      HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *buf);
      read_data = *(uint32_t *)addr;
      /* check data */
      if (read_data != *buf)
      {
        result = EF_WRITE_ERR;
        break;
      }
    }
   HAL_FLASH_Lock();
    return result;
}

  • 修改ef_port.c的向量表, 添加要使用的变量
  • 如下图:

写测试程序

  • 在主函数中添加#include "easyflash.h"头文件
  • 在主函数添加如下测试代码:
  /* USER CODE BEGIN 2 */
  unsigned int Reboot_Time = 0;
  if(easyflash_init() == EF_NO_ERR)                         // 初始化成功
  {
    ef_get_env_blob("reboot_time", &Reboot_Time, 8, NULL);  // 读出reboot_time的值
  }
  Reboot_Time++;                                            // reboot_time的值加1

  ef_set_env_blob("reboot_time",&Reboot_Time,8);            // 保存reboot_time的值
  printf("Reboot_Time is %d\n",Reboot_Time);                // 打印reboot_time的值
  /* USER CODE END 2 */

测试输出

  • 打开串口调试助手
  • 按复位按键, 会发现每次复位之后咱们存的值会增加1, 说明测试成功!

源代码获取

源码已放到码云 ! ! ! ( 请点击文首链接进入仓库 )


### STM32 Flash 大小定义与配置 STM32 的闪存大小在不同的系列和型号中有所差异,通常会在芯片的数据手册(Datasheet)中明确列出。此外,闪存的大小也可以通过软件配置文件进行定义和使用。 #### 1. Flash 大小定义 在 STM32 的 HAL 库或标准库中,Flash 的大小可以通过特定的宏或配置文件来定义。例如,在 STM32F4 系列中,`stm32f4xx_hal_conf.h` 文件中需要开启宏定义 `HAL_FLASH_MODULE_ENABLED`[^2],这表明 Flash 模块已被启用。 对于 STM32G473CBT6 芯片,其内部 Flash 的大小为 128KB[^3]。此信息通常可以在芯片的数据手册中找到,并且在开发环境中也需要正确配置以确保代码能够正常运行。 #### 2. 配置文件中的 Flash 定义 在 EasyFlash移植过程中,需要对 `ef_cfg.h` 和 `ef_port.c` 文件进行配置以适配具体的 Flash 参数[^1]。这些参数可能包括 Flash 的起始地址、扇区大小以及总大小等。 以下是一个常见的 Flash 配置示例: ```c #define FLASH_BASE_ADDRESS 0x08000000 // Flash 起始地址 #define FLASH_SECTOR_SIZE 0x1000 // 每个扇区的大小(以字节为单位) #define FLASH_TOTAL_SIZE 0x20000 // 总 Flash 大小(以字节为单位) ``` #### 3. 外部 Flash 的配置 如果使用外部 Flash(如 GD25Q16),则需要通过 SPI 协议进行驱动配置[^5]。外部 Flash 的大小定义通常在驱动文件中指定,例如: ```c #define EXTERNAL_FLASH_SIZE (2 * 1024 * 1024) // 2MB 外部 Flash ``` #### 4. Flash 配置的注意事项 - 在 STM32 的 HAL 库中,Flash 操作的时钟频率受到系统时钟的影响。例如,STM32F103 的 SCK 时钟频率最高可达 `fpclk/2`,其中 `fpclk1` 默认为 42MHz,`fpclk2` 默认为 84MHz[^4]。 - 对于内部 Flash,确保开发环境(如 CubeMX 或 Keil)中正确配置了芯片型号及其对应的 Flash 大小。 ```python # 示例:通过 Python 计算 Flash 扇区数量 flash_total_size = 0x20000 # 总 Flash 大小(字节) flash_sector_size = 0x1000 # 每个扇区大小(字节) sector_count = flash_total_size // flash_sector_size print(f"Total sectors: {sector_count}") ```
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iot 小胡

从未指望过会有人打赏...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值