硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2355|回复: 10
收起左侧

[SD/SDIO] H7 使用 CubeMX 配置 SDMMC 和 FatFS,f_mount 返回 3

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 2023-10-27 13:12:00 | 显示全部楼层 |阅读模式
本帖最后由 969176707 于 2023-10-27 13:14 编辑

STM32H743 单片机通过 CubeMX 配置 SDMMC 和 FatFS,能读取到 SD 卡信息,但是调用 f_mount 返回值 3。请问是哪里的配置有问题吗?

CubeMX 配置:

01.png

02.png

03.png

04.png

05.png

时钟配置:

06.png

KEIL 工程:

7.png

8.png

执行结果:

9.png



回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2023-10-27 14:36:09 | 显示全部楼层
分享你的工程到百度云网盘,我看下
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2023-10-27 14:49:44 | 显示全部楼层
eric2013 发表于 2023-10-27 14:36
分享你的工程到百度云网盘,我看下

链接:https://pan.baidu.com/s/1l7-VzeXo91e6K182nTAd2w?pwd=sgnh
提取码:sgnh
万分感谢
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2023-10-27 14:53:26 | 显示全部楼层
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2023-10-28 08:50:56 | 显示全部楼层
你用的是SDMMC1,这个仅支持AXI SRAM空间。

下面两个地方修改下,你再试试

1、这个地方不要勾选DTCM,SDMMC1不支持这个空间。

这个对勾要去掉

下载.png

2、SDMMC1,先关闭AXI SRAM Cache试试

[C] 纯文本查看 复制代码
  /* 配置AXI SRAM的MPU属性为NORMAL, NO Read allocate,NO Write allocate */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

        HAL_MPU_ConfigRegion(&MPU_InitStruct);



回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2025-5-20 20:30:50 | 显示全部楼层
eric2013 发表于 2023-10-28 08:50
你用的是SDMMC1,这个仅支持AXI SRAM空间。

下面两个地方修改下,你再试试

我用的这个厂家给的示例,0x20000000是打勾的,而且也能正常运行
微信图片_20250520202923.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2025-5-21 07:03:13 | 显示全部楼层
my39366 发表于 2025-5-20 20:30
我用的这个厂家给的示例,0x20000000是打勾的,而且也能正常运行

这个帖子深入讨论了这个问题

STM32H7的SDIO接SD卡使用FatFS时,推荐用TCM,而SDIO直接访问的区用AXI SRAM
https://www.armbbs.cn/forum.php? ... 1531&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2025-5-21 23:45:42 | 显示全部楼层
eric2013 发表于 2025-5-21 07:03
这个帖子深入讨论了这个问题

STM32H7的SDIO接SD卡使用FatFS时,推荐用TCM,而SDIO直接访问的区用AXI S ...

感谢。终于搞定这个问题了,头疼了2天了。
我下载了您的代码,用您的代码 STM32H7+FREERTOS+FATFS是可以正常挂载磁盘的。但是用的GCC编译器,DMA接收是接收到了变量 FRESULT fs,所以需要将这个变量分配到DMA能访问的区域,即 0x24000000,这也是为什么您只分配了IRAM2区域的原因。f_mount会启用SD_Read 调用 BSP_SD_ReadBlocks_DMA,这个函数的形参如果传递是不可访问的区域,会直接在中断接收到错误,进入函数 void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
  BSP_SD_ErrorCallback();
}
这样DMA肯定是接收不到数据的,超时之后ReadStatus值依然为0,导致错误。

现在这个问题解决了,但是f_mount的结果变成了 FR_NO_FILESYSTEM 。。。

补充一下,我上面发的那个截图的代码没有使用FreeRTOS,所以它没问题。
明天再补充一些截图,今天太晚了,脑袋都快炸了。
1.png
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2025-5-22 11:24:47 | 显示全部楼层
my39366 发表于 2025-5-21 23:45
感谢。终于搞定这个问题了,头疼了2天了。
我下载了您的代码,用您的代码 STM32H7+FREERTOS+FATFS是可以 ...

FR_NO_FILESYSTEM 问题解决了,不是没有文件系统,用示例都能正常写,硬件是没问题的。
归根到底还是DMA访问区域的问题



解决方法如下
1 将文件读写相关变量都分配在 0x24000000区域

2 MPU我使用了硬汉哥代码里的低速配置
[C] 纯文本查看 复制代码
/* ×î¸ßÐÔÄÜ£¬¶ÁCacheºÍдCache¶¼¿ªÆô */	
#if 0  // 这里是低速
   	/* ÅäÖÃAXI SRAMµÄMPUÊôÐÔΪWrite back, Read allocate£¬Write allocate */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0x24000000;
	MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

	HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /* ×îµÍÐÔÄÜ£¬¶ÁCacheºÍдCache¶¼¹Ø±Õ */
#else
	/* ÅäÖÃAXI SRAMµÄMPUÊôÐÔΪWT, Read allocate£¬NO Write allocate */
	MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	MPU_InitStruct.BaseAddress      = 0x24000000;
	MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
	MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
	MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
	MPU_InitStruct.SubRegionDisable = 0x00;
	MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

	HAL_MPU_ConfigRegion(&MPU_InitStruct);
#endif
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);


我的变量声明,文件操作相关的都需要分配到 0x24000000区域

FATFS fs __attribute__((section(".RAM_DATA")));
char buffer[512] __attribute__((section(".RAM_DATA")));  // 写入数据缓存

BYTE work_buffer[512] __attribute__((section(".RAM_DATA")));  // 格式化用的,还没用过功能未知,先分配个区域吧
FIL fil __attribute__((section(".RAM_DATA")));  // 文件对象,这个里面包含写入缓存,所以必须声明在DMA能访问的区域




附件是我的 *.ld 文件(文件后缀是ld,为了上传改成了txt),GCC编译器靠这个分配变量地址
关键部分代码,声明一个区域,地址是 RAM(0x24000000),4字节对齐

   .RAM_AREA :
  {
    . = ALIGN(4);
    *(.RAM_DATA)
  }  >RAM


stm32h743vitx_flash.txt

6.03 KB, 下载次数: 2

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116779
QQ
发表于 2025-5-23 07:43:54 | 显示全部楼层
my39366 发表于 2025-5-22 11:24
FR_NO_FILESYSTEM 问题解决了,不是没有文件系统,用示例都能正常写,硬件是没问题的。
归根到底还是DMA ...

谢谢分享最终原因
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2025-5-24 19:26:04 | 显示全部楼层
my39366 发表于 2025-5-22 11:24
FR_NO_FILESYSTEM 问题解决了,不是没有文件系统,用示例都能正常写,硬件是没问题的。
归根到底还是DMA ...


我用的 vscode + gcc,如果你用stm32cubeide用gcc编译器,大概也会遇到类似问题。

又发现了新问题,debug下载正常,flash下载不正常,报错 binary check 错误  二进制比较错误,但不影响调试,就是说程序下进去了,但是下完了比对发现对不上
(GCC有debug编译和release编译)

排查发现:
编译出来的 bin文件640MB... 这样二进制比对不一致也是情理之中了(我的板子FLASH只有2048K)

最后确定,原因是上面的ld文件里,内存段定义有问题,如果没有声明段 (NOLOAD),那么相邻两个段会填充,结果会把文件填充成一个超大文件。

最好是把自己定义的内存段都加上 (NOLOAD) 声明
[C] 纯文本查看 复制代码
 .D22_AREA (NOLOAD):
 {
    . = ALIGN(4);
    . = 0x00;
    *(.RxDecripSection)
    . = 0x60;
    *(.TxDecripSection)
    . = 0x100;
    *(.Rx_PoolSection)
 } >RAM_D22 
  
 .D2_AREA (NOLOAD):
  {
    . = ALIGN(4);
    *(.AnalogInputSection)
    *(.other)
    . = ALIGN(4);
    *(.recordBuffer)

  }  >RAM_D2 

  .RAM_AREA  (NOLOAD):
  {
    . = ALIGN(4);
    *(.RAM_DATA)
  }  >RAM 


更新后的 .ld文件放在附件了

stm32h743vitx_flash.txt

6.41 KB, 下载次数: 1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-7-7 05:53 , Processed in 0.403706 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表