C 金融行动特别工作组报告不起作用

C 金融行动特别工作组报告不起作用,c,embedded,sd-card,bare-metal,fatfs,C,Embedded,Sd Card,Bare Metal,Fatfs,我在跳板上,我正试图在SD卡上写字。 我在一个嵌入式系统上工作,我没有任何操作系统,我运行的是纯金属 我可以从SD卡上读得很好,他们的数据没有问题 但当我开始阅读时,我有一些奇怪的行为: f_write返回FR_OK bw bytes write变量是正确的 该文件已创建,当我从PC读取SD卡时,我可以看到它 但是当我读文件时,它是空的 这是我的密码: void WriteFile(char const* fileName, char* buffer, size_t size) { FI

我在跳板上,我正试图在SD卡上写字。 我在一个嵌入式系统上工作,我没有任何操作系统,我运行的是纯金属

我可以从SD卡上读得很好,他们的数据没有问题

但当我开始阅读时,我有一些奇怪的行为:

f_write返回FR_OK bw bytes write变量是正确的 该文件已创建,当我从PC读取SD卡时,我可以看到它 但是当我读文件时,它是空的

这是我的密码:

void WriteFile(char const* fileName, char* buffer, size_t size)
{
    FIL file;
    FATFS fs;
    UINT bw;
    FRESULT fr;

    f_mount(&fs, "", 0);
    f_open(&file, fileName, FA_WRITE | FA_CREATE_ALWAYS);
    fr = f_write(&file, buffer, size, &bw);
    if (size != bw || fr != FR_OK)
        PRINT(("Error in writing !\n"));
    f_close(&file);
    f_mount(NULL, "", 0);
}
我这样调用这个方法:

 WriteFile("Hello.txt", "Hello World !", 13);

你知道我做错了什么吗?

我找到了一个解决我问题的小方法: 基本上它不会写在SD卡上,因为在XILINX的低级API中缓冲区还没有满。 所以我做的很简单:我只写一次数据。虽然文件的大小不等于或大于写入的数据的大小,但我以32块为单位写入0 另外,还有一件重要的事情:您写入的数据必须是32字节对齐的\ 这是我的工作代码:

size_t SizeOfFile(char const *path)
{
    FILE *fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size_t fsize = (size_t) ftell(fp);
    fclose(fp);
    return fsize;
}

void WriteFile( char const* fileName, char* buffer, size_t size )
{
    size_t allignement = ( size + 32 - 1 ) & ~ ( 32 - 1 );  // We must allign by 32
    char* Buffer_logger = pleb_malloc( allignement );
    pleb_memset( Buffer_logger, 0, allignement );
    pleb_memcpy( Buffer_logger, buffer, size );

    unsigned int BytesWr;
    size_t accum = 0;
    result = f_open( &file, fileName, FA_CREATE_ALWAYS | FA_WRITE | FA_READ );
    if ( result != 0 )
    {
        return;
    }

    sprintf( Buffer_logger, "%s", buffer );

    while ( SizeOfFile( fileName ) == 0 )
    {
        // Open log for writing
        result = f_open( &file, fileName, FA_WRITE );
        if ( result != 0 )
        {
            return;
        }

        // Point to the EOF
        result = f_lseek( &file, accum );
        if ( result != 0 )
        {
            return;
        }

        // Write to log
        result = f_write( &file, (const void*) Buffer_logger, size, &BytesWr );
        if ( result != 0 )
        {
            return;
        }

        accum += accum + strlen( Buffer_logger );

        //Close file.
        result = f_close( &file );
        if ( result != 0 )
        {
            return;
        }

        pleb_memset( Buffer_logger, 0, allignement );

        size = 32;
        pleb_memset( Buffer_logger, 0, size );
    }
    pleb_free( Buffer_logger );
    PRINT( ("Data written to log Successfully\r\n") );
}

您只需刷新缓冲区f_sync:

        FRESULT result;
        FATFS fs;
        FIL file;

        const char string[] = "Hallo world\0";
        uint16_t written = 0;
        FILINFO fno;

        /* Open or create a log file and ready to append */
        printf("mount:%d",f_mount(&fs, "", 1));
        printf("open: %d", f_open(&file, "log.txt", FA_WRITE  | FA_OPEN_ALWAYS ));
        printf("stat: %d", f_stat("log3.txt", &fno));
        printf("write: %d wr: %d", f_write(&file, string, 11, &written), written);
        printf("flush: %d", f_sync(&file));
        printf("close: %d", f_close(&file)); /* close performs sync before close */

我也有同样的问题,fatfs创建了该文件,但不会向其中写入任何数据。fatfs函数没有产生错误,因此我被困了2天,然后我发现,如果我在I/o层发送512字节块后放置断点,在我的代码中,它的函数send_datablockbuff,0xFE就可以工作了

我发现,在写入数据块后,SD需要时间将该数据块实际写入内部闪存

在“单块写入忙周期DO行”部分下,在发送任何其他命令(即另一个CMD24单块写入)之前,您必须等待该周期结束,否则SD将丢弃最后一个CMD24,因此您将丢失刚才发送的数据

我在send_datablock函数的末尾放置了一个等待循环,如下所示

    /* if not accepted, return with error */
    if((data & 0x1F) != 0x05)
    {
        return 0;
    }
    else
    {
        /* wait for SD to finish writing data */
        tmr = 5000;
        do
        {
            data = get_response(SDEXIChannel);
            if(data != 0x00)
            {
                break;
            }
            udelay(100);
            tmr--;
        } while(0 != tmr);

        /* did we time out ? if so return with error */
        if(tmr == 0)
        {
            return 0;
        }

这似乎已经解决了我的问题,我现在可以写入SD卡上的文件,无论如何,希望这可以节省人两天的调试

我在使用Xilinx SoC(如ZedBoard)在SD上写东西时遇到了同样的问题。我无法将数据写入SD卡,即使:

所有功能都成功

我能够删除和创建文件,所以我不是只读的

当我读回我在卡片上写的内容时,f_lseek返回到0,f_read我读到了正确的数据

每次我在重新启动后读取文件时,它都是空的

我尝试了以前的解决方案,但没有一个奏效。 史蒂夫的回答使我走上了正确的道路

修复方法:我需要按256字节的块写入数据,才能将数据实际写入SD。256字节是我SD卡中一页的大小,所以它很有意义

如果写入不是256的倍数,则不会写入所有数据。 例:

使用f_write->实际写入文件的字节写入的字节

512->512

480->256

255->0

256->256


希望它能帮助别人:

我知道这是一篇旧文章,但如果有人有这个问题,我可以通过添加f_sync&myFile来修复它

            char myData[] = "Hello from STM32";
            if(f_write(&myFile, myData, strlen(myData), &myBytes) == FR_OK)
            {
                if(f_sync(&myFile) == FR_OK){
                    HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
                    HAL_Delay(500);
                    HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
                }
            }

FatFs不提供低级设备I/O,例如,您必须提供第三方板或芯片供应商提供的设备I/O,因此这可能是一个问题,尽管很难看出文件是如何创建的。此外,FATF还可以配置为只读文件系统,但文件的创建似乎并非如此。在任何情况下,问题似乎不在您提供的代码级别,而是在库配置级别的驱动程序,因此,就目前情况而言,你不太可能得到一个答案。这是你的问题答案。我和你艾曼有同样的问题,但当我尝试在我用电脑创建的文本文件上使用f_write时,我可以覆盖该文件的内容。但是我不能让它与我用f_open创建的空文件一起工作。@Frostbite:当你说覆盖时,你的意思是在其中添加你自己的数据,而不仅仅是一个空白文件?有趣的是,我还没试过这个。。。但是在阅读了您的邮件后,我记得我应该将问题更新为“已回答”,因为我找到了一个可行的解决方案。我非常确定f_同步会完成这项工作,正如下面在本文中所述,这并不能真正回答问题。如果您有不同的问题,可以单击以提问。一旦你有足够的时间,你也可以吸引更多的注意力@疯狂疯狂我认为OP在写问题时犯了一个错误:。。。但是当我开始阅读时,我。。。根据代码,他想写入文件,但无法写入。所以我认为我的回答很好:你知道我做错了什么吗?至于为什么世界你好!大小为13字节的数据将不会写入文件。我编辑过的答案更清楚吗?我遇到的一个问题是在附加一个文件时,文件中的数据不是32位对齐的。每当写入跨越块大小边界时,它会从我的数据中添加2个字节或删除2个字节。让数据32位对齐解决了这个问题。这个答案帮助我找到了答案 问题谢谢