Petit FatFs-pf_read()将错误的参数传递给disk_readp()



我正在使用带有Arduino Mega的Petit FatFS。我已经实现了所有必要的功能,但是pf_read()功能有问题。我正在尝试读取一个568(512+56(字节长的文件。第一个扇区可以毫无问题地读取(而且是正确的(,但第二个部分扇区无法读取。

我试着调试pf_read(),发现如下:对于第一个扇区,它用sector = 41104offset = 0count = 512调用disk_readp(),这似乎是正确的。然而,第二次它调用sector = -538935151offset = 512count = 56(至少计数是正确的(。

奇怪的是,在pf_read()完成之后,*br就是97,尽管函数实际上读取了512个字节。

为了防止disk_readp()出现问题,下面是我的代码:

DRESULT disk_readp (
BYTE* buff,     /* Pointer to the destination object */
DWORD sector,   /* Sector number (LBA) */
UINT offset,    /* Offset in the sector */
UINT count      /* Byte count (bit15:destination) */
)
{
uint8_t r1; 
uint8_t res_token;
uint16_t readAttempts;
DRESULT res = RES_ERROR;
CS_HIGH();
spi_transmit(0xFF);
CS_LOW();
spi_transmit(0xFF);
r1 = send_command(CMD17, sector);

if(r1 != 0xFF)
{
readAttempts = 0;
while(++readAttempts != SD_MAX_READ_ATTEMPTS)
{
if((res_token = spi_transmit(0xFF)) != 0xFF) break;
}
if(res_token == 0xFE)
{
// read 512 byte block
for(uint16_t i = 0; i < offset; i++) {
spi_transmit(0xFF); // discard data from (0) to (offset)
}
for(uint16_t i = offset; i < offset + count; i++)
{
*(buff++) = spi_transmit(0xFF); // safe data from (offset) to (offset + count)
}
for(uint16_t i = offset + count; i < 512; i++) {
spi_transmit(0xFF); // discard data from (offset + count) to (512)
}

// read and ignore 16-bit CRC
spi_transmit(0xFF);
spi_transmit(0xFF);
res = RES_OK;
}
}
CS_LOW();
spi_transmit(0xFF);
CS_HIGH();
spi_transmit(0xFF);
return res;
}

以及Petit FatFS文档的链接:http://elm-chan.org/fsw/ff/00index_p.html

谢谢

我终于发现了问题。由于某种原因,gcc优化掉了pf_read()的一个重要部分。

FRESULT pf_read (
void* buff,     /* Pointer to the read buffer (NULL:Forward data to the stream)*/
UINT btr,       /* Number of bytes to read */
UINT* br        /* Pointer to number of bytes read */
)
{
DRESULT dr;
CLUST clst;
DWORD sect, remain;
UINT rcnt;
BYTE cs, *rbuff = buff;
FATFS *fs = FatFs;

*br = 0;
if (!fs) return FR_NOT_ENABLED;     /* Check file system */
if (!(fs->flag & FA_OPENED)) return FR_NOT_OPENED;  /* Check if opened */
remain = fs->fsize - fs->fptr;
if (btr > remain) btr = (UINT)remain;           /* Truncate btr by remaining bytes */
while (btr) {                                   /* Repeat until all data transferred */
if ((fs->fptr % 512) == 0) {                /* On the sector boundary? */
cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1));  /* Sector offset in the cluster */
if (!cs) {                              /* On the cluster boundary? */
if (fs->fptr == 0) {                /* On the top of the file? */
clst = fs->org_clust;
} else {
clst = get_fat(fs->curr_clust);
}
if (clst <= 1) ABORT(FR_DISK_ERR);
fs->curr_clust = clst;              /* Update current cluster */
}
sect = clust2sect(fs->curr_clust);      /* Get current sector */
if (!sect) ABORT(FR_DISK_ERR);
fs->dsect = sect + cs;
}
rcnt = 512 - (UINT)fs->fptr % 512;          /* Get partial sector data from sector buffer */
if (rcnt > btr) rcnt = btr;
debugInt(fs->dsect);
debugInt((UINT)fs->fptr % 512);
debugInt(rcnt);
writeString("n");
dr = disk_readp(rbuff, fs->dsect, (UINT)fs->fptr % 512, rcnt);
if (dr) ABORT(FR_DISK_ERR);
fs->fptr += rcnt;                           /* Advances file read pointer */
btr -= rcnt; *br += rcnt;                   /* Update read counter */
if (rbuff) rbuff += rcnt;                   /* Advances the data pointer if destination is memory */
}
return FR_OK;
}

*br = 0行永远不会被执行,这完全打乱了进一步的计算。在我关闭了-O0的优化后,一切都正常了。

因此,在将*br传递给函数之前,我只确保将其设置为0。并不能真正解决问题,但至少它现在起作用了。

(GCC 11.1.0(

编辑:

没关系,我只是忘了指针是如何工作的。我这样叫pf_read()

unsigned int *br;
pf_read(path, size, br);

最新更新