Jump to content

Can't read file on FatFS system using GFILE (ugfx + chibios)


Recommended Posts

Posted

Hi, I hava a stm32f746-discovery board. I'm using chibios + ugfx. Made fatfs diskio.c layout. With fatfs only all works fine, I can read and write files.

Also I'm working with QSPI external flash.

The problem that I can't read file on fatFS with function gfileRead. File opens with GFILE and I can get size of it. But when I read file I get array with zeros. But when I read the same sector with qspi layout I get right data. What it may be? Here is code:

  volatile bool_t resultMount = gfileMount('F', "QSPI");

  GFILE* imgFile;
  volatile GFILE *imgFatFile;
  imgFile = gfileOpen("S|test-pal8.bmp", "rb");
  imgFatFile = gfileOpen("F|testpal.bmp", "rb");
  volatile uint16_t fatSS = gfileGetSize(imgFatFile);

  uint8_t quadRead[512];

  //        quadIndirectReadMode(quadRead, 512, 128*512); // get right data, sector is the same (128), sector size 512 byte
  gfileRead(imgFatFile, quadRead, 10); // array with 10 zeros

  volatile gdispImageError received_error = gdispImageOpenGFile(&myImage, imgFatFile); // the problem discovered here
  gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
  gdispImageClose(&myImage);

 

Posted

Try reseting the file position back to 0 before calling gdispImageOpenGFile.

I am not sure that gdispImageOpenGFile does that automatically and you have already read data from the file with gfileRead.

I think the call is gfileSetPos(imgFatFile, 0).

Also have you checked that imgFatFile is non-NULL after opening the file?

Posted
4 minutes ago, inmarket said:

Try reseting the file position back to 0 before calling gdispImageOpenGFile.

I am not sure that gdispImageOpenGFile does that automatically and you have already read data from the file with gfileRead.

I think the call is gfileSetPos(imgFatFile, 0).

Also have you checked that imgFatFile is non-NULL after opening the file?

I already did this before. Yeah, he is non null and when accessing fatfs diskio.c layout read right 128 sector. But somehow bufffer is written with zeros, But when I access file with f_read or just quadIndirectReadMode I can read data that absolutely correct.

Posted (edited)
int main(int argc, char* argv[])
{
    gfxInit();

//    uint8_t workBuffer[2048];
//    volatile FRESULT mkResult = f_mkfs("QSPI", FM_FAT | FM_SFD, 4*512, workBuffer, 2048);

    gdispSetBacklight(100);
    gdispSetContrast(100);

    geventListenerInit(&glistener);
    gwinAttachListener(&glistener);

    guiCreate();
//    writeUgfxImage();
    volatile uint8_t arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,  10};
    volatile uint8_t readArr[10];
    volatile uint8_t readArr2[10];
//    writeSimpleFile("test.png", arr, 10);
	readSimpleFile("test.png", readArr, 10);  \\ this read array with values of arr[10]
	readUgfxFile2("F|test.png", readArr2, 10); \\ this with zeros
    readUgfxFile("F|test.png"); \\ this with zeros
    while (1) {
//      chThdSleepMilliseconds(300);
      guiEventLoop();
    }


    return 0;
}

void writeSimpleFile(char* name, uint8_t *buff, UINT n) {
  FATFS fileSystem;
  FIL testFile;
  f_mount(&fileSystem, "QSPI", 1);
  volatile UINT sizeB = 0;

  volatile FRESULT ttt = f_open(&testFile, name, FA_CREATE_ALWAYS | FA_WRITE);
  volatile FRESULT writeFl = f_write (&testFile, buff, n, &sizeB);
  volatile closeSt = f_close(&testFile);
}

void readSimpleFile(char* name, uint8_t *buff, UINT n) {
  FATFS fileSystem;
  FIL testFile;
  f_mount(&fileSystem, "QSPI", 1);
  volatile UINT sizeB = 0;

  volatile FRESULT ttrt = f_open(&testFile, name, FA_READ);
  volatile FRESULT readStatus =  f_read (&testFile, buff, n, &sizeB);
  volatile closeSrt = f_close(&testFile);
}

void writeUgfxImage() {
  volatile bool_t resultMount = gfileMount('F', "QSPI");
  volatile GFILE* imgFile;
  volatile GFILE *imgFatFile;
  imgFile = gfileOpen("S|test-pal8.bmp", "rb");
  imgFatFile = gfileOpen("F|testpal.bmp", "wx");

  volatile uint16_t imgSize = gfileGetSize(imgFile);
  volatile uint8_t *imgBuf = gfxAlloc(gfileGetSize(imgFile));

  gfileRead(imgFile, imgBuf, gfileGetSize(imgFile));
  gfileWrite(imgFatFile, imgBuf, imgSize);
  gfileClose(imgFatFile);
  gfileClose(imgFile);
}

void readUgfxFile(char *name) {
  volatile bool_t resultMount = gfileMount('F', "QSPI");
  volatile GFILE* imgFile;
  imgFile = gfileOpen(name, "rb");

  volatile uint16_t imgSize = gfileGetSize(imgFile);
  volatile uint8_t *imgBuf = gfxAlloc(gfileGetSize(imgFile));

  gfileRead(imgFile, imgBuf, gfileGetSize(imgFile));
  gfileClose(imgFile);
}

void readUgfxFile2(char *name, uint8_t *buff, UINT n) {
  volatile bool_t resultMount = gfileMount('F', "QSPI");
  volatile GFILE* imgFile;
  imgFile = gfileOpen(name, "rb");
  volatile UINT sizeB = 0;

  FIL* testFile = (FIL*) imgFile->obj;

  volatile FRESULT readStatus =  f_read (testFile, buff, n, &sizeB);
  volatile closeSrt = f_close(testFile);
}

void displayImage(GFILE *imgFatFile) {
  coord_t swidth, sheight;
  volatile bool_t resultMount = gfileMount('F', "QSPI");
  swidth = gdispGetWidth();
  sheight = gdispGetHeight();

  gfileSetPos(imgFatFile, 0);
  volatile gdispImageError received_error = gdispImageOpenGFile(&myImage, imgFatFile);
  gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
  gdispImageClose(&myImage);
}

readUgfxFile(2) not working, returns array with zeros

Edited by Robert G.
add some code
Posted

This is looking like something that is specific to your implementation relating to fatfs and the devices you use.

Can you please try cpu20's suggestion and if that doesn't work can you please debug down to find out why it is failing. GFILE is a thin wrapper around a number of file system handlers so typically (and especially for fatfs) the uGFX call translates directly into a file system call.

The GFILE /fatfs interface is well tested on multiple platforms including ChibiOS (it was originally built on ChibiOS and that is why it is the only os with a predefined diskio interface). It will be interesting to see what you find. 

Posted

I think problem is here (changed from ORIGINAL) and it will read, but somehow it can't out off funciton f_read and continue thread, but data is right: 

static bool_t fatfsOpen(GFILE* f, const char* fname)
{
    FIL fd;

    #if !GFILE_NEED_NOAUTOMOUNT
        if (!fatfs_mounted && !fatfsMount(""))
            return FALSE;
    #endif

//    if (!(fd = gfxAlloc(sizeof(FIL))))
//        return FALSE;

    if (f_open(&fd, fname, fatfs_flags2mode(f)) != FR_OK) {
//        gfxFree(fd);
        f->obj = 0;

        return FALSE;
    }

    f->obj = (void*)&fd;

    #if !GFILE_NEED_NOAUTOSYNC
        // no need to sync when not opening for write
        if (f->flags & GFILEFLG_WRITE) {
            f_sync( (FIL*)f->obj );
        }
    #endif

    return TRUE;    
}

ORIGINAL: 
static bool_t fatfsOpen(GFILE* f, const char* fname)
{
	FIL* fd;

	#if !GFILE_NEED_NOAUTOMOUNT
		if (!fatfs_mounted && !fatfsMount(""))
			return FALSE;
	#endif

	if (!(fd = gfxAlloc(sizeof(FIL))))
		return FALSE;

	if (f_open(fd, fname, fatfs_flags2mode(f)) != FR_OK) {
		gfxFree(fd);
		f->obj = 0;

		return FALSE;
	}

	f->obj = (void*)fd;

	#if !GFILE_NEED_NOAUTOSYNC
		// no need to sync when not opening for write
		if (f->flags & GFILEFLG_WRITE) {
			f_sync( (FIL*)f->obj );
		}
	#endif

	return TRUE;	
}

 

Posted

Your new version has a BIG bug in it...

You are returning the address of a stack local variable to outside the scope it is defined in.

What will happen is that as you call other functions after the open call it could easily overwrite that stack area hence corrupting the FIL structure. Even worse, any update in the FIL structure could overwrite your call stack leading to strange symptoms and very likely hard fault crashes.

If that new routine seems to work for you it indicates that something bad is happenning with your heap memory allocator thus affecting the operation of gfxAlloc and gfxFree.

One likely cause of that is having defined too small a stack. Overrunning the stack could affect memory allocation which in turn affects the image.

Posted
12 minutes ago, inmarket said:

Your new version has a BIG bug in it...

You are returning the address of a stack local variable to outside the scope it is defined in.

What will happen is that as you call other functions after the open call it could easily overwrite that stack area hence corrupting the FIL structure. Even worse, any update in the FIL structure could overwrite your call stack leading to strange symptoms and very likely hard fault crashes.

If that new routine seems to work for you it indicates that something bad is happenning with your heap memory allocator thus affecting the operation of gfxAlloc and gfxFree.

One likely cause of that is having defined too small a stack. Overrunning the stack could affect memory allocation which in turn affects the image.

thanks. solution of cpu20 is worked. 

Posted

Note that this isn't a solid solution. As also mentioned in this bug report on the ChibiOS forums it is not guaranteed that the FatFS buffers are 32-bit aligned.
So in most cases it will work, but if the buffer stretches over two 32-bit lines in memory due to misalignment it could be that things go wrong as only one cache line will be flushed.

The most solid solution is to use non-cachable memory.

Posted

This is now incorporated into the uGFX repository.

There are a couple of fixes relative to the version above:

  • It is now ChibiOS V2 compatible too (ie dma cache support just does not exist)
  • It now handles the bug where ChibiOS expects the buffer to be 32 byte aligned.

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...