USB Mass storage, fwrite and buffer > 512 octets

11 May 2011

Hi,

I have a bug with fwrite function on Mben LPC176B. I use FAT library with an USB Key. When I write larger than 512 bytes in one time, only the first bloc is valid. For example, if I write the byte 0xAA 2048 times (4 blocs), I read in the file : ->0xAA 512 times ->1536 strange bytes.

The stranges bytes come from old file deleted or data already present on key.

It's a bug in FAT library ?

Thank you.

Regards.

PS : sorry for my bad english.

11 May 2011

Hi Stephane,

It could be in the USB or FAT library I guess. You can see the original test port of the CHAN FS I did at:

Import programfat

I guess you are using the one based on that, so you may be able to track down the problem in that (I've also noticed some others have ported the CHAN filesystem too, so you may find some improved versions). Else it could be in the USB code.

Hope that helps you track it down!

Simon

13 May 2011

Hi,

Thank you very much for your help. I replace my FAT library by the code, but it's don't solve my problem.

I test with this simple code :

#include "mbed.h"

#include "MSCFileSystem.h"
#include "stdio.h"

#define SIZETRAME 1024*16
char buff[SIZETRAME]; 

MSCFileSystem massStorage("usb");

DigitalOut led1(LED1),led2(LED2),led3(LED3),led4(LED4);

int main() {
    
    // Sample buffer initialisation    
    for(unsigned int i=0;i<SIZETRAME;i++)
    {
        buff[i]=0x1A+(i%6);
    }
    
    
    led1=0;
    FILE* fp=fopen("/usb/mbedtest.bin","wb");
    
    fwrite(buff,512*4,1,fp);
    fclose(fp);
    led1=1;
    while(1);
}

I will read the FAT source code, maybe I can understand the mistake.

13 May 2011

Ok, I found the bug. On line 61 of diskio.c, you must replace :

int res = FATFileSystem::_ffs[drv]->disk_write((char*)buff, sector);

by

int res = FATFileSystem::_ffs[drv]->disk_write((char*)buff, s);

The function is :

DRESULT disk_write (
    BYTE drv,            /* Physical drive nmuber (0..) */
    const BYTE *buff,    /* Data to be written */
    DWORD sector,        /* Sector address (LBA) */
    BYTE count            /* Number of sectors to write (1..255) */
)
{
    FFSDEBUG("disk_write(sector %d, count %d) on drv [%d]\n", sector, count, drv);
    for(int s=sector; s<sector+count; s++) {
        FFSDEBUG(" disk_write(sector %d)\n", s);
---->   int res = FATFileSystem::_ffs[drv]->disk_write((char*)buff, sector);
        if(res) {
            return RES_PARERR;
        }
        buff += 512;
    }
    return RES_OK;
}

and sector is not incremented when loop go to the next secteur.

I don't found the bug tracker to report this.

13 May 2011

This had me tearing out my hair for a few days about a month ago.