六、在zephyr上配置sdmmc和fatfs演示

发布时间:2026/7/10 1:10:46

六、在zephyr上配置sdmmc和fatfs演示
1、配置sdmmc使得系统能检测到sd卡并测试sd的性能1配置prj.conf #开启 Zephyr SD 卡子系统与 SDHC 驱动 CONFIG_SDHCy CONFIG_DISK_ACCESSy 开启文件系统支持以 FatFs 为例 CONFIG_FILE_SYSTEMy CONFIG_FAT_FILESYSTEM_ELMy CONFIG_LOG_MODE_IMMEDIATEy 配置app.overlay文件。dmamux1{statusokay;};dma1{statusokay;};sdmmc1{statusokay;compatiblest,stm32-sdmmc;pinctrl-0sdmmc1_ck_pc12sdmmc1_cmd_pd2sdmmc1_d0_pc8sdmmc1_d1_pc9sdmmc1_d2_pc10sdmmc1_d3_pc11;pinctrl-namesdefault;bus-width4;disk-nameSD;};配置 sd卡的时钟过高可能导致sd检测不到设置到合理的范围。如 div-q 10; 配置一下符合48mhz倍数。当前是配置完为48mhz主要线程调用。#includezephyr/storage/disk_access.h#includezephyr/linker/linker-defs.h#includeinttypes.h#includezephyr/linker/linker-defs.h#includezephyr/fs/fs.h#includezephyr/arch/cpu.h#defineTEST_BLOCK_SIZE512/* 标准扇区大小 */#defineTEST_BLOCK_COUNT100/* 每次连续读写的扇区数 (100 * 512 50KB) */#defineTEST_ITERATIONS20/* 循环测试次数 */#defineTOTAL_DATA_SIZE(TEST_BLOCK_SIZE*TEST_BLOCK_COUNT)/* 定义 512 字节的扇区缓冲区并确保 32 字节对齐 */staticuint8_t__aligned(32)test_write_buf[TOTAL_DATA_SIZE]__attribute__((section(.nocache.sd_nocache_mem)));staticuint8_t__aligned(32)test_read_buf[TOTAL_DATA_SIZE]__attribute__((section(.nocache.sd_nocache_mem)));#defineMAX_RETRIES3intsd_write_with_retry(constchar*pdrv,constuint8_t*buf,uint32_tsector,uint32_tcount){intret;for(inti0;iMAX_RETRIES;i){retdisk_access_write(pdrv,buf,sector,count);if(ret0)return0;// 成功则直接返回LOG_WRN(Write failed (attempt %d), retrying...,i1);k_msleep(10);// 等待 10ms 后重试}returnret;// 重试耗尽返回错误}intsd_read_with_retry(constchar*pdrv,uint8_t*buf,uint32_tsector,uint32_tcount){intret;for(inti0;iMAX_RETRIES;i){retdisk_access_read(pdrv,buf,sector,count);if(ret0)return0;LOG_WRN(Read failed (attempt %d), retrying...,i1);k_msleep(10);}returnret;}voidthread_entry4(void*p1,void*p2,void*p3){intret;uint32_tstart_sector1000;/* 避开 0 扇区MBR/引导区从安全区域开始 */uint32_tstart_time,end_time;uint64_ttotal_write_ms0,total_read_ms0;uint32_tsector_count;uint32_tsector_size;retdisk_access_init(SD);if(ret!0){printk(SD card init failed: %d \n,ret);}printk(SD card initialized successfully!\n);/* 2. 获取 SD 卡容量信息 */retdisk_access_ioctl(SD,DISK_IOCTL_GET_SECTOR_COUNT,sector_count);if(ret!0){printk(Failed to get sector count);}retdisk_access_ioctl(SD,DISK_IOCTL_GET_SECTOR_SIZE,sector_size);if(ret!0){printk(Failed to get sector size);}printk(SD Card Info: %u sectors, %u bytes/sector\n,sector_count,sector_size);printk(Total Capacity: %u MB\n,(sector_count*sector_size)/(1024*1024));/* 填充测试数据 */memset(test_write_buf,0xA5,sizeof(test_write_buf));for(inti0;iTEST_ITERATIONS;i){/* 1. 写入性能测试 *//* 【关键】写入前将 D-Cache 中的数据刷入 AXI SRAM确保 DMA 读到最新数据 */SCB_CleanDCache_by_Addr((uint32_t*)test_write_buf,TOTAL_DATA_SIZE);start_timek_uptime_get();retsd_write_with_retry(SD,test_write_buf,start_sector,TEST_BLOCK_COUNT);end_timek_uptime_get();if(ret!0){printk(Write failed at iteration %d, err: %d,i,ret);//return;}total_write_ms(end_time-start_time);SCB_InvalidateDCache_by_Addr((uint32_t*)test_read_buf,TOTAL_DATA_SIZE);/* 2. 读取性能测试 */start_timek_uptime_get();retsd_read_with_retry(SD,test_read_buf,start_sector,TEST_BLOCK_COUNT);end_timek_uptime_get();if(ret!0){printk(Read failed at iteration %d, err: %d,i,ret);// return;}SCB_InvalidateDCache_by_Addr((uint32_t*)test_read_buf,TOTAL_DATA_SIZE);total_read_ms(end_time-start_time);}/* 3. 数据完整性校验 */if(memcmp(test_write_buf,test_read_buf,TOTAL_DATA_SIZE)!0){printk(Data mismatch! Read/Write data is inconsistent.);//return;}/* 4. 计算并打印吞吐量 (MB/s) */floatwrite_speed((float)(TOTAL_DATA_SIZE*TEST_ITERATIONS)/(1024.0f*1024.0f))/((float)total_write_ms/1000.0f);floatread_speed((float)(TOTAL_DATA_SIZE*TEST_ITERATIONS)/(1024.0f*1024.0f))/((float)total_read_ms/1000.0f);uint32_twrite_speed_int(uint32_t)(write_speed*100);uint32_tread_speed_int(uint32_t)(read_speed*100);printk( Test Completed Successfully );printk(Avg Write Speed: %u.%02u MB/s (Total: %PRIu64 ms),write_speed_int/100,write_speed_int%100,total_write_ms);printk(Avg Read Speed: %u.%02u MB/s (Total: %PRIu64 ms),read_speed_int/100,read_speed_int%100,total_read_ms);while(1){k_sleep(K_FOREVER);}}演示结果2、在sdmmc基础上加上配置 fatfs系统# 开启 Zephyr SD 卡子系统与 SDHC 驱动 CONFIG_SDHCy CONFIG_DISK_ACCESSy CONFIG_DISK_DRIVER_SDMMCy CONFIG_SDMMC_STM32y # 开启文件系统支持以 FatFs 为例 CONFIG_FILE_SYSTEMy CONFIG_FAT_FILESYSTEM_ELMy CONFIG_LOG_MODE_IMMEDIATEy CONFIG_HEAP_MEM_POOL_SIZE8192CONFIG_MAIN_STACK_SIZE16384CONFIG_DMAy # 显式启用 DMA 支持 CONFIG_DMA_STM32y CONFIG_NOCACHE_MEMORYy # 保持 DMA 缓冲区一致性代码#includestm32h7xx_hal.h#includestring.h#includestdbool.h#includezephyr/drivers/dma.h#includezephyr/cache.h#includezephyr/devicetree.h#includezephyr/storage/disk_access.h#includezephyr/linker/linker-defs.h#includeinttypes.h#includezephyr/arch/cpu.h#includezephyr/fs/fs.h#includeff.h#defineTEST_FILE_PATH/SD:/test.txtstaticFATFS fatfs_fs;staticstructfs_mount_tfat_fs_mnt{.typeFS_FATFS,.fs_datafatfs_fs,.mnt_point/SD:,};staticintlsdir(constchar*path){intres;structfs_dir_tdirp;structfs_dirententry;fs_dir_t_init(dirp);resfs_opendir(dirp,path);if(res){LOG_ERR(Error opening dir %s [%d],path,res);returnres;}LOG_INF(Listing dir %s ...,path);for(;;){resfs_readdir(dirp,entry);if(res||entry.name[0]0){break;}if(entry.typeFS_DIR_ENTRY_DIR){LOG_INF([DIR ] %s,entry.name);}else{LOG_INF([FILE] %s (size %zu),entry.name,entry.size);}}fs_closedir(dirp);returnres;}/** * brief 创建文件并写入内容 */staticintcreate_and_write_file(constchar*path,constchar*data,size_tlen){structfs_file_tfile;intres;fs_file_t_init(file);/* 以 写 模式打开文件如果文件不存在则创建存在则清空 */resfs_open(file,path,FS_O_CREATE|FS_O_WRITE);if(res){LOG_ERR(Failed to open file for writing [%d],res);returnres;}/* 将数据写入文件 */resfs_write(file,data,len);if(res0){LOG_ERR(Failed to write to file [%d],res);gotocleanup;}LOG_INF(Successfully wrote %d bytes to %s,res,path);cleanup:/* 关闭文件 */fs_close(file);returnres;}/** * brief 读取文件内容 */staticintread_file_content(constchar*path,char*buf,size_tbuf_size){structfs_file_tfile;intres;ssize_tbytes_read;fs_file_t_init(file);/* 以 读 模式打开文件 */resfs_open(file,path,FS_O_READ);if(res){LOG_ERR(Failed to open file for reading [%d],res);returnres;}/* 读取文件内容到缓冲区 */bytes_readfs_read(file,buf,buf_size);if(bytes_read0){LOG_ERR(Failed to read from file [%d],bytes_read);resbytes_read;gotocleanup;}/* 确保字符串以 \0 结尾方便打印 */buf[bytes_read]\0;LOG_INF(Successfully read %d bytes from %s,bytes_read,path);LOG_INF(File Content: %s,buf);cleanup:/* 关闭文件 */fs_close(file);returnres;}voidled_thread_entry4(void*p1,void*p2,void*p3){intret;printk( SDIO Performance Test Start \n);retdisk_access_init(SD);if(ret!0){printk(Disk init failed: %d\n,ret);}else{printk(Disk initialized successfully.\n);}intresfs_mount(fat_fs_mnt);if(resFR_OK){LOG_INF(SD Card mounted successfully.);lsdir(fat_fs_mnt.mnt_point);}else{LOG_ERR(Error mounting disk: %d,res);}constchar*test_dataHello Zephyr on STM32H723ZG!\nThis is a test file.;charread_buffer[128];create_and_write_file(TEST_FILE_PATH,test_data,strlen(test_data));k_sleep(K_MSEC(5));read_file_content(TEST_FILE_PATH,read_buffer,sizeof(read_buffer));while(1){k_sleep(K_FOREVER);}}结果演示依据

相关新闻

STM32F101ZG上下拉电阻配置与DTH-08信号控制实践

STM32F101ZG上下拉电阻配置与DTH-08信号控制实践

2026/7/10 1:10:46

1. 项目背景与核心需求在嵌入式系统开发中,信号的上拉和下拉状态切换是一个基础但至关重要的操作。我最近在一个工业控制项目中遇到了这样的需求:需要通过STM32F101ZG微控制器精确控制DTH-08模块的信号状态。这个场景让我深刻理解了上下拉电阻选择对系统…

PIC18LF26K40驱动EPT-14A4005P蜂鸣器的低功耗警报方案

PIC18LF26K40驱动EPT-14A4005P蜂鸣器的低功耗警报方案

2026/7/10 1:10:46

1. 项目背景与核心需求解析在工业控制、安防系统和医疗设备等领域,可靠的声音警报系统是保障安全的关键组件。这次我们要探讨的是基于EPT-14A4005P压电蜂鸣器和PIC18LF26K40微控制器的警报解决方案设计。这个组合特别适合需要低功耗、高可靠性且环境适应性强的应用场…

C语言 atoi 函数深度解析:5个关键行为与 strtol 替代方案

C语言 atoi 函数深度解析:5个关键行为与 strtol 替代方案

2026/7/10 1:10:46

C语言 atoi 函数深度解析:5个关键行为与 strtol 替代方案在C语言开发中,字符串与数值的转换是基础但容易出错的环节。许多开发者习惯性地使用atoi函数进行快速转换,却常常忽略其潜在风险。本文将深入剖析atoi函数的5个关键行为特征&#xff0…

白盒测试实战:3个经典C程序(闰年/三角形/中间值)的4种覆盖方法对比

白盒测试实战:3个经典C程序(闰年/三角形/中间值)的4种覆盖方法对比

2026/7/10 2:30:50

白盒测试实战:3个经典C程序的4种覆盖方法深度对比1. 白盒测试核心方法论解析白盒测试作为代码级测试的核心手段,其价值在于通过可视化的代码逻辑分析,系统性地验证程序内部结构的正确性。与黑盒测试不同,白盒测试要求测试者像X光透…

OpenClaw:轻量级本地智能体框架,支持跨平台AI工具编排

OpenClaw:轻量级本地智能体框架,支持跨平台AI工具编排

2026/7/10 2:30:50

1. OpenClaw 是什么?它不是另一个“Claude 模仿者”,而是一套可落地的本地化智能体协作框架 OpenClaw 这个名字最近在开发者圈子里冒得很快,尤其在 Mac 和 Windows 用户搜索“claude code 本地部署”“codex mac intel”“dify 本地部署教程…

AI 辅助 API 文档生成与维护:从代码注释到交互式文档的完整链路

AI 辅助 API 文档生成与维护:从代码注释到交互式文档的完整链路

2026/7/10 2:30:50

AI 辅助 API 文档生成与维护:从代码注释到交互式文档的完整链路 一、API 文档最大的维护成本,不是「写第一版」,而是「让文档和代码保持同步」 API 文档有两种主要的维护模式:「代码优先」(从代码生成文档&#xff0…

【VMware Workstation NAT 网络配置指南】

【VMware Workstation NAT 网络配置指南】

2026/7/10 2:30:50

VMware Workstation NAT 网络配置指南一、三种网络模式对比1. 桥接模式(Bridged)2. NAT 模式(Network Address Translation)3. 仅主机模式(Host-Only)三种模式对比总结二、宿主机配置检查1. 确认 VMnet8 网…

3dsconv:5分钟快速将.3ds游戏文件转换为CIA格式的终极指南

3dsconv:5分钟快速将.3ds游戏文件转换为CIA格式的终极指南

2026/7/10 2:30:50

3dsconv:5分钟快速将.3ds游戏文件转换为CIA格式的终极指南 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 还在…

Apache HttpClient与OkHttpClient深度对比:性能、实战与选型指南

Apache HttpClient与OkHttpClient深度对比:性能、实战与选型指南

2026/7/10 2:20:49

1. 项目概述:一次关于HTTP客户端的深度抉择在Java生态里,但凡涉及到网络通信,尤其是HTTP协议,选择一款趁手的HTTP客户端库几乎是每个开发者都会面临的决策。这不仅仅是选一个工具那么简单,它直接关系到你项目的性能基线…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/9 19:40:56

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/8 14:04:34

1. 项目背景与核心价值在计算机视觉领域,YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备(如树莓派、Jetson Nano或手机终端)时,立刻会遇到两个致命问题:模型体积庞大(原始YO…

终极原神FPS解锁器完整指南:轻松突破60帧限制

终极原神FPS解锁器完整指南:轻松突破60帧限制

2026/7/10 0:00:42

终极原神FPS解锁器完整指南:轻松突破60帧限制 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock 原神FPS解锁器是一款专为《原神》玩家设计的开源工具,通过先进的Wri…

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?[特殊字符]

2026/7/10 0:00:42

YesPlayMusic:如何用高颜值播放器重塑你的网易云音乐体验?🎵 【免费下载链接】YesPlayMusic 高颜值的第三方网易云播放器,支持 Windows / macOS / Linux :electron: 项目地址: https://gitcode.com/gh_mirrors/ye/YesPlayMusic…

从零实现红黑树:手写C++的set与map容器

从零实现红黑树:手写C++的set与map容器

2026/7/10 0:00:42

1. 项目概述:从STL容器到自研轮子在C的日常开发中,std::set和std::map是我们再熟悉不过的伙伴了。它们一个负责管理不重复的集合,一个负责维护键值对映射,底层都依赖一颗高效的红黑树来保证数据的有序性和操作的性能。但你是否曾想…