Robert G. Posted September 27, 2017 Report Share Posted September 27, 2017 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); Link to comment Share on other sites More sharing options...
inmarket Posted September 27, 2017 Report Share Posted September 27, 2017 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? Link to comment Share on other sites More sharing options...
Robert G. Posted September 27, 2017 Author Report Share Posted September 27, 2017 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. Link to comment Share on other sites More sharing options...
Robert G. Posted September 27, 2017 Author Report Share Posted September 27, 2017 (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 September 27, 2017 by Robert G. add some code Link to comment Share on other sites More sharing options...
cpu20 Posted September 27, 2017 Report Share Posted September 27, 2017 Can you try replacing the file src/gfile/gfile_fatfs_diskio_chibios.c with the one I provided here and test that? gfile_fatfs_diskio_chibios.c Link to comment Share on other sites More sharing options...
inmarket Posted September 27, 2017 Report Share Posted September 27, 2017 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. Link to comment Share on other sites More sharing options...
Robert G. Posted September 28, 2017 Author Report Share Posted September 28, 2017 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; } Link to comment Share on other sites More sharing options...
inmarket Posted September 28, 2017 Report Share Posted September 28, 2017 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. Link to comment Share on other sites More sharing options...
Robert G. Posted September 28, 2017 Author Report Share Posted September 28, 2017 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. Link to comment Share on other sites More sharing options...
cpu20 Posted September 28, 2017 Report Share Posted September 28, 2017 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. Link to comment Share on other sites More sharing options...
inmarket Posted October 2, 2017 Report Share Posted October 2, 2017 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. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now