rtthread stm32h743的使用(十二)spi设备fal驱动的使用

我们要在rtthread studio 开发环境中建立stm32h743xih6芯片的工程。我们使用一块stm32h743及fpga的核心板完成相关实验,核心板如图:
在这里插入图片描述
在这里插入图片描述
fal驱动的使用是建立在sfud驱动之上的,所以我们在上一节使用的工程基础上继续实验。
在这里插入图片描述1.在上一节工程的基础上,我们添加fal驱动:
在这里插入图片描述
在这里插入图片描述
2.打开工程目录,将samples文件夹下的fal cfg.h复制到inc文件夹下,如图:
在这里插入图片描述
3.在drive文件夹下添加drv_flash_h7.c文件如图:
在这里插入图片描述
代码如下:

#include <rtconfig.h>
#include <rtdef.h>
#include <board.h>#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_config.h"
#include "drv_flash.h"#if defined(RT_USING_FAL)
#include "fal.h"
#endif//#define DRV_DEBUG
#define LOG_TAG                "drv.flash"
#include <drv_log.h>/*** Read data from flash.* @note This operation's units is word.** @param addr flash address* @param buf buffer to store read data* @param size read bytes size** @retval The length of bytes that have been read*/
int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
{size_t i;if ((addr + size - 1) > FLASH_END){LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));return -RT_ERROR;}for (i = 0; i < size; i++, buf++, addr++){*buf = *(rt_uint8_t *) addr;}return size;
}/*** Write data to flash.* @note This operation's units is word.* @note This operation must after erase. @see flash_erase.** @param addr flash address* @param buf the write data buffer* @param size write bytes size** @return The length of bytes that have been written*/
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{rt_err_t result      = RT_EOK;rt_uint32_t end_addr = addr + size - 1, write_addr;rt_uint32_t write_granularity = FLASH_NB_32BITWORD_IN_FLASHWORD * 4;rt_uint32_t write_size = write_granularity;rt_uint8_t write_buffer[32] = {0};if ((end_addr) > FLASH_END){LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));return -RT_EINVAL;}if(addr % 32 != 0){LOG_E("write addr must be 32-byte alignment");return -RT_EINVAL;}if (size < 1){return -RT_EINVAL;}HAL_FLASH_Unlock();write_addr = (uint32_t)buf;__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR);while (addr < end_addr){if(end_addr - addr + 1 < write_granularity){write_size = end_addr - addr + 1;for(size_t i = 0; i < write_size; i++){write_buffer[i] = *((uint8_t *)(write_addr + i));}write_addr = (uint32_t)((rt_uint32_t *)write_buffer);}if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, write_addr) == HAL_OK){for(rt_uint8_t i = 0; i < write_size; i++){if (*(rt_uint8_t *)(addr + i) != *(rt_uint8_t *)(write_addr + i)){result = -RT_ERROR;goto __exit;}}addr += write_granularity;write_addr  += write_granularity;}else{result = -RT_ERROR;goto __exit;}}__exit:HAL_FLASH_Lock();if (result != RT_EOK){return result;}return size;
}/*** Erase data on flash.* @note This operation is irreversible.* @note This operation's units is different which on many chips.** @param addr flash address* @param size erase bytes size** @return result*/
int stm32_flash_erase(rt_uint32_t addr, size_t size)
{rt_err_t result = RT_EOK;rt_uint32_t SECTORError = 0;if ((addr + size - 1) > FLASH_END){LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));return -RT_EINVAL;}rt_uint32_t addr_bank1 = 0;rt_uint32_t size_bank1 = 0;
#ifdef FLASH_BANK_2rt_uint32_t addr_bank2 = 0;rt_uint32_t size_bank2 = 0;
#endifif((addr + size) < FLASH_BANK2_BASE){addr_bank1 = addr;size_bank1 = size;
#ifdef FLASH_BANK_2size_bank2 = 0;
#endif}else if(addr >= FLASH_BANK2_BASE){size_bank1 = 0;
#ifdef FLASH_BANK_2addr_bank2 = addr;size_bank2 = size;
#endif}else{addr_bank1 = addr;size_bank1 = FLASH_BANK2_BASE - addr_bank1;
#ifdef FLASH_BANK_2addr_bank2 = FLASH_BANK2_BASE;size_bank2 = addr + size - FLASH_BANK2_BASE;
#endif}/*Variable used for Erase procedure*/FLASH_EraseInitTypeDef EraseInitStruct;/* Unlock the Flash to enable the flash control register access */HAL_FLASH_Unlock();EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;EraseInitStruct.VoltageRange  = FLASH_VOLTAGE_RANGE_3;SCB_DisableDCache();if(size_bank1){EraseInitStruct.Sector    = (addr_bank1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE;EraseInitStruct.NbSectors = (addr_bank1 + size_bank1 -1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1;EraseInitStruct.Banks = FLASH_BANK_1;if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK){result = -RT_ERROR;goto __exit;}}#ifdef FLASH_BANK_2if(size_bank2){EraseInitStruct.Sector    = (addr_bank2 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE;EraseInitStruct.NbSectors = (addr_bank2 + size_bank2 -1 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1;EraseInitStruct.Banks = FLASH_BANK_2;if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK){result = -RT_ERROR;goto __exit;}}
#endif__exit:SCB_EnableDCache();HAL_FLASH_Lock();if (result != RT_EOK){return result;}LOG_D("erase done: addr (0x%p), size %d", (void *)addr, size);return size;
}#if defined(RT_USING_FAL)
static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase_128k(long offset, size_t size);
const struct fal_flash_dev stm32_onchip_flash_128k = { "onchip_flash_128k", STM32_FLASH_START_ADRESS, FLASH_SIZE_GRANULARITY_128K, (128 * 1024), {NULL, fal_flash_read_128k, fal_flash_write_128k, fal_flash_erase_128k} };static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size)
{return stm32_flash_read(stm32_onchip_flash_128k.addr + offset, buf, size);
}
static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size)
{return stm32_flash_write(stm32_onchip_flash_128k.addr + offset, buf, size);
}static int fal_flash_erase_128k(long offset, size_t size)
{return stm32_flash_erase(stm32_onchip_flash_128k.addr + offset, size);
}#endif
#endif /* BSP_USING_ON_CHIP_FLASH */

4.在在board.h文件打开BSP_USING_ON_CHIP_FLASH如图:
在这里插入图片描述
5.对fal_cfg.h做更改,使其和h7芯片对应,如图:
在这里插入图片描述
6.这时候编译已经没有错误了,我们下载测试下:
在这里插入图片描述
可以看到,[I/SFUD] Probe SPI flash norflash0 by SPI device spi10 success.RT-Thread Flash Abstraction Layer initialize success.说明sfud和fal都init成功,并且打印了分区表。
7.测试几个fal指令,都没有问题:
在这里插入图片描述
8.我们测试下性能,性能将会测试 Flash的擦除、写入及读取速度,同时将会测试写入及读取数据的准确性,保证整个 Flash 或整个分区的 写入与读取 数据的一致性。
指令为fal bench 4096 yes
在这里插入图片描述
其余指令可以参考:

msh />fal
Usage:
fal probe [dev_name|part_name]   - probe flash device or partition by given name
fal read addr size               - read 'size' bytes starting at 'addr'
fal write addr data1 ... dataN   - write some bytes 'data' starting at 'addr'
fal erase addr size              - erase 'size' bytes starting at 'addr'
fal bench <blk_size>             - benchmark test with per block size

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/37082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud Alibaba Seata2.0基础入门与安装

官网地址&#xff1a;https://seata.apache.org/zh-cn/ GitHub下载地址&#xff1a;https://github.com/apache/incubator-seata/releases 本文这里下载的是seata2.0.0版本。 【1】概述 ① Seata是什么 Simple Extensible Autonomous Transaction Architecture&#xff0c…

vue3 全局引入 onMounted, reactive, ref 的插件全局引入

webpack 的引入 npm install -D unplugin-auto-import const AutoImport require(unplugin-auto-import/webpack).default;configureWebpack: {devtool: source-map,module: {rules: [{test: /\.mjs$/,include: /node_modules/,type: javascript/auto}],}, plugins: [Aut…

Java对象创建过程

在日常开发中&#xff0c;我们常常需要创建对象&#xff0c;那么通过new关键字创建对象的执行中涉及到哪些流程呢&#xff1f;本文主要围绕这个问题来展开。 类的加载 创建对象时我们常常使用new关键字。如下 ObjectA o new ObjectA();对虚拟机来讲首先需要判断ObjectA类的…

# Sharding-JDBC从入门到精通(4)- Sharding-JDBC 入门程序几种配置方式

Sharding-JDBC从入门到精通&#xff08;4&#xff09;- Sharding-JDBC 入门程序几种配置方式 一、Sharding-JDBC 入门程序&#xff08;水平分表&#xff09;-使用 application.yml 配置文件的 方式 1、打开 idea 创建 artifactId 名为 dbsharding 的 maven 父工程。 --> i…

python sklearn机械学习模型-回归

&#x1f308;所属专栏&#xff1a;【机械学习】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您…

redis实战-添加商户缓存

为什么要使用缓存 言简意赅&#xff1a;速度快&#xff0c;好用缓存数据存储于代码中&#xff0c;而代码运行在内存中&#xff0c;内存的读写性能远高于磁盘&#xff0c;缓存可以大大降低用户访问并发量带来的服务器读写压力实际开发中&#xff0c;企业的数据量&#xff0c;少…

找不到mfc100.dll文件怎么办?推荐这7个解决方法快速解决mfc100.dll丢失问题

使用电脑中&#xff0c;会遇到各种各样的问题&#xff0c;比如找不到mfc100.dll&#xff0c;或mfc100.dll丢失导致软件程序无法继续运行&#xff0c;就是日常中比较常见的问题之一&#xff0c;今天我教大家遇到这个mfc100.dll丢失问题时候&#xff0c;要怎么解决&#xff0c;以…

【List集合排序】

List集合排序Demo import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor;import java.util.*;/*** list order demo*/ public class ListOrderDemo {public static void main(String[] args) {List<String> lis…

Linux基础篇——学习Linux基本工具安装教程视频链接

本篇文章就是记录一下学习Linux需要用到的基本工具的视频教程链接&#xff0c;方便以后查看 VMware15.5安装 安装视频教程&#xff1a;VMware15.5安装教程 centos7.6安装&#xff08;这个视频教程真的很nice&#xff09; 视频教程&#xff1a;centos7.6 虚拟机克隆、快照、…

学习平台推荐_菜鸟教程官网

网址&#xff1a; 菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01;菜鸟教程(www.runoob.com)提供了编程的基础技术教程, 介绍了HTML、CSS、Javascript、Python&#xff0c;Java&#xff0c;Ruby&#xff0c;C&#xff0c;PHP , MySQL等各种编程语言的基础知识。 同…

Nginx-2

一、高级配置 1.1网页状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状…

Open3D (C++) 点云边界提取

边界提取 一、算法原理1、详细流程2、主要函数3、参考文献二、代码实现三、结果展示四、注意事项本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、详细流程 该算法完全复刻自PCL。 2、主要函数 /// \…

算法入门(上)

什么是算法&#xff1f; 算法&#xff08;Algorithm&#xff09;是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 给定一个问题&#xff0c;能够解决这个问题的算法是有很多种的。算式中的问题是千奇百怪…

Debian/Ubuntu Linux安装OBS

先决条件 建议使用 xserver-xorg 1.18.4 或更新版本&#xff0c;以避免 OBS 中某些功能&#xff08;例如全屏投影仪&#xff09;出现潜在的性能问题。在 Linux 上使用 OBS Studio 需要 OpenGL 3.3&#xff08;或更高版本&#xff09;支持。在终端中输入以下内容来检查系统支持…

GMSB文章八:微生物中介分析

欢迎大家关注全网生信学习者系列&#xff1a; WX公zhong号&#xff1a;生信学习者Xiao hong书&#xff1a;生信学习者知hu&#xff1a;生信学习者CDSN&#xff1a;生信学习者2 介绍 中介分析&#xff08;Mediation Analysis&#xff09;是一种统计方法&#xff0c;用于研究一…

C# Benchmark

创建控制台项目&#xff08;或修改现有项目的Main方法代码&#xff09;&#xff0c;Nget导入Benchmark0.13.12&#xff0c;创建测试类&#xff1a; public class StringBenchMark{int[] numbers;public StringBenchMark() {numbers Enumerable.Range(1, 20000).ToArray();}[Be…

大语言模型(LLMs)全面学习指南,初学者入门,一看就懂!

大语言模型&#xff08;LLMs&#xff09;作为人工智能&#xff08;AI&#xff09;领域的一项突破性发展&#xff0c;已经改变了自然语言处理&#xff08;NLP&#xff09;和机器学习&#xff08;ML&#xff09;应用的面貌。这些模型&#xff0c;包括OpenAI的GPT-4o和Google的gem…

杨幂跨界学术圈:内容营销专家刘鑫炜带你了解核心期刊的学术奥秘

近日&#xff0c;知名艺人杨幂在权威期刊《中国广播电视学刊》上发表了一篇名为《浅谈影视剧中演员创作习惯——以电视剧<哈尔滨一九四四>为例》的学术论文&#xff0c;此举在学术界和娱乐圈均引起了广泛关注。该期刊不仅享有极高的声誉&#xff0c;还同时被北大中文核心…

数据库-数据完整性-用户自定义完整性实验

NULL/NOT NULL 约束&#xff1a; 在每个字段后面可以加上 NULL 修饰符来指定该字段是否可以为空&#xff1b;或者加上 NOT NULL 修饰符来指定该字段必须填上数据。 DEFAULT约束说明 DEFAULT 约束用于向列中插入默认值。如果列中没有规定其他的值&#xff0c;那么会将默认值添加…

发;flask的基本使用2

上一篇我们介绍了基本使用方法 flask使用 【 1 】基本使用 from flask import Flask# 1 实例化得到对象 app Flask(__name__)# 2 注册路由--》写视图函数 app.route(/) def index():# 3 返回给前端字符串return hello worldif __name__ __main__:# 运行app&#xff0c;默认…