【ZYNQ】SD 卡读写及文件扫描实验

SD 卡控制器(SD/SDIO Controller)

ZYNQ 中的 SD 卡控制器符合 SD2.0 协议规范,接口兼容 eMMC、MMC3.31、SDIO2.0、SD2.0、SPI,支持 SDHC、SDHS 器件。SD 卡控制器支持 SDMA(单操作 DMA)、ADMA1(4K 边界限制 DMA)和 ADMA2(在 32 位系统中允许任何位置和任意大小)。ARM 处理器通过 AHB 总线访问 SD 卡控制器,SD 控制器采用读和写通道各自双缓冲 FIFO 的机制提高吞吐带宽。

其内部框图如下图所示:

在这里插入图片描述

SD 控制器读写通道采用独立的 512 字节深度的双缓冲 FIFO 执行读和写操作。在写操作时,处理器向其中一个 FIFO 写数据,将另一个 FIFO 的数据写到 SD 总线;在读操作时,SD 总线上的数据向其中一个 FIFO 写数据,处理器将数据从另一个 FIFO 读出数据。SD 卡控制器通过双缓冲机制以保证最大带宽。

FATFS 文件系统

FATFS 是一个完全开源免费的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准 C 语言编写,所以具有良好的硬件平台独立性,可以很方便的移植到各种嵌入式处理器中。Xilinx SDK 的 standalone 已经移植好了 FATFS 文件系统,因此在 SDK 中添加 xilffs 库后,就可以在程序中使用 FATFS 中的 API 函数来操作 SD 卡。

FATFS 的特点如下:

  • 1、 结构清晰,代码量少,文件系统和 IO 底层分开,特别适合新手入门学习;
  • 2、 支持最多 10 个逻辑盘符和两级文件夹;
  • 3、 支持 FAT12/FAT16 和 FAT32 文件系统;
  • 4、 支持长文件名称。

FATFS 的这些特点,加上开源、免费的原则,使得 FATFS 的应用非常广泛。FATFS 模块的层次结构分为顶层、中间层 FATFS 模块和底层接口。

最顶层是应用层,使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用 FATFS 模块提供给用户的一系列应用接口函数,如 f_open,f_read,f_write 和 f_close 等,就可以像在 PC 上读/写文件那样简单。

中间层 FATFS 模块,实现了 FAT 文件读/写协议。FATFS 模块提供的是 ff.c 和 ff.h。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。

FATFS 模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。

读写实验

  • 实验平台:黑金 Zynq7035
  • 开发环境:Vivado 2017.4

硬件设计

参考原理图可知,SD 卡接在了 PS_MIO40~45:

在这里插入图片描述

在这里插入图片描述

ZYNQ PS 做如下配置,配置 Bank 1 为 LVCMOS 1.8V,打开 UART0 和 SD0:

在这里插入图片描述

完善其他配置后生成比特流,导出硬件信息。

软件设计

创建 SDK 工程,在 BSP 设置中选中 xilffsxilffs 即为 FATFS 库,保存配置:

在这里插入图片描述

添加如下代码:

#include "xparameters.h"
#include "ff.h"
#include "xdevcfg.h"
#include "xil_printf.h"
#include "stdio.h"#define kprintf xil_printf#define SD_FS   "0:/"
#define SD_FILE "0:SD_TEST.txt"static FATFS sd_fatfs;static FRESULT fatfs_init(FATFS *fatfs, TCHAR *path)
{FRESULT res;res = f_mount(fatfs, path, 1);if(res != FR_OK){res = f_mkfs(path, 0, 0);if (res != FR_OK){kprintf("ERROR: Unable to format FATfs.\r\n");return res;}res = f_mount(fatfs, path, 1);if(res != FR_OK){kprintf("ERROR: f_mount returned %d.\r\n", res);return res;}}return res;
}static FRESULT sd_read_data(char *FileName, uint32_t DestinationAddress, uint32_t ByteLength)
{FIL fil;FRESULT res;UINT br;res = f_open(&fil, FileName, FA_READ);if(res){kprintf("ERROR: %s f_open returned %d\r\n", FileName, res);return res;}res = f_lseek(&fil, 0);if(res){kprintf("ERROR: %s f_lseek returned %d\r\n", FileName, res);return res;}res = f_read(&fil, (void*)DestinationAddress, ByteLength, &br);if(res){kprintf("ERROR: %s f_read returned %d\r\n", FileName, res);return res;}res = f_close(&fil);if(res){kprintf("ERROR: %s f_close returned %d\r\n", FileName, res);return res;}return res;
}static FRESULT sd_write_data(char *FileName, uint32_t SourceAddress, uint32_t ByteLength)
{FIL fil;FRESULT res;UINT bw;res = f_open(&fil, FileName, FA_CREATE_ALWAYS | FA_WRITE);if(res){kprintf("ERROR: %s f_open returned %d.\r\n", FileName, res);return res;}res = f_lseek(&fil, 0);if(res){kprintf("ERROR: %s f_lseek returned %d.\r\n", FileName, res);return res;}res = f_write(&fil, (void*) SourceAddress, ByteLength, &bw);if(res){kprintf("ERROR: %s f_write returned %d.\r\n", FileName, res);return res;}res = f_close(&fil);if(res){kprintf("ERROR: %s f_close returned %d.\r\n", FileName, res);return res;}return res;
}static FRESULT sd_rw_test(void)
{FRESULT res;const char src_str[] = "ZYNQ test SD card write and read!";char dest_str[33];uint32_t len = strlen(src_str);res = sd_write_data(SD_FILE, (uint32_t)src_str, len);if(XST_SUCCESS != res){kprintf("ERROR: fail to write SD Card.\r\n");return res;}else{kprintf("Success to write SD Card.\r\n");}res = sd_read_data(SD_FILE, (uint32_t)dest_str, len);if(XST_SUCCESS != res){kprintf("ERROR: fail to read SD Card.\r\n");return res;}else{kprintf("Success to read SD Card; data: %s \r\n", dest_str);}kprintf("SD Card Write and Read test end.\r\n");return res;}static FRESULT scan_files(char *path)
{FRESULT res;DIR dir;UINT i;static FILINFO fno;res = f_opendir(&dir, path);char pathBuff[256];if(res == FR_OK){for( ; ; ){res = f_readdir(&dir, &fno);if(res != FR_OK || fno.fname[0] == 0){break;}if(fno.fattrib & AM_DIR){i = strlen(path);sprintf(&path[i], "/%s", fno.fname);kprintf("%s \r\n", path);res = scan_files(path);if(res != FR_OK){break;}path[i] = 0;}else{kprintf("%s/%s \r\n", path, fno.fname);strcpy(pathBuff, fno.fname);}}}else{kprintf("Failed - %s", &res);}f_closedir(&dir);return res;
}int main(void)
{kprintf("hello world. \r\n");FRESULT res;res = fatfs_init(&sd_fatfs, SD_FS);if(XST_SUCCESS != res){kprintf("ERROR: fail to open SD Card.\r\n");}else{kprintf("Success to open SD Card.\r\n");}sd_rw_test();scan_files(SD_FS);while(1){}return 0;
}

实验现象

  • 终端输出:

在这里插入图片描述

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

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

相关文章

数据结构-顺序表

文章目录 线性表概念顺序表静态顺序表动态顺序表 总结 线性表概念 线性表是最基本、最简单、也是最常用的一种数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…线性表(linear> list)是数据结构的一种,一个线性表是n个具…

2024年福建省职业院校技能大赛高职组“软件测试”赛项样题

2024年福建省职业院校技能大赛 高职组“软件测试”赛项样题 任务一:功能测试(45分) 1、测试计划(5分) (1)任务描述 针对功能测试任务,划分和界定测试范围,分解测试任…

蚂蚁庄园小课堂答题今日答案最新

蚂蚁庄园小课堂答题今日答案最新 温馨提醒:由于本文章会停留在一个固定的更新时间上,包含当前日期最新的支付宝蚂蚁庄园小课堂答题今日答案。如果您看到这篇文章已成为过去时,请按下面的方法进入查看天天保持更新的最新今日答案; …

Linux 网络通信

(一)套接字Socket概念 Socket 中文意思是“插座”,在 Linux 环境下,用于表示进程 x 间网络通信的特殊文件 类型。本质为内核借助缓冲区形成的伪文件。 既然是文件,那么理所当然的,我们可以使用文件描述符引用套接字。Linux 系统…

Windows11安装后跳过联网登录

Windows11安装后跳过联网登录 实验设备: VMware17Pro虚拟机中使用Windows11镜像安装Windows11操作系统,并且在虚拟机中测试跳过联网登录。 步骤 说明:物理卸载网卡(在虚拟机上禁用网卡)没用 思路: sh…

8.统一异常处理 + 统一记录日志

目录 1.统一异常处理 2.统一记录日志 1.统一异常处理 在 HomeController 类中添加请求方法(服务器发生异常之后需要统一处理异常,记录日志,然后转到 500 页面,需要人工处理重定向到 500 页面,提前把 500 页面请求访问…

经典神经网络——AlexNet模型论文详解及代码复现

一、背景 AlexNet是在2012年由Alex Krizhevsky等人提出的,该网络在2012年的ImageNet大赛上夺得了冠军,并且错误率比第二名高了很多。Alexnet共有8层结构,前5层为卷积层,后三层为全连接层。 论文地址:ImageNet Classif…

ModuleNotFoundError: No module named ‘mdtex2html‘ module已经安装还是报错,怎么办?

用streamlit运行ChatGLM/basic_model/web_demo.py的时候,出现了module not found: ModuleNotFoundError: No module named mdtex2html Traceback: File "/home/haiyue/.local/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script…

【阿里云】图像识别 智能分类识别 增加网络控制功能点(三)

一、增加网络控制功能 实现需求TCP 心跳机制解决Soket异常断开问题 二、Linux内核提供了通过sysctl命令查看和配置TCP KeepAlive参数的方法。 查看当前系统的TCP KeepAlive参数修改TCP KeepAlive参数 三、C语言实现TCP KeepAlive功能 四、setsockopt用于设置套接字选项的系…

leetcode做题笔记907. 子数组的最小值之和

给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。 由于答案可能很大,因此 返回答案模 10^9 7 。 示例 1: 输入:arr [3,1,2,4] 输出:17 解释&…

Qt4利用MVC开发曲线数据编辑器

目录 1 需求 2 开发流程 1 搭建框架 2 构造函数 3 打开工程 4 实现应用程序参数加载 5 QCustomPlot和TableView的联动 6 数据的可视化修改 7 列表点击事件事先键盘控制 8 表格实现复制,粘贴,删除等一系列功能 9 曲线实现自适应范围和统一范围…

【JMeter】运行方式

第一种: 使用GUI 操作: 在JMeter界面菜单导航上点击运行按钮 一般用作创建TestPlan和调试脚本增加java堆空间来满足测试环境 第二种:使用CLI(Command Line) 性能测试一般请求量比较大,为了节省资源 CLI参数用法: 字段…

零代码,无限可能:打造无服务器应用程序的成功秘诀!

在应用程序构建时,代码作为一组打包成应用程序的计算机指令,仅在有计算机(服务器)与之交互时才会发挥作用。对于无服务器化的应用程序,它并不是看似无需任何硬件即可运行的应用程序。无服务器是一种基于功能的架构&…

C语言-方阵循环右移

本题要求编写程序,将给定nn方阵中的每个元素循环向右移m个位置,即将第0、1、⋯、n−1列变换为第n−m、n−m1、⋯、n−1、0、1、⋯、n−m−1列。 输入格式: 输入第一行给出两个正整数m和n(1≤n≤6)。接下来一共n行&am…

Flask Echarts 实现历史图形查询

Flask前后端数据动态交互涉及用户界面与服务器之间的灵活数据传递。用户界面使用ECharts图形库实时渲染数据。它提供了丰富多彩、交互性强的图表和地图,能够在网页上直观、生动地展示数据。ECharts支持各种常见的图表类型,包括折线图、柱状图、饼图、散点…

[Spring] 字节一面~Spring 如何解决循环依赖问题 以及 @resource 与 @autowire 同时存在时谁生效

文章目录 Spring 如何解决循环依赖问题resource 与 autowire 同时存在时谁生效 Spring 如何解决循环依赖问题 Spring在实例化一个bean的时候,是首先递归实例化其所依赖的所有bean,直到某个bean没有依赖其他bean,此时就会将该实例返回&#x…

UniWebView的更新日志【### 5.3.0 (28 Jan, 2023)】

UniWebView的更新日志 # Release Note ### 5.3.0 (28 Jan, 2023) #### Add * Support for customization of Kotlin and Android Browser package versions. This can help to resolve the conflict with other plugins which use another version of these packages. ###…

【JavaWeb】Servlet

Servlet 文章目录 Servlet一、简介二、开发流程三、生命周期四、ServletConfig和ServletContext五、HttpServletRequest常见API六、HttpServletResponse常见API七、请求转发和响应重定向7.1 概述7.2 请求转发7.3 响应重定向 八、请求与响应乱码问题8.1 GET与POST请求乱码8.2 响…

内网穿透的应用-Jupyter Notbook+cpolar内网穿透实现公共互联网访问使用数据分析工作

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中,使用最多的无疑就是各种函数、图表、…

Vue 或者 React 中,什么情况下会用 Es6 的 Class 类

// 问个问题,一般在 Vue 或者 React中 // 在框架具备很多组件通讯技术或者js语法支持的情况下,什么情况下会用 Es6 的 Class类?在Vue或React中,通常会在以下情况下使用ES6的Class类: 复杂组件或模块: 当需要构建较为复…