stm32f103使用RT-Thread组件fal读写内部flash



本次使用RT-Thread studio编写,使用为5.02完整版,目的是将内部flash进行分区,可以直接在内部flash存储数据。

一、功能配置

首先是打开设置里的FAL组件,因为我这里不需要外部内存,SFUD驱动就没打开:
在这里插入图片描述
然后是配置两个参数,一个在board.h里,定义BSP_USING_ON_CHIP_FLASH,一个是在stm32xxxx_hal_config.h里定义HAL_FLASH_MODULE_ENABLED,这个步骤在board.h里面可以看到:

/** if you want to use on chip flash you can use the following instructions.
 *
 * STEP 1 define macro related to the on chip flash
 *                 such as    BSP_USING_ON_CHIP_FLASH
 *
 * STEP 2, modify your stm32xxxx_hal_config.h file to support on chip flash peripherals. define macro related to the peripherals
 *                 such as     #define HAL_FLASH_MODULE_ENABLED

二、取消构建排除与添加路径

这里必须要吐槽一下,RT-Thread studio配置完一个功能后就会把配置和路径回到初始状态,所以经常是添加一个东西报出来一大堆错误,还有就是头文件路径,已经include了还得一个一个配置路径,要是和MATLAB一样可以直接添加文件及文件夹下所有文件夹就好了,搞得都想放弃这个软件了。
言归正传,首先就是要取消porting的构建并添加进路径:
在这里插入图片描述
在这里插入图片描述
然后多编译几次,看缺少什么头文件直接添加路径就可以了。

三、fal_flash_stm32f1_port.c代码

最后要添加fal_flash_stm32f1_port.c文件,这个我也是看别人写的,感觉没必要重复造轮子,因为原来生成的是fal_flash_stm32f2_port.c的文件,将这个不参加构建就行了。

/*
 * Copyright (c) 2020, Armink, <armink.ztl@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <fal.h>
#include <stm32f1xx.h>

#if defined(STM32F103xE)
#define PAGE_SIZE     2048
#else
#define PAGE_SIZE     1024
#endif

/*
STM32F1会因容量不同而不同
    小容量和中容量产品主存储块128KB以下,  每页1KB。
    大容量和互联型产品主存储块256KB以上,  每页2KB。

GD32   会因容量不同而不同
    1. Low-density Products     Flash容量从 16KB到  32KB的产品
    2. Medium-density Products  Flash容量从 64KB到 128KB的产品
          全是1K
    3. High-density Products    Flash容量从256KB到 512KB的产品
          全是2K
    4. XL-density Products      Flash容量从768KB到3072KB的产品
          <512K 是2K
          >512K 是4K

雅特力
    全是2K

STM32F4
    STM32F4的flash页尺寸不一样,低地址16KB,高地址32KB或128KB.
*/


static int init(void)
{
    /* do nothing now */
    return 1;
}


static int ef_err_port_cnt = 0;
int on_ic_read_cnt  = 0;
int on_ic_write_cnt = 0;

void feed_dog(void)
{

}

static int read(long offset, uint8_t *buf, size_t size)
{

    size_t i;
    uint32_t addr = stm32_onchip_flash.addr + offset;

    if( addr%4 != 0)
        ef_err_port_cnt++;

    for (i = 0; i < size; i++, addr++, buf++)
    {
        *buf = *(uint8_t *) addr;
    }
    on_ic_read_cnt++;
    return size;
}


static int write(long offset, const uint8_t *buf, size_t size)
{
    size_t   i;
    uint32_t addr = stm32_onchip_flash.addr + offset;

    __ALIGN_BEGIN uint32_t write_data __ALIGN_END;
    __ALIGN_BEGIN uint32_t read_data  __ALIGN_END;  

    if(addr%4 != 0)
        ef_err_port_cnt++;

/*
    if((int)buf%4 != 0)
        ef_err_port_cnt++;
*/

    HAL_FLASH_Unlock();
    for (i = 0; i < size; i += 4, buf+=4, addr += 4) {
        memcpy(&write_data, buf, 4); //用以保证HAL_FLASH_Program的第三个参数是内存首地址对齐
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, write_data);
        read_data = *(uint32_t *)addr;
        /* You can add your code under here. */
        if (read_data != write_data) {
            HAL_FLASH_Lock(); 
            return -1;
        }
        else{
			//FLash操作可能非常耗时,如果有看门狗需要喂狗,以下代码由用户实现
           feed_dog();
        }
    }
    HAL_FLASH_Lock();

    on_ic_write_cnt++;
    return size;
}


static int erase(long offset, size_t size)
{
    uint32_t addr = stm32_onchip_flash.addr + offset;

    HAL_StatusTypeDef flash_status;
    size_t erase_pages, i;
    uint32_t PAGEError = 0;

    erase_pages = size / PAGE_SIZE;
    if (size % PAGE_SIZE != 0) {
        erase_pages++;
    }

    FLASH_EraseInitTypeDef EraseInitStruct;
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.NbPages     = 1;  //一次擦出一个扇区, 以执行一次喂狗,防止超时
    HAL_FLASH_Unlock();
    
    for (i = 0; i < erase_pages; i++) {
        EraseInitStruct.PageAddress = addr + (FLASH_PAGE_SIZE * i);
        flash_status = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
        if (flash_status != HAL_OK) {
            HAL_FLASH_Lock(); 
            return -1;
        }
        else{
			//FLash操作可能非常耗时,如果有看门狗需要喂狗,以下代码由用户实现
            feed_dog();
        }
    }
    HAL_FLASH_Lock(); 

    return size;
}


/*
  "stm32_onchip" : Flash 设备的名字。
  0x08000000: 对 Flash 操作的起始地址。
  1024*1024:Flash 的总大小(1MB)。
  128*1024:Flash 块/扇区大小(因为 STM32F2 各块大小不均匀,所以擦除粒度为最大块的大小:128K)。
  {init, read, write, erase} :Flash 的操作函数。 如果没有 init 初始化过程,第一个操作函数位置可以置空。
  8 : 设置写粒度,单位 bit, 0 表示未生效(默认值为 0 ),该成员是 fal 版本大于 0.4.0 的新增成员。各个 flash 写入粒度不尽相同,可通过该成员进行设置,以下列举几种常见 Flash 写粒度:
  nor flash:  1 bit
  stm32f2/f4: 8 bit
  stm32f1:    32 bit
  stm32l4:    64 bit
 */

//1.定义 flash 设备

const struct fal_flash_dev stm32_onchip_flash =
{
    .name       = "stm32_onchip",
    .addr       = 0x08000000,
    .len        = 512*1024,
    .blk_size   = 2*1024,
    .ops        = {init, read, write, erase},
    .write_gran = 32
};



上面这点代码把len改成自己实际的内存大小,blk_size也就是页大小也改成实际的页大小。
最后需要把fal_cfg.h里面的stm32f2_onchip_flash改成stm32_onchip_flash,然后修改自己想要的table表就行了。在这里插入图片描述

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

k-kun

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值