Skip to content

Commit 651d596

Browse files
Allow FreeRTOS to ::printf (#1195)
The stdin/stdout FILEs have an internal mutex which needs to be initted to a FreeRTOS one, or any sketch with ::printf will hang. Automatically create and acquire/release the shadowed mutex. Requires new build of pico-quick-toolchain to function properly. Tested on preliminary local build.
1 parent 75bab41 commit 651d596

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

cores/rp2040/_freertos.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef struct {
2828
} FMMap;
2929

3030
static FMMap *_map = nullptr;
31-
extern "C" SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m) {
31+
SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
3232
if (!_map) {
3333
_map = (FMMap *)calloc(sizeof(FMMap), 16);
3434
}
@@ -42,7 +42,12 @@ extern "C" SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m) {
4242
for (int i = 0; i < 16; i++) {
4343
if (_map[i].src == nullptr) {
4444
// Make a new mutex
45-
SemaphoreHandle_t fm = __freertos_mutex_create();
45+
SemaphoreHandle_t fm;
46+
if (recursive) {
47+
fm = _freertos_recursive_mutex_create();
48+
} else {
49+
fm = __freertos_mutex_create();
50+
}
4651
if (fm == nullptr) {
4752
return nullptr;
4853
}

cores/rp2040/_freertos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ extern "C" {
5959
extern void vTaskPreemptionEnable(TaskHandle_t p) __attribute__((weak));
6060
#endif
6161

62-
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m);
6362
}
63+
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive = false);
6464

6565
// Halt the FreeRTOS PendSV task switching magic
6666
extern "C" int __holdUpPendSV;

cores/rp2040/lock.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static SemaphoreHandle_t __getFreeRTOSMutex(_LOCK_T lock) {
8080
} else if (l == &__lock___arc4random_mutex) {
8181
return __lock___arc4random_mutex_freertos;
8282
}
83-
return nullptr;
83+
return __get_freertos_mutex_for_ptr(l, false);
8484
}
8585

8686
static SemaphoreHandle_t __getFreeRTOSRecursiveMutex(_LOCK_T lock) {
@@ -96,20 +96,32 @@ static SemaphoreHandle_t __getFreeRTOSRecursiveMutex(_LOCK_T lock) {
9696
} else if (l == &__lock___env_recursive_mutex) {
9797
return __lock___env_recursive_mutex_freertos;
9898
}
99-
return nullptr;
99+
return __get_freertos_mutex_for_ptr((mutex_t *)l, true);
100100
}
101101

102102
void __retarget_lock_init(_LOCK_T *lock) {
103103
if (__freeRTOSinitted) {
104-
/* Already done in initFreeRTOSMutexes() */
104+
mutex_t *l = (mutex_t *)lock;
105+
if ((l == &__lock___at_quick_exit_mutex) || (l == &__lock___tz_mutex) || (l == &__lock___dd_hash_mutex) || (l == &__lock___arc4random_mutex)) {
106+
/* Already done in initFreeRTOSMutexes() */
107+
} else {
108+
// Will init the mutex as well
109+
__get_freertos_mutex_for_ptr(l, false);
110+
}
105111
} else {
106112
mutex_init((mutex_t*) lock);
107113
}
108114
}
109115

110116
void __retarget_lock_init_recursive(_LOCK_T *lock) {
111117
if (__freeRTOSinitted) {
112-
/* Already done in initFreeRTOSMutexes() */
118+
recursive_mutex_t *l = (recursive_mutex_t *)lock;
119+
if ((l == &__lock___sinit_recursive_mutex) || (l == &__lock___sfp_recursive_mutex) || (l == &__lock___atexit_recursive_mutex) || (l == &__lock___malloc_recursive_mutex) || (l == &__lock___env_recursive_mutex)) {
120+
/* Already done in initFreeRTOSMutexes() */
121+
} else {
122+
// Will init the mutex as well
123+
__get_freertos_mutex_for_ptr((mutex_t *)l, true);
124+
}
113125
} else {
114126
recursive_mutex_init((recursive_mutex_t*) lock);
115127
}

0 commit comments

Comments
 (0)