I'm implementing SD card hot-plug functionality in a Zephyr RTOS application. My workflow for managing the SD card involves the following Zephyr APIs:
Initialization/Insertion:
disk_access_ioctl(DISK_DRIVE_NAME, DISK_IOCTL_CTRL_INIT, NULL)
fs_mount(&mp)
Removal:
fs_unmount(&mp)
Problem Description:
When an SD card is inserted for the first time or on power-up, the sequence of disk_access_ioctl(DISK_IOCTL_CTRL_INIT)
followed by fs_mount()
works perfectly.
However, if I remove the SD card (triggering fs_unmount()
) and then re-insert it, the re-initialization (disk_access_ioctl(DISK_IOCTL_CTRL_INIT)
) succeeds, but the subsequent fs_mount()
call fails consistently with an EIO
(-5) error. The relevant log output is:
<err> sd: Failed to read from SDMMC -5
<err> sd: Card read failed
<err> fs: fs mount error (-5)
My understanding, based on the Zephyr documentation (e.g., the general usage of fs_unmount
and the disk_access
API), is that fs_unmount()
should sufficiently deinitialize or prepare the disk for a future re-mount. There doesn't appear to be a DISK_IOCTL_CTRL_DEINIT
explicitly documented or commonly used that would be called after fs_unmount
.
Additional Observation (if I were to hypothetically force deinitialization):
If I manually deinit using disk_access_ioctl
(assuming a DEINIT
equivalent existed or by trying other IOCTLs that might reset the state), within a k_work
item scheduled on the system workqueue, it causes that k_work
item to become permanently blocked or never complete its execution after the first removal.
My questions are:
fs_unmount
'ed and then re-inserted?disk_access_ioctl(DISK_IOCTL_CTRL_INIT)
succeed on re-insertion, but fs_mount()
subsequently fail with EIO
? What internal states or resources might be improperly released or re-initialized?disk_access_ioctl
commands or other driver-level considerations that are necessary for a clean SD card "eject" and re-insertion cycle in Zephyr that are not immediately obvious from fs_unmount
's description?Any insights into successfully managing SD card hot-plugging in Zephyr, specifically regarding reliable re-mounting after unmounting, would be greatly appreciated.
This issue was resolved here: https://devzone.nordicsemi.com/f/nordic-q-a/123400/zephyr-sd-card-remount-issue-fs_unmount-vs-disk-deinitialization-leading-to-eio-or-blocked-workqueue
I was able to solve it with these steps:
1. Did not use either of the following:
disk_access_ioctl("SD", DISK_IOCTL_CTRL_INIT, NULL);
disk_access_ioctl("SD", DISK_IOCTL_CTRL_DEINIT, NULL);
Earlier I would init the disk, mount, (do stuff) and then on pin triggered removal of SD card unmount and deinit. It seems I need to remove the init/deinit them altogether or deinit right after init if I need to access any parameters using the disk_access_ioctl command.
2. Even with the above solution for some reason everything would get blocked after at unmount. This was resolved once I moved to a lower priority workqueue. I was using the system workqueue before and it would block forever.