当前位置: 首页 > news >正文

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

1、配置sdmmc,使得系统能检测到sd卡并测试sd的性能

1)配置prj.conf #开启 Zephyr SD 卡子系统与 SDHC 驱动 CONFIG_SDHC=y CONFIG_DISK_ACCESS=y 开启文件系统支持(以 FatFs 为例) CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_LOG_MODE_IMMEDIATE=y 配置app.overlay文件。&dmamux1{status="okay";};&dma1{status="okay";};&sdmmc1{status="okay";compatible="st,stm32-sdmmc";pinctrl-0=<&sdmmc1_ck_pc12&sdmmc1_cmd_pd2&sdmmc1_d0_pc8&sdmmc1_d1_pc9&sdmmc1_d2_pc10&sdmmc1_d3_pc11>;pinctrl-names="default";bus-width=<4>;disk-name="SD";};

配置 sd卡的时钟过高可能导致sd检测不到,设置到合理的范围。如 div-q = <10>; 配置一下符合48mhz倍数。当前是配置完为48mhz,
主要线程调用。

#include<zephyr/storage/disk_access.h>#include<zephyr/linker/linker-defs.h>#include<inttypes.h>#include<zephyr/linker/linker-defs.h>#include<zephyr/fs/fs.h>#include<zephyr/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(inti=0;i<MAX_RETRIES;i++){ret=disk_access_write(pdrv,buf,sector,count);if(ret==0)return0;// 成功则直接返回LOG_WRN("Write failed (attempt %d), retrying...",i+1);k_msleep(10);// 等待 10ms 后重试}returnret;// 重试耗尽,返回错误}intsd_read_with_retry(constchar*pdrv,uint8_t*buf,uint32_tsector,uint32_tcount){intret;for(inti=0;i<MAX_RETRIES;i++){ret=disk_access_read(pdrv,buf,sector,count);if(ret==0)return0;LOG_WRN("Read failed (attempt %d), retrying...",i+1);k_msleep(10);}returnret;}voidthread_entry4(void*p1,void*p2,void*p3){intret;uint32_tstart_sector=1000;/* 避开 0 扇区(MBR/引导区),从安全区域开始 */uint32_tstart_time,end_time;uint64_ttotal_write_ms=0,total_read_ms=0;uint32_tsector_count;uint32_tsector_size;ret=disk_access_init("SD");if(ret!=0){printk("SD card init failed: %d \n",ret);}printk("SD card initialized successfully!\n");/* 2. 获取 SD 卡容量信息 */ret=disk_access_ioctl("SD",DISK_IOCTL_GET_SECTOR_COUNT,&sector_count);if(ret!=0){printk("Failed to get sector count");}ret=disk_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(inti=0;i<TEST_ITERATIONS;i++){/* 1. 写入性能测试 *//* 【关键】写入前:将 D-Cache 中的数据刷入 AXI SRAM,确保 DMA 读到最新数据 */SCB_CleanDCache_by_Addr((uint32_t*)test_write_buf,TOTAL_DATA_SIZE);start_time=k_uptime_get();ret=sd_write_with_retry("SD",test_write_buf,start_sector,TEST_BLOCK_COUNT);end_time=k_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_time=k_uptime_get();ret=sd_read_with_retry("SD",test_read_buf,start_sector,TEST_BLOCK_COUNT);end_time=k_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_SDHC=y CONFIG_DISK_ACCESS=y CONFIG_DISK_DRIVER_SDMMC=y CONFIG_SDMMC_STM32=y # 开启文件系统支持(以 FatFs 为例) CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_HEAP_MEM_POOL_SIZE=8192CONFIG_MAIN_STACK_SIZE=16384CONFIG_DMA=y # 显式启用 DMA 支持 CONFIG_DMA_STM32=y CONFIG_NOCACHE_MEMORY=y # 保持 DMA 缓冲区一致性

代码:

#include<stm32h7xx_hal.h>#include<string.h>#include<stdbool.h>#include<zephyr/drivers/dma.h>#include<zephyr/cache.h>#include<zephyr/devicetree.h>#include<zephyr/storage/disk_access.h>#include<zephyr/linker/linker-defs.h>#include<inttypes.h>#include<zephyr/arch/cpu.h>#include<zephyr/fs/fs.h>#include<ff.h>#defineTEST_FILE_PATH"/SD:/test.txt"staticFATFS fatfs_fs;staticstructfs_mount_tfat_fs_mnt={.type=FS_FATFS,.fs_data=&fatfs_fs,.mnt_point="/SD:",};staticintlsdir(constchar*path){intres;structfs_dir_tdirp;structfs_dirententry;fs_dir_t_init(&dirp);res=fs_opendir(&dirp,path);if(res){LOG_ERR("Error opening dir %s [%d]",path,res);returnres;}LOG_INF("Listing dir %s ...",path);for(;;){res=fs_readdir(&dirp,&entry);if(res||entry.name[0]==0){break;}if(entry.type==FS_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);/* 以 "写" 模式打开文件,如果文件不存在则创建,存在则清空 */res=fs_open(&file,path,FS_O_CREATE|FS_O_WRITE);if(res){LOG_ERR("Failed to open file for writing [%d]",res);returnres;}/* 将数据写入文件 */res=fs_write(&file,data,len);if(res<0){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);/* 以 "读" 模式打开文件 */res=fs_open(&file,path,FS_O_READ);if(res){LOG_ERR("Failed to open file for reading [%d]",res);returnres;}/* 读取文件内容到缓冲区 */bytes_read=fs_read(&file,buf,buf_size);if(bytes_read<0){LOG_ERR("Failed to read from file [%d]",bytes_read);res=bytes_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");ret=disk_access_init("SD");if(ret!=0){printk("Disk init failed: %d\n",ret);}else{printk("Disk initialized successfully.\n");}intres=fs_mount(&fat_fs_mnt);if(res==FR_OK){LOG_INF("SD Card mounted successfully.");lsdir(fat_fs_mnt.mnt_point);}else{LOG_ERR("Error mounting disk: %d",res);}constchar*test_data="Hello 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);}}

结果演示依据:

http://www.jsqmd.com/news/1157730/

相关文章:

  • deepx-code:终端原生AI编程工作流操作系统
  • 建造者模式和模板方法模式的区别
  • 雷达中国官方售后服务中心|服务电话及详细地址权威信息通知(2026年7月最新) - 亨得利官方服务中心
  • AI率爆表怎么办?10款降AI率软件实测(含免费降ai率工具)真实避坑指南
  • 2026年长春企业老板力荐公司法律师 5家实战精选推荐 - 本地品牌推荐
  • 孩子数学“计算总出错“不是粗心,真相只有这一个
  • 芯片电路能耗与散热控制方法与原理
  • 变增益运算放大器(PGA)原理与应用:动态范围扩展与信号调理技术
  • RBAC 权限模型演进解析:从RBAC0到RBAC3的4种模型对比与选型指南
  • 2026常州及周边文信授权全屋定制商家实测盘点 - 互联网科技品牌测评
  • Build Variants 构建变体
  • 前端转AI全栈,6-9个月落地实战!收藏这份专属学习路线,轻松实现职业升级
  • Spring Boot 3 + Vue 3 + MySQL 智能灌溉系统源码 前后端分离 实战项目
  • Ouch 0.8.1 官方版下载(夸克网盘,SHA256校验)
  • 2026年现阶段厦门旋转货柜公司盘点:蓝兴泰科技为何备受关注? - 品牌鉴赏官2026
  • 2026工业电源采购攻略:分享充电器厂家怎么选择方法,优质防水电源厂家推荐,分析裸板电源厂哪家好 - 栗子测评
  • 2026医院供电配套采购参考,医用隔离电源工厂资质盘点,医用隔离变压器、医用隔离电源哪家好怎么选 - 栗子测评
  • 无刷直流电机 PWM 频率与电感选择:50kHz下电流纹波降低30%的3个关键参数
  • 2026 年最佳恶意软件清除软件推荐:多款软件各有亮点,助你守护设备安全!
  • 延伸音(Tension)应用指南:属七和弦5种常用Tension音搭配与省略五音原则
  • 智能阅卷系统OCRAutoScore:让AI帮你批改试卷,节省90%阅卷时间
  • 伯爵中国官方售后服务中心|服务电话及完整官方地址权威信息声明(2026年7月更新) - 亨得利官方服务中心
  • C语言语法笔记
  • 从零搭建高效Linux虚拟机:网络、磁盘与增强功能配置全解析
  • ESP32 Arduino 经典蓝牙 SPP 通信实战:2节点自动配对与LED控制(附完整代码)
  • 【0基础嵌入式学习日志】Day15:位操作、GPIO 寄存器模拟与 LED 控制
  • PagedAttention失效诊断与DeepSeek V4推理优化实战
  • 2026双叠自锁垫圈使用成本怎么降低
  • 猫抓浏览器插件:新手到专家的视频下载完全指南
  • 69、<简单>数组元素插入