SPI FLASH Fatfs文件系统移植

news2024/10/5 4:25:39

一.FATFS文件系统简介

FATFS是面向小型嵌入式系统的FAT文件系统。他由C语言编写并且独立与底层I/O介质。支持的内核有:8051,PLC,ARV,ARM等。FATFS支持FAT12,FAT16,FAT32等文件系统格式。
官网链接

二.FATFS源码文件结构

  • diskio.c:包含底层存储介质的操作函数,需要与硬件设备适配移植。主要是在这个文件里调用用户实现的底层驱动函数,如SPI读写falsh的操作函数;
  • diskio.h:为diskio.c文件的函数原型声明和各个宏定义;
  • ff.c:Fatfs核心文件,通过调用diskio.c的底层操作函数实现文件的读写等操作。该文件独立于底层介质操作文件,移植系统时不需要修改。
  • ff.h:相关文件和文件夹的结构体定义。
  • ffconf.h:用于fatfs的功能配置,通过宏实现条件编译,修改相应宏定义的值即可实现功能的裁剪。如,需要支持简体中文,长文件名等。

三.函数调用流程

在这里插入图片描述

四.移植说明

修改diskio.c文件,这个文件里的函数主要有已下几个函数需要实现:

获取当前的驱动的状态:
DSTATUS disk_status(BYTE pdrv )

初始化当前驱动的硬件设备:
DSTATUS disk_initialize(BYTE pdrv)

从当前驱动中读取某块连续的扇区数据:
DRESULT disk_read(
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE buff, / Data buffer to store read data /
LBA_t sector, /
Start sector in LBA /
UINT count /
Number of sectors to read */
)

将数据写入当前驱动的某块扇区:
DRESULT disk_write(
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE buff, / Data to be written /
LBA_t sector, /
Start sector in LBA /
UINT count /
Number of sectors to write */
)

获取当前驱动的一些信息:
DRESULT disk_ioctl(
BYTE pdrv, /* Physical drive nmuber (0…) /
BYTE cmd, /
Control code */
void buff / Buffer to send/receive control data */
)

ff.h相关的几个重要的宏定义

#define _USE_MKFS 1 // 格式化选择
#define _CODE_PAGE 936 // 语言选择
#define _USE_LFN 2 // 长文件名支持
#define _VOLUMES 2 // 物理设备数量
#define _MIN_SS 512 // 指定扇区的最小值
#define _MAX_SS 4096 // 指定扇区的最大值

五.测试demo


FATFS fs;                          
FIL fp;                            
BYTE fatfs_buffer[FF_MAX_SS] = {0}; 
UINT bw;                           

BYTE write_buf[] = "my name is leo"; 
BYTE read_buf[sizeof(write_buf)];
UINT br;

char filename[] = "SPI0:test.txt";

void test(void)
{
    FRESULT res; /* 文件操作结果 */
    res = f_mount(&fs, "SPI0:", 1);
    if (res == FR_NO_FILESYSTEM)
    {
        printf("[%s:%d] not find filesystem \r\n", __func__, __LINE__);
        /* 格式化 */
        res = f_mkfs("SPI0:", 0, fatfs_buffer, sizeof(fatfs_buffer));
        if (res == FR_OK)
        {
            /* 格式化后,先取消挂载 */
            res = f_mount(NULL, "SPI0:", 1);
            /* 重新挂载 */
            res = f_mount(&fs, "SPI0:", 1);
            if (res == FR_OK)
            {
                printf("[%s:%d]format flash ok\r\n", __func__, __LINE__);
            }
        }
        else
        {
            printf("[%s:%d]format falsh filed(%d)\r\n", __func__, __LINE__, res);
            while (1)
                ;
        }
    }
    else if (res != FR_OK)
    {
        printf("[%s:%d] mount flash filesystem failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    else
    {
        printf("[%s:%d] mount flash system ok\r\n", __func__, __LINE__);
    }

    res = f_open(&fp, "SPI0:test.txt", FA_READ | FA_WRITE | FA_CREATE_ALWAYS);
    if (res != FR_OK)
    {
        printf("[%s:%d] open test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    res = f_close(&fp);
    if (res != FR_OK)
    {
        printf("[%s:%d] close test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }

    res = f_open(&fp, "SPI0:test.txt", FA_WRITE | FA_OPEN_EXISTING);
    if (res != FR_OK)
    {
        printf("[%s:%d] open test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    res = f_write(&fp, write_buf, sizeof(write_buf), &bw);
    if (res != FR_OK)
    {
        printf("[%s:%d] write test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    res = f_close(&fp);
    if (res != FR_OK)
    {
        printf("[%s:%d] close test.txt failed(%s)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }

    //	// 读之前需要打开文件:只读权限(文件存在就读取)
    res = f_open(&fp, filename, FA_READ | FA_OPEN_EXISTING);
    if (res != FR_OK)
    {
        printf("[%s:%d] open test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    res = f_read(&fp, read_buf, sizeof(write_buf), &br);
    if (res != FR_OK)
    {
        printf("[%s:%d] read test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
    printf("read_buf = %s\r\n", read_buf);

    res = f_close(&fp);
    if (res != FR_OK)
    {
        printf("[%s:%d] close test.txt failed(%d)\r\n", __func__, __LINE__, res);
        while (1)
            ;
    }
}

移植好的链接

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

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

相关文章

linux搭建hadoop集群

linux搭建hadoop集群 1、创建4台虚拟机2、修改主机名3、配置网络4、配置hosts文件5、分配本地网络给虚拟机6、下载jdk,hadoop压缩包7、用xftp传输到虚拟机8、配置jdk9、配置hadoop10、创建脚本shell脚本,方便同步数据11、配置ssh免密登录12、同步jdk和ha…

希尔贝壳参与构建可信人工智能数据空间,助力大模型行业应用落地

2023年5月30日,由中国信息通信研究院、浙江省经济和信息化厅、杭州市人民政府、中国人工智能产业发展联盟主办的杭州通用人工智能发展论坛在未来科技城圆满落幕。本次会议以“大模型应用机遇和挑战”为主题,众多产学研代表现场参会,共同探讨人…

什么是可以文言文字翻译的呢?

大家有没有在日常生活中需要翻译自己不熟的外语呢?有没有觉得使用翻译软件的时候很轻松呢?你们知道文本翻译这个操作吗?它是一项很实用和创新的技术,可以将一种语言自动翻译转换为另一种语言,当然这些一般都是使用计算…

YOLOv5-7.0添加解耦头

Decoupled Head Decoupled Head是由YOLOX提出的用来替代YOLO Head,可以用来提升目标检测的精度。那么为什么解耦头可以提升检测效果呢? 在阅读YOLOX论文时,找到了两篇引用的论文,并加以阅读。 第一篇文献是Song等人在CVPR2020发表…

根据实体excel导入导出百万数据,可修改表头名称

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 表格导入导出实现效果展示根据实体类导出模板读取表格数据导出数据为excel进阶:修改表格导出的列头 controller示例工具类测试实体实体注解maven依赖 表…

基于SpringBoot+微信小程序的医院预约叫号小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 该项目是基于uniappWe…

加密软件VMProtect教程:使用Windows、Net 、UNIX 秘钥生成器

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic(本机)、Virtual Pascal和XCode编译器。 同时,VMProtect有一个内置的反汇编程序,可以与Windows和Mac OS X可执行文件一起…

VMware虚拟机和主机传输文件

原文链接 虚拟机为Linux系统 使用vm-tools即可。 卸载旧工具: vmware-uninstall-tools.pl安装新工具: apt-get install open-vm-tools-desktop重启系统: reboot此时可以使用CtrlC、CtrlV的方式在主机和Linux虚拟机之间传输文件。 虚拟…

【网络原理】TCP协议如何实现可靠传输(确认应答机制)

🥊作者:一只爱打拳的程序猿,Java领域新星创作者,CSDN、阿里云社区优质创作者。 🤼专栏收录于:计算机网络原理 本篇主要讲解:TCP协议段格式,TCP的序列号,SYN、ACK标志位&a…

操作系统(王道)

1.1_1_操作系统概念 裸机(硬件只听得懂二进制指令)——>操作系统(属于软件,提供良好交互界面)——>应用软件——>用户使用 操作系统是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织…

Python技术自学的方式

Python是一种高级编程语言,被广泛用于软件开发、数据分析、人工智能和科学计算等领域。它于1991年由Guido van Rossum创建,并且其简洁、易读的语法以及丰富的标准库使得它成为了初学者和专业开发人员的首选语言之一。 一、Python技术介绍 学习Python技术…

css响应式布局

这里写自定义目录标题 1.效果展示2.使用grid布局3.使用flex布局 1.效果展示 2.使用grid布局 <!DOCTYPE html> <html><head><meta name"viewport" content"widthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalableno"…

ASEMI代理安森美MOS管FQL40N50参数,FQL40N50描述

编辑-Z FQL40N50参数描述&#xff1a; 型号&#xff1a;FQL40N50 漏源电压VDSS&#xff1a;500V 漏极电流ID&#xff1a;40A 漏极电流-脉冲IDM&#xff1a;160A 栅极-源极电压VGSS&#xff1a;30V 功耗PD&#xff1a;460W 操作和储存温度范围TJ, TSTG&#xff1a;-55 t…

Rust in Action笔记 第六章 内存

Option<T>类型在Rust中使用了空指针优化&#xff08;null pointer optimization&#xff09;来保证该类型在编译后的二进制文件中占用0个字节。None变量是通过一个空指针null pointer来表示&#xff1b;内存地址、指针、引用的区别&#xff0c;内存地址是指在内存中的一个…

SpringBatch从入门到实战(三):多步骤控制

一&#xff1a;if else案例 案例&#xff1a;如果开始步骤成功了就执行成功步骤&#xff0c;否则执行失败步骤。 // 伪代码 String exitStatus helloWorldJob(); if("FAILED".equals(exitStatus)){failStep(); }else{successStep(); }Configuration public class …

01 面向对象方法的概念

面向对象方法的概念 1、什么是面向对象? 面向对象不仅仅是一种程序开发方法 使用面向对象程序设计语言 使用对象、类、继承、封装、消息等基本概念进 行编程 面向对象是一种软件方法学 如何看待软件系统与现实世界的关系 以什么观点进行求解 如何进行系统构造 2、面向对象方…

chatgpt赋能python:Python导入自己写的包详解

Python导入自己写的包详解 在Python中&#xff0c;我们可以将代码封装成包来重复利用&#xff0c;也可以将自己写的包分享给其他人使用。但是&#xff0c;在使用自己写的包时&#xff0c;如何进行导入呢&#xff1f; 什么是包&#xff1f; 在Python中&#xff0c;包是一个有…

计算机网络(更新中)

本文是个人笔记&#xff0c;都是概念&#xff0c;没基础不建议看。 绪论 计算机网络的定义 最简单的定义&#xff1a;计算机网络是一些互相连接的、自治的计算机的集合因特网&#xff08;Internet&#xff09;是“网络的网络” 计算机网络的组成&#xff08;物理组成&#x…

git从http切换到ssh

git从http切换到ssh 之前项目代码git clone的http的git地址&#xff0c;后来禁用了http协议&#xff0c;只能用ssh协议。 1. 生成ssh公钥 进入Git Bash Here, 执行以下命令 ssh-keygen -m PEM -t rsa -b 4096 -C "your.emailemail.com"一直Enter直到完成。 2. 添加…

个人对几个IDE的看法

&#xff08;说明&#xff1a;本文仅表达个人看法&#xff0c;实际上文中的几个IDE功能不同&#xff0c;不能互相取代。截图上的程序均已发布&#xff09; 个人认为一款IDE在功能完整的前提下&#xff0c;应当做到操作简便。另外&#xff0c;对缩放的兼容性也会影响观感。以下…