大家好,有段代码我想了很久不知怎么也想不出来,求解答!!谢谢!!谢谢!!是SD卡FAtfs系统测试的代码,在diskio.c文件中的一个函数:
DRESULT disk_read (
BYTE pdrv, /* 设备物理编号(0..) */
BYTE *buff, /* 数据缓存区 */
DWORD sector, /* 扇区首地址 */
UINT count /* 扇区个数(1..128) */
)
{
DRESULT status = RES_PARERR;
SD_Error SD_state = SD_OK;
switch (pdrv) {
case ATA: /* SD CARD */
if((DWORD)buff&3) //这个是判断是否4字节对齐的吧?我不懂为什么 ”与3” 的原因
{
DRESULT res = RES_OK;
DWORD scratch[SD_BLOCKSIZE / 4];
while (count--)
{
res = disk_read(ATA,(void *)scratch, sector++, 1); //这个又调用了自身函数,应该怎么解释其用法?这语句不是重新执行disk_read 函数吗?不是又要进行if((DWORD)buff&3) 语句判断了吗?这样 一直调用自身,下面的memcpy(buff, scratch, SD_BLOCKSIZE);语句不就一直得 不到执行了吗?
if (res != RES_OK)
{
break;
}
memcpy(buff, scratch, SD_BLOCKSIZE);
buff += SD_BLOCKSIZE;
}
return res;
}
SD_state=SD_ReadMultiBlocks(buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
if(SD_state==SD_OK)
{
/* Check if the Transfer is finished */
SD_state=SD_WaitReadOperation();
while(SD_GetStatus() != SD_TRANSFER_OK);
}
if(SD_state!=SD_OK)
status = RES_PARERR;
else
status = RES_OK;
break;
case SPI_FLASH:
break;
default:
status = RES_PARERR;
}
return status;
}
书本解析说:对于 SD 卡,最重要是使用 SD_ReadMultiBlocks 函数读取多块数据到存储区。这里需要注意的地方是 SD 卡数据操作是使用 DMA 传输的,并设置数据尺寸为 32 位大小,为实现数据正确传输,要求存储区是 4 字节对齐。在某些情况下, FatFs 提供的 buff 地址不是 4 字节对齐,这会导致 DMA 数据传输失败,所以为保证数据传输正确,可以先判断存储区地址是否是 4 字节对齐,如果存储区地址已经是 4 字节对齐,无需其他处理,直接使用SD_ReadMultiBlocks 函数执行多块读取即可。如果判断得到地址不是 4 字节对齐,则先申请一个 4 字节对齐的临时缓冲区,即局部数组变量 scratch,通过定义为 DWORD 类型可以使得其自动 4 字节对齐, scratch 所占的总存储空间也是一个块大小,这样把一个块数据读取到 scratch 内,然后把 scratch 存储器内容拷贝到 buff 地址空间上就可以了。
但我看不懂为什么 if((DWORD)buff&3) 这条语句是判断地址4字节对齐呢?而且,为什么下面又调用自身 disk_read(ATA,(void *)scratch, sector++, 1); ? |