1

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

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

奇怪的是,在pf_read()完成之后,*bris 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

谢谢!

4

1 回答 1

0

我终于找到了问题所在。出于某种原因,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);
于 2022-01-28T14:29:00.880 回答