首页 > 其他分享 >stm32f103使用RT-Thread组件fal读写内部flash

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

时间:2024-04-18 18:01:02浏览次数:18  
标签:stm32f103 RT FLASH HAL addr Thread flash Flash size

本次使用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, <[email protected]>
*
* 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表就行了。
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/bing_xin_/article/details/134789123

标签:stm32f103,RT,FLASH,HAL,addr,Thread,flash,Flash,size
From: https://www.cnblogs.com/liusheldon/p/18144130

相关文章

  • Pyecharts制作动态GDP柱状图
    学习使用pyecharts制作动态柱状图使用csv模块进行csv数据文件处理importcsvfrompyecharts.chartsimportBar,Timelinefrompyecharts.optionsimport*frompyecharts.globalsimportThemeTypedefdealCSVFile():"""读取处理csv数据文件:retu......
  • CF1933D Turtle Tenacity: Continual Mods
    思路:此题其实很简单,不要被邪恶的出题人迷惑了双眼。此题判断有解一共有两种情况。通过题意可以知道将原数组排序后如果\(b_{1}\neb_{2}\),那么最后的结果一定\(\ne0\),这是第一种情况。第二种情况其实就是第一种情况的变形,在排序后\(b_{1}=b_{2}\)的情况下,如果\(b\)......
  • json反序列化 JsonConvert.DeserializeObject 报错 One or more errors occurred. (U
    接口返回的字符串肉眼看起来正常,也是标准json,反序列化时候报错,字符串添加了UTF8-BOM头(windows记事本默认编码),可以通过以下代码移除标头//模拟json字符串对象varjsonStr="{}";byte[]buffer=Encoding.UTF8.GetBytes(jsonStr);varsResult=Encoding.UTF8.GetString......
  • pandas读取sql文件出现:告警UserWarning: pandas only supports SQLAlchemy connectabl
    ​错误原因:导入sql的方式更新了解决方法:importpandasaspdfromsqlalchemyimportcreate_engineMYSQL_HOST='localhost'MYSQL_PORT='3306'MYSQL_USER='root'MYSQL_PASSWORD='123456'MYSQL_DB='cldk_data'engine=......
  • 30天【代码随想录算法训练营34期】第七章 回溯算法part06 (● 332.重新安排行程 ● 51
    332.重新安排行程木有看懂,没视频所以也没看懂51.N皇后自己写出来还是有难度的classSolution:defsolveNQueens(self,n:int)->List[List[str]]:result=[]#存储最终结果的二维字符串数组chessboard=['.'*nfor_inrange(n)]#初始化......
  • https://blog.csdn.net/qq_64314976/article/details/125843147
    importjava.awt.FlowLayout;importjava.awt.GridLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.ButtonGroup;importjavax.swing.JButton;importjavax.swing.JCheckBox;importjavax.swing.JComboBox;importjavax.s......
  • 对大量ip:port进行批量telnet检测的python脚本
    对大量ip:port进行批量telnet检测的python脚本telnet_test.py#导入socket模块,用于网络通信importsocket#定义一个函数,用于测试Telnet连接是否成功deftest_telnet(ip,port):try:#尝试创建到指定IP和端口的连接socket.create_connection((ip,po......
  • quick_sort ——第k个数
    思路:本题就是一个快速排序的模板题,通过对数组中的数字进行从小到大排序,从左到右第k个数,但得注意数组下标是从0开始,所以答案应该是排序后数组下标为k-1如果您还不了解快速排序,请移步这篇文章,https://www.cnblogs.com/expect-999/p/17594345.html#include<iostream>#include......
  • 【构建】start.sh脚本中变量被maven profile构建过程替换
    启动脚本readonlyAPP_NAME="${project.artifactId}"#定义当前应用的名称readonlyJAR_VERSION="${project.version}"#打包的JAR版本EXE_JAR="$APP_NAME-$JAR_VERSION.jar"如何通过maven构建的时候将相应变量内容进行替换呢依赖插件maven-resources-plug......
  • 华为云CodeArts IDE For Python 快速使用指南
    本文分享自华为云社区《华为云CodeArtsIDEForPython快速使用指南》,作者:为云PaaS服务小智。CodeArtsIDE带有Python扩展,为Python语言提供了广泛的支持。Python扩展可以利用CodeArtsIDE的代码补全、验证、调试和单元测试等特性,与多种Python解释器协同工作,轻松切换包......