cancel
Showing results for 
Search instead for 
Did you mean: 

FatFs f_open() fails after upgrading to STM32F4 FW pkg 1.17

Zaher
Senior II
Posted on November 03, 2017 at 19:53

I have two versions of my project exported from the CubeMX, one for the MDK-ARM and the other for the gcc-based Eclipse IDE (AC6). Both projects built with STM32F4 firmware package 1.1.

After upgrading the firmware package to the latest 1.17, generating project files again for the MDK-ARM project, my FatFs is no longer able to open files on medium, (SD card). Everything else is working properly, f_mount() returns without error, until the program calls f_open(), which causes Hard Fault and sometimes returns error 3 (FR_NOT_READY).

I tested the same code in the project I have generated earlier for AC6, everything works flawlessly and the file opened without any problem. Generating the project files with the upgraded FW pkg for AC6 has resulted in the same issue in the other project, too, and again, f_open() is no longer works and the program crash with hard fault.

Initially, I thought it's something related to FreeRTOS, as I have been playing around that option back and forth.

I was wondering if this is a known issue in the 1.17 version of the firmware package, as the release notes mention the following:

    • Update to use FatFS R0.12c ST modified 201707

Could it be a problem with this new version of FatFs adopted in the FW package 1.17?

I'm going to downgrade to 1.1 and rebuild the project and see if that solves the issue.

Thanks,

Zaher

Note: this post was migrated and contained many threaded conversations, some content may be missing.
29 REPLIES 29
Posted on November 03, 2017 at 20:34

I'd assume the problem is the layer below FatFs

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 03, 2017 at 20:38

Do you mean SDIO? If so, why this happened after the update?

Posted on November 03, 2017 at 20:57

The block device (SDIO, SPI, or whatever) needs to work properly. FatFs will pass through media and subsystem errors to you, and is likely to be vulnerable to being passed junk data and acting upon it.

Before you blame FatFs you need to prove/validate the block storage layer. If that is broken no amount of hand waving at the application level is going to fix it.

If you have Hard Faults, debug them, they are gross errors, and the CPU provides a wealth of detail about why it doesn't like something. Make sure your stack is big enough for the code you are running.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 04, 2017 at 11:23

Of course, I'm not blaming FatFs and I know it's independent of the disk I/O layer, and this latter has numerous implementations, ST's initiative is one of them. However, what I wanted to say is, the project configurations generated from CubeMX based on the latest FW pckg 1.17 for STMF4 might be out of phase with the version of FatFs used, or maybe something else is involved. 

The block device (SDIO, SPI, or whatever) needs to work properly

Yes, that's what I meant when I referred to generated code after the update. Otherwise, why the earlier project built with FW pckg 1.13.1 still works flawlessly? And the result was quite the same when I have re-generated the project files from within the upgraded CubeMx with the latest firmware package, without even touching any part of the configurations, project files, or the sources. 

Removing the latest FW pckg and downgrading to an earlier version has made things even worse. The project configuration generated from the 4.17 version of CubeMx doesn't align with FW pckg 1.13.1, or maybe something went wrong in my situation and I have to re-install CubeMx? I ended up with over a dozen of error and undefined symbols and they were all related to the BSP_SD module. 

Now, I have just removed the 1.13 package and downloaded the latest one, 1.17 back again, created a new and clean project from scratch with very simple and basic code in order to test FatFs/SDIO. As expected, f_open() failed with error code number 3 (FR_NOT_READY). 

Stack and heap were both left to default setting, 1024/512.

I will include the MDK-ARM project in a subsequent reply if you want to take a look and see what's going on. 

Thanks again for your fabulous support, boss!

Zaher

Posted on November 04, 2017 at 11:55

Here is my MDK-ARM project:

https://drive.google.com/open?id=0Bw2VIBveePuSRXZwSjZtem95aW8

Please make sure you have SD card module connected in SDIO 4-bit mode, and a file on card before testing! 

Posted on November 04, 2017 at 12:19

I just found a define in the BSP_SD for 'OLD_API' when migrating old projects. Even the HAL/Cube FW package has different and conflicting APIs? We barely moved from SPL to HAL to start struggling with conflicting APIs everytime a new firmware package or CubeMX version is released? That's really confusing and time consuming.

Posted on November 05, 2017 at 12:05

/** An Update **/

I just managed to debug the program and get the results. As expected, the problem lies in the disk I/O layer, diskio.c, and the line that fires the Hard_Fault is the following:

stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);

And here is the result of debugging the Hard_Fault:

[HardFault]

- Stack frame:

R0 = 20000938

R1 = 80001b1

R2 = 8000c4f

R3 = 800098b

R12 = 8000c4d

LR = 800029b

PC = 8000d79

PSR = 0

- FSR/FAR:

CFSR = 20000

HFSR = 40000000

DFSR = 0

AFSR = 0

- Misc

LR/EXC_RETURN= 800098f

Another thing is, I'm not sure how the diskio initializes the SD card module in the new API. The bsp_driver_sd.c and BSP_SD_Init() are both still there, however, I do not see any reference to the BSP_SD_Init() in the new API across the entire project. Then where the SD card is being initialized in this new API? 

From the old working API in another project, the sd_diskio.c has the following initialize function:

DSTATUS SD_initialize(BYTE lun)

{

Stat = STA_NOINIT;

/* Configure the uSD device */

if(BSP_SD_Init() == MSD_OK)

{

Stat &= ~STA_NOINIT;

}

return Stat;

}

But, in the new API, it looks like this:

DSTATUS SD_initialize(BYTE lun)

{

return SD_CheckStatus(lun);

}

Could someone please explain to me how that is supposed to work? 

Posted on November 08, 2017 at 20:59

Hi,

i'm working to found the problem, and now work, but some bugs are present inside library,

Please try to put this:

DSTATUS SD_initialize(BYTE lun)

{

Stat = STA_NOINIT;

/* Configure the uSD device */

if(BSP_SD_Init() == MSD_OK)

{

Stat &= ~STA_NOINIT;

}

return Stat;

}

but the big problem is inside the file 'sd_diskio.c', on functions 'SD_read' and 'SD_write'.

I don't know exactly what are tryng to make, but i see

1) static osMessageQId SDQueueID; >> but no creation of queue

so when the code reach this line

event = osMessageGet(SDQueueID, SD_TIMEOUT);

you will have ever this result 'osErrorParameter' because the handle of SDQueueID is NULL.

Create it not help you because the callback functions to insert the event on the queue are not linked from dma.

Now i have put this very POOR fix to solve it quickly, but i wait a best solution from someone.

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)

{

DRESULT res = RES_ERROR;

osEvent event;

uint32_t timer;

&sharpif (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

uint32_t alignedAddr;

&sharpendif

if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,

(uint32_t) (sector),

count) == MSD_OK)

{

/* wait for a message from the queue or a timeout */

event = osMessageGet(SDQueueID, SD_TIMEOUT);

if (event.status == osEventMessage)

{

if (event.value.v == READ_CPLT_MSG)

{

timer = osKernelSysTick() + SD_TIMEOUT;

/* block until SDIO IP is ready or a timeout occur */

while(timer > osKernelSysTick())

{

if (BSP_SD_GetCardState() == SD_TRANSFER_OK)

{

res = RES_OK;

&sharpif (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

/*

the SCB_InvalidateDCache_by_Addr() requires a 32-Bit aligned address,

adjust the address and the D-Cache size to invalidate accordingly.

*/

alignedAddr = (uint32_t)buff & ~3;

SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

&sharpendif

break;

}

}

}

}

else // myfix porco dio maledetti bastardi !

{

timer = osKernelSysTick() + SD_TIMEOUT;

/* block until SDIO IP is ready or a timeout occur */

while(timer > osKernelSysTick())

{

if (BSP_SD_GetCardState() == SD_TRANSFER_OK)

{

res = RES_OK;

&sharpif (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

/*

the SCB_InvalidateDCache_by_Addr() requires a 32-Bit aligned address,

adjust the address and the D-Cache size to invalidate accordingly.

*/

alignedAddr = (uint32_t)buff & ~3;

SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

&sharpendif

break;

}

}

}

}

return res;

}

and

DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)

{

DRESULT res = RES_ERROR;

osEvent event;

uint32_t timer;

&sharpif (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

uint32_t alignedAddr;

/*

the SCB_CleanDCache_by_Addr() requires a 32-Bit aligned address

adjust the address and the D-Cache size to clean accordingly.

*/

alignedAddr = (uint32_t)buff & ~3;

SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

&sharpendif

if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,

(uint32_t) (sector),

count) == MSD_OK)

{

/* Get the message from the queue */

event = osMessageGet(SDQueueID, SD_TIMEOUT);

if (event.status == osEventMessage)

{

if (event.value.v == WRITE_CPLT_MSG)

{

timer = osKernelSysTick() + SD_TIMEOUT;

/* block until SDIO IP is ready or a timeout occur */

while(timer > osKernelSysTick())

{

if (BSP_SD_GetCardState() == SD_TRANSFER_OK)

{

res = RES_OK;

break;

}

}

}

}

else // myfix porco dio

{

timer = osKernelSysTick() + SD_TIMEOUT;

while(timer > osKernelSysTick())

{

if (BSP_SD_GetCardState() == SD_TRANSFER_OK)

{

res = RES_OK;

break;

}

}

}

}

return res;

}

Sorry for my english and 'code allignment '

Bye bye

Posted on November 08, 2017 at 22:01

Hi Marco,

Thank you very much for your reply. I created a new project with the bare minimum modules, no RTOS, just to confirm if the problem lies in the library or somewhere in my code, but to my astonishment, the fault was the library itself. Now, while I'm also waiting to hear from Mr. Clive or someone else who might help solve it, all I want is to get back to FW package I had before that regrettable update, 1.13.1. The problem is, the CubeMx version I have now, latest version, generate project defines and configurations incompatible with that FW package. 

I was wondering if someone knows where I can get an earlier version of the STM32CubeMx. 

Thanks,

Zaher