[英]Petit FatFs - pf_read() passes wrong arguments to disk_readp()
I'm using Petit FatFS with an Arduino Mega.我正在使用带有 Arduino Mega 的 Petit FatFS。 I've implemented all necessary functions, however I'm having issues with the
pf_read()
function.我已经实现了所有必要的功能,但是我遇到了
pf_read()
function 的问题。 I'm trying to read a file, which is 568 (512 + 56) bytes long.我正在尝试读取一个长度为 568 (512 + 56) 字节的文件。 The first sector can be read without a problem (and is correct), but the second partial sector doesn't get read.
第一个扇区可以毫无问题地读取(并且是正确的),但第二个部分扇区不会被读取。
I tried debugging pf_read()
and found following: For the first sector it calls disk_readp()
with sector = 41104
, offset = 0
and count = 512
, which seems correct.我尝试调试
pf_read()
并发现以下内容:对于第一个扇区,它调用disk_readp()
sector = 41104
, offset = 0
和count = 512
,这似乎是正确的。 The second time however, it calls with sector = -538935151
, offset = 512
and count = 56
(at least the count is correct).然而,第二次,它使用
sector = -538935151
、 offset = 512
和count = 56
调用(至少计数是正确的)。
Weirdly enough, after pf_read()
is done, *br
is 97
, even though the function has actually read 512 bytes.奇怪的是,在
pf_read()
完成后, *br
是97
,即使 function 实际上已经读取了 512 个字节。
Just in case it's an issue with disk_readp()
, here is my code:以防万一
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;
}
And the link to the Petit FatFS documentation: http://elm-chan.org/fsw/ff/00index_p.html以及 Petit FatFS 文档的链接: http://elm-chan.org/fsw/ff/00index_p.html
Thanks!谢谢!
I finally found the problem.我终于找到了问题所在。 For some reason,
gcc
optimized away an important part of pf_read()
.出于某种原因,
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;
}
The line *br = 0
never gets executed, which completely messes up further calculations. *br = 0
行永远不会被执行,这完全打乱了进一步的计算。 After I turned off optimizations with -O0
, everything worked.在我使用
-O0
关闭优化后,一切正常。
So I just made sure to set *br
to 0, before I pass it to the function.所以我只是确保将
*br
设置为 0,然后再将它传递给 function。 Doesn't really solve the problem, but at least it works now.并没有真正解决问题,但至少现在可以了。
(GCC 11.1.0) (GCC 11.1.0)
Edit:编辑:
Never mind, I just forgot how pointers worked.没关系,我只是忘记了指针是如何工作的。 I called
pf_read()
like this:我这样调用
pf_read()
:
unsigned int *br;
pf_read(path, size, br);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.