FRDM-K66F microSD f_opendir never returns: stuck in SDMMC_OSAEventWait

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FRDM-K66F microSD f_opendir never returns: stuck in SDMMC_OSAEventWait

Jump to solution
856 Views
aaronm
Contributor III

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:

Thread #1 57005 (Suspended : Breakpoint)
OSA_SemaphoreWait() at fsl_os_abstraction_bm.c:584 0x616e
SDMMC_OSAEventWait() at fsl_sdmmc_osa.c:69 0x3268
SDMMCHOST_TransferFunction() at fsl_sdmmc_host.c:299 0x8524
SD_SendScr() at fsl_sd.c:814 0x16e0
sdcard_init() at fsl_sd.c:2,033 0x2cbe
SD_CardInit() at fsl_sd.c:2,085 0x2d96
SD_Init() at fsl_sd.c:2,268 0x307a
sd_disk_initialize() at fsl_sd_disk.c:145 0x374c
disk_initialize() at diskio.c:117 0x87ba
mount_volume() at ff.c:3,376 0x3c02
f_opendir() at ff.c:4,544 0x953c
prepareSDForWrite() at MK66F18_Van_Gizmo_v02.c:340 0xa9a
measureAccelerometer() at MK66F18_Van_Gizmo_v02.c:353 0xaee
main() at MK66F18_Van_Gizmo_v02.c:416 0xc8c
 
How can I get either the timeout value to decrease, while time is physically passing, or get the semaphore count increased so the loop continues to work properly until f_opendir() completes?
 
Also, here's a shot of the g_sd variable, at the time it enters the endless loop:
0 Kudos
Reply
1 Solution
802 Views
aaronm
Contributor III

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.

View solution in original post

0 Kudos
Reply
4 Replies
830 Views
Joey_z
NXP Employee
NXP Employee

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.

XuZhang_0-1720425194756.png

XuZhang_1-1720425207689.png

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.

XuZhang_2-1720425294428.png

I have attached the program, I hope this can help you.

BR

XuZhang

0 Kudos
Reply
803 Views
aaronm
Contributor III

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.

0 Kudos
Reply
815 Views
aaronm
Contributor III
Can I ask what kind of SD card you used? And how was it formatted: ExFAT, or MS-DOS / FAT? I know it shouldn't matter, but I'm seeing different results in the same code if I use different SD cards. The one that fails with ACMD51, is a 2GB Lexar formatted as FAT-32; and the other is a 64GB SanDisk formatted as ExFAT. That one fails at SD_AllSendCid() line 2005, in sdcard_init() / fsl_sd.c.
0 Kudos
Reply
841 Views
aaronm
Contributor III

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?

0 Kudos
Reply