2017-11-03 11:53 AM
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:
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.2017-11-03 12:34 PM
I'd assume the problem is the layer below FatFs
2017-11-03 01:38 PM
Do you mean SDIO? If so, why this happened after the update?
2017-11-03 01:57 PM
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.
2017-11-04 04:23 AM
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
2017-11-04 04:55 AM
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!
2017-11-04 05:19 AM
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.
2017-11-05 04:05 AM
/** 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= 800098fAnother 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?
2017-11-08 12:59 PM
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;&sharpendifif(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));&sharpendifbreak;}}}}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));&sharpendifbreak;}}}}return res;}andDRESULT 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 addressadjust 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));&sharpendifif(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
2017-11-08 02:01 PM
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