详解SD协议与FatFs文件系统中的Block、Sector的差异,与FatFs中底层驱动disk_ioctl的编写及思路

1. SD2.0协议中的sector与block

点我下载SD2.0协议

git clone https://github.com/Hotakus/SD2.0-protocol-pdf

在SD协议中,我们可以看到这样的原话:

block size

大意是讲,在高容量卡(SDHC)中,卡的block size是512字节(bytes),这里指的是data block size,也是大容量卡最小的数据操作单位,那么问题来了,还有一个比较重要的参数是sector size,在2.0以下的卡中,sector size被定义在CSD Version 1.0中,但在CSD Version 2.0中sector size固定为0x7F,并且是没有任何意义的。

从SD2.0协议中的CSD Version 2.0可以看到:
sector size

大意为:sector size固定为0x7F,memory boundary(存储边界)由AU size(Allocation Unit size 可以叫做物理边界)指定,所以对于2.0及以上的卡,是无法从CSD中获取sector size的。


2. SD协议中AU size

那么问题又来了,这个所谓的AU size又该如何获知呢?
首先我们得知道这个AU size代表什么,在SD2.0协议4.11中可以看到:
AU size

大意为:AU是卡的物理边界,这个值可以由一个或多个data block(512 bytes)组成。

  • Maximum AU size(最大物理边界)一定程度上定义了memory capacity(卡容量)的大小范围。
  • AU size 同时也可以被认为是主机正常操作SD卡的最小单位的保证。(那是不是可以认为最小的AU size == data block size?)
  • AU size 也被用来计算卡的擦除时间(不用了解)。

在SD2.0协议4.10.2中,我们可以看到如下定义:

在这里插入图片描述
在这里插入图片描述

图中红圈表示的正是Maximum AU size,继续往下看:

在这里插入图片描述

我们可以从表格中了解到,对于大容量卡(SDHC)且SD协议来说,
Maximum AU size( 最大 ) 一定是 4MB( 4096kb / 512bytes = 8192 data blocks,记住这个值 )


3. FatFs中的sector与block

大家如果使用一些存储设备(例如SPI FLASH 或 SD卡等)的话,可能大多数人会考虑使用FatFs进行项目开发,那么问题就由此衍生出来了,一部分细心的人可能会提出一个问题:如果使用SD卡,那么在SD2.0协议中明明说block为512字节(bytes),那为什么在FatFs中,sector size才是512字节呢?这不是错了吗?

其实文件系统的sector和block 与 SD协议的sector和block含义正好相反。在SD协议中,大小包含关系是:block ⊆ sector。而在FatFs中相反:sector ⊆ block,所以使用FatFs在底层驱动编写和移植时,这个关系要清楚。不过也有相当一部分人是“代码搬运工”,只管用,却不研究原理,属实不妥。

由此可知,在disk_ioctl中GET_SECTOR_SIZE和GET_BLOCK_SIZE,可以有以下关系:

最大:8192 data blocks(SD) == 8192 sector(FatFs) == 1 block(FatFs)

最小:1 data blocks(SD) == 1 sector(FatFs) == 1 block(FatFs)

有这样的关系就可以开始基于SD卡移植FatFs了。


4. FatFs中底层驱动disk_ioctl的编写及思路

FatFs的官网,我们可以看到disk_ioctl的cmd参数解释:

在这里插入图片描述
这几个参数是系统使用的,除了CTRL_TRIM,其他必须实现,且最后加一条命令CTRL_SYNC。

我们用C代码演示:

/* 	
*	假设我们已经从SD卡中的CSD中获取并计算得到了当前SD卡的块(blocks)信息,
*	由FatFs与SD协议的关系,定义变量:sect_cnt(FatFs),这个值等于blocks(SD)数量
*/
#define SD			0
#define SPIFLASH	1

extern u32 sect_cnt;				//导入sect_cnt

DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
) {
	switch (pdrv) {
	case SD :
		switch ( cmd ) {			//fatfs内核使用cmd调用
            case GET_SECTOR_COUNT:	//sector count, 传入sect_cnt
                *(DWORD*)buff = sect_cnt;
                return RES_OK;
            case GET_SECTOR_SIZE:	//sector size, 传入block size(SD),单位bytes
                *(DWORD*)buff = 512;
                return RES_OK;
            case GET_BLOCK_SIZE:	//block size, 由上文可得,对于SD2.0卡最大8192,最小 1
                *(DWORD*)buff = 1;	//单位为 sector(FatFs)
                return RES_OK;
            case CTRL_SYNC:			//同步命令,貌似FatFs内核用来判断写操作是否完成
                return RES_OK;
        }
	default:
        printf( "No device %d.\n", pdrv );
        break;
	}
	return RES_PARERR;				//默认返回参数错误
}


如果您看到了这里,还请点个赞支持一下吧。

http://elm-chan.org/fsw/ff/doc/dioctl.html
SD2.0 protocol

  • 23
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要删除SD卡的文件夹,需要使用FATFS文件系统提供的相关函数。以下是一个简单的例子,可以让你了解如何在STM32上使用FATFS文件系统删除SD卡的文件夹。 首先,你需要初始化FATFS文件系统,包括挂载SD卡、打开文件夹等操作。下面是一个初始化FATFS的示例代码: ```c FATFS fs; FRESULT res; DIR dir; res = f_mount(&fs, "", 1); if (res != FR_OK) { // 处理挂载失败的情况 } res = f_opendir(&dir, "/folder_name"); if (res != FR_OK) { // 处理打开文件夹失败的情况 } ``` 上面的代码,`f_mount`函数用于挂载FATFS文件系统,`f_opendir`函数用于打开指定的文件夹。 接下来,你可以使用`f_readdir`函数遍历文件夹的所有文件和子文件夹,然后使用`f_unlink`函数删除子文件夹和其的文件。下面是一个示例代码: ```c FILINFO fileInfo; while (f_readdir(&dir, &fileInfo) == FR_OK && fileInfo.fname[0] != 0) { if (fileInfo.fattrib & AM_DIR) { // 如果是子文件夹,则递归删除 if (strcmp(fileInfo.fname, ".") != 0 && strcmp(fileInfo.fname, "..") != 0) { char path[64]; sprintf(path, "/folder_name/%s", fileInfo.fname); res = f_unlink(path); if (res != FR_OK) { // 处理删除失败的情况 } } } else { // 如果是文件,则直接删除 char path[64]; sprintf(path, "/folder_name/%s", fileInfo.fname); res = f_unlink(path); if (res != FR_OK) { // 处理删除失败的情况 } } } ``` 上面的代码,`f_readdir`函数用于读取文件夹的文件信息,`f_unlink`函数用于删除文件或文件夹。在遍历文件夹时,需要忽略`.`和`..`两个特殊的文件夹。 最后,你可以使用`f_closedir`函数关闭文件夹,以释放相关资源: ```c f_closedir(&dir); ``` 这样,你就可以使用FATFS文件系统STM32上删除SD卡的文件夹了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值