Skip to content

Commit 04f0ac6

Browse files
CopilotJohnAmadis
andcommitted
Add pre-RTOS Dmod_Mutex_New guard via --wrap to fix VFS mounts
The dmosi bridge provides a strong Dmod_Mutex_New that creates a FreeRTOS mutex using pvPortMalloc+xSemaphoreCreateRecursiveMutex even before the scheduler starts. Mutex creation succeeds but locking returns -ENOTSUP pre-RTOS, causing all three dmvfs_mount_fs calls to fail with "Failed to lock DMVFS mutex". This prevents board modules (dmgpio, dmclk, dmdevfs) from loading, blocking crash reproduction. Fix: src/arch/armv7/dmod_mutex.c wraps Dmod_Mutex_New via -Wl,--wrap=Dmod_Mutex_New. The wrapper returns NULL when !dmosi_is_started() so dmvfs falls back to Dmod_EnterCritical/ ExitCritical (interrupt-disable critical sections). After vTaskStartScheduler the wrapper forwards to the real implementation. src/arch/armv7/CMakeLists.txt: add dmod_mutex.c to dmboot_arch and propagate -Wl,--wrap=Dmod_Mutex_New to the firmware link via INTERFACE. Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com>
1 parent eda6751 commit 04f0ac6

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

src/arch/armv7/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
# ======================================================================
44
add_library(dmboot_arch STATIC
55
dmod_critical.c
6+
dmod_mutex.c
67
)
78

89
target_link_libraries(dmboot_arch
910
PRIVATE
1011
dmod
1112
)
1213

14+
# Wrap Dmod_Mutex_New so the pre-RTOS guard is applied to all callers
15+
# (e.g. dmvfs) that are linked into the final firmware image.
16+
target_link_options(dmboot_arch INTERFACE -Wl,--wrap=Dmod_Mutex_New)
17+
1318
add_subdirectory(${DMBOOT_ARCH_FAMILY})

src/arch/armv7/dmod_mutex.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @brief Pre-RTOS guard for Dmod_Mutex_New (ARMv7-M)
3+
*
4+
* The dmosi bridge library provides a strong Dmod_Mutex_New that calls
5+
* dmosi_mutex_create(), which in turn calls pvPortMalloc() +
6+
* xSemaphoreCreateRecursiveMutex(). Both succeed before vTaskStartScheduler()
7+
* because FreeRTOS heap allocation does not require the scheduler. However,
8+
* dmosi_mutex_lock() returns -ENOTSUP when !dmosi_is_started(), so any caller
9+
* that obtains a non-NULL mutex handle before the scheduler starts and then
10+
* tries to lock it will fail.
11+
*
12+
* This wrapper (enabled via -Wl,--wrap=Dmod_Mutex_New) returns NULL when the
13+
* scheduler has not yet been started. NULL causes callers such as dmvfs to
14+
* fall back to Dmod_EnterCritical / Dmod_ExitCritical (interrupt-disable
15+
* critical sections), which work correctly both before and after RTOS start.
16+
*
17+
* After vTaskStartScheduler() the wrapper forwards to the real implementation
18+
* so proper recursive RTOS mutexes are created as usual.
19+
*/
20+
21+
#include <stdbool.h>
22+
23+
/* Resolved at link time from dmosi_freertos */
24+
extern bool dmosi_is_started(void);
25+
26+
/* The real (unwrapped) symbol comes from the dmosi bridge library */
27+
extern void* __real_Dmod_Mutex_New(bool Recursive);
28+
29+
void* __wrap_Dmod_Mutex_New(bool Recursive)
30+
{
31+
if (!dmosi_is_started())
32+
{
33+
return NULL;
34+
}
35+
return __real_Dmod_Mutex_New(Recursive);
36+
}

0 commit comments

Comments
 (0)