Board: FRDM-K66F. SDK: 2.11.0 (541 2022-01-14)
I'm using the SD library to read and write files to an SD card.
I'm using "baremetal" instead of an RTOS; I mention this because the definition for KOSA_StatusIdle says:
KOSA_StatusIdle = MAKE_STATUS(kStatusGroup_OSA, 3), /*!< Used for bare metal only, the wait object is not ready and timeout still not occur */
My program is trying to f_opendir(), after verifying that the card exists, successful calls to f_mount(), and f_chdrive(), and it's hanging in this function:
status_t SDMMC_OSAEventWait(void *eventHandle, uint32_t eventType, uint32_t timeoutMilliseconds, uint32_t *event)
{
assert(eventHandle != NULL);
osa_status_t status = KOSA_StatusError;
#if defined(SDMMC_OSA_POLLING_EVENT_BY_SEMPHORE) && SDMMC_OSA_POLLING_EVENT_BY_SEMPHORE
while (true)
{
status = OSA_SemaphoreWait(&(((sdmmc_osa_event_t *)eventHandle)->handle), timeoutMilliseconds);
if (KOSA_StatusTimeout == status)
{
break;
}
if (KOSA_StatusSuccess == status)
{
(void)SDMMC_OSAEventGet(eventHandle, eventType, event);
if ((*event & eventType) != 0U)
{
return kStatus_Success;
}
}
}
#endif
return kStatus_Fail;
}
This while() loop never exits because "timeoutMilliseconds" never decreases - the value passed in is a define: SDMMCHOST_TRANSFER_COMPLETE_TIMEOUT, rather than a variable - which might eventually lead to a time out, and the loop condition doesn't check for KOSA_StatusIdle. Before the point at which the program hangs, the semaphore is evidently properly created and removed: I've followed the semaphore value as it's increased and decreased in the Expression panel. However, at some point, OSA_SemaphorePost() is no longer called, so semCount isn't increased, and OSA_SemaphoreWait() just keeps returning KOSA_StatusIdle.
Here's the call stack when it's stuck in this loop:
已解决! 转到解答。
XuZhang,
I ran my copy of the sdcard_fatfs example program, which is probably identical to what you posted, and it did work, curiously, and when I added the "PRINTF" statements to the SDK example for the semaphore waits, the output looked similar to yours. Puzzling.
I then went through all of the files in the two projects to see if the SDKs were somehow different: they were not.
I checked the pull-up and pull-down statuses in the Pins perspective: the SDK example manually sets them "pull-up," and mine were "ignore." I changed mine, but it didn't make a difference.
I checked the clock configuration - maybe a system clock of 120MHz was incorrect for the SD card; I dunno - and that had no change.
Finally, since I couldn't find any other differences, I added the SYSMPU SDK module and the call to SYSMPU_Enable(SYSMPU, false); in the main initialization block. That did it. My semaphore counts were increasing and decreasing as in your example, and f_opendir() returned successfully. I've no idea what SYSMPU does, and I haven't seen it before when dealing with the FRDMK66 board, but that was the trick, evidently. I'm marking this as "solved."
Thanks for your help.
Hi , aaronm
I experimented with the MK66FN2M0xxx18 development board and the "frdmk66f_sdcard_fatfs" program in the SDK. It didn't seem to hang in SDMMC_OSAEventWait. I tried to print out the values of timeoutMilliseconds and semCount and found that the value of semCount was changing, and the return value of the OSA_SemaphoreWait() function was KOSA_StatusSuccess.
The location of adding the test output function is as shown below.
I can see the output results as shown in this figure, which outputs the values of timeoutMilliseconds and semCount during the program execution, and creates files in the SD card.
I have attached the program, I hope this can help you.
BR
XuZhang
XuZhang,
I ran my copy of the sdcard_fatfs example program, which is probably identical to what you posted, and it did work, curiously, and when I added the "PRINTF" statements to the SDK example for the semaphore waits, the output looked similar to yours. Puzzling.
I then went through all of the files in the two projects to see if the SDKs were somehow different: they were not.
I checked the pull-up and pull-down statuses in the Pins perspective: the SDK example manually sets them "pull-up," and mine were "ignore." I changed mine, but it didn't make a difference.
I checked the clock configuration - maybe a system clock of 120MHz was incorrect for the SD card; I dunno - and that had no change.
Finally, since I couldn't find any other differences, I added the SYSMPU SDK module and the call to SYSMPU_Enable(SYSMPU, false); in the main initialization block. That did it. My semaphore counts were increasing and decreasing as in your example, and f_opendir() returned successfully. I've no idea what SYSMPU does, and I haven't seen it before when dealing with the FRDMK66 board, but that was the trick, evidently. I'm marking this as "solved."
Thanks for your help.
Further info:
This is locking up in sdcard_init() -> SD_SendScr(), or when we run SD command ACMD51, Read the SD Configuration Register (SCR). When I stepped through the commands from SD_SendSCR(), I notice it doesn't trigger an SDHC interrupt, like the previous commands, such as SD_SendRca(), or SD_SendCsd(). These function trigger interrupts, which is where the semaphore counter is increased before reaching SDMMC_OSAEventWait().
What is the problem with SD_SendScr()?
Just in case it matters, I'm not specifically using DMA in this application. Does that make a difference?