Protect the HW random generation from FreeRTOS (#1395)
Fixes #1394 The Pico_Rand SDK calls gather bits from the HW ROSC at precise intervals. If there is jitter in the sleep_until() call then the ROSC bit collection will always think it's failed to acquire the right bit and retry infintitely. Avoid by wrapping the HW random number calls and the sleep_until() routine. Only when in FreeRTOS set a flag to silently make sleep_until() into a busy wait loop while in a random number generation step. When not in the random code, do the normal sleep_until call.
This commit is contained in:
parent
5a949443a5
commit
01ee673dc2
3 changed files with 48 additions and 1 deletions
|
|
@ -21,6 +21,7 @@
|
||||||
#include "_freertos.h"
|
#include "_freertos.h"
|
||||||
#include "pico/mutex.h"
|
#include "pico/mutex.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mutex_t *src;
|
mutex_t *src;
|
||||||
|
|
@ -59,3 +60,45 @@ SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
|
||||||
}
|
}
|
||||||
return nullptr; // Need to make space for more mutex maps!
|
return nullptr; // Need to make space for more mutex maps!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The HW Random code needs a precise sleep_until() in order to assure it
|
||||||
|
// grabs the ROSC bit when it wants. Unfortunately, under FreeRTOS the
|
||||||
|
// sleep_until() becomes imprecise and the "did I get the bit when I wanted"
|
||||||
|
// check in the pico_rand code always fails and you get an infinite loop.
|
||||||
|
|
||||||
|
// This block wraps the 2 get_rand calls to set a flag to convert
|
||||||
|
// sleep_until() (which can do a task swap and cause bad timing) into a
|
||||||
|
// busy wait.
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static bool __inRand = false;
|
||||||
|
|
||||||
|
extern uint64_t __real_get_rand_64();
|
||||||
|
uint64_t __wrap_get_rand_64() {
|
||||||
|
if (__isFreeRTOS) {
|
||||||
|
rp2040.idleOtherCore();
|
||||||
|
__inRand = true;
|
||||||
|
auto r = __real_get_rand_64();
|
||||||
|
__inRand = false;
|
||||||
|
rp2040.resumeOtherCore();
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return __real_get_rand_64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t __wrap_get_rand_32() {
|
||||||
|
return (uint32_t) __wrap_get_rand_64();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void __real_sleep_until(absolute_time_t t);
|
||||||
|
void __wrap_sleep_until(absolute_time_t t) {
|
||||||
|
if (__inRand) {
|
||||||
|
busy_wait_until(t);
|
||||||
|
} else {
|
||||||
|
__real_sleep_until(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,3 +207,7 @@
|
||||||
-Wl,--wrap=cyw43_tcpip_link_status
|
-Wl,--wrap=cyw43_tcpip_link_status
|
||||||
-Wl,--wrap=cyw43_cb_tcpip_init
|
-Wl,--wrap=cyw43_cb_tcpip_init
|
||||||
-Wl,--wrap=cyw43_cb_tcpip_deinit
|
-Wl,--wrap=cyw43_cb_tcpip_deinit
|
||||||
|
|
||||||
|
-Wl,--wrap=get_rand_64
|
||||||
|
-Wl,--wrap=get_rand_32
|
||||||
|
-Wl,--wrap=sleep_until
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S ./libraries/SingleF
|
||||||
./libraries/Updater ./libraries/HTTPClient ./libraries/HTTPUpdate \
|
./libraries/Updater ./libraries/HTTPClient ./libraries/HTTPUpdate \
|
||||||
./libraries/WebServer ./libraries/HTTPUpdateServer ./libraries/DNSServer \
|
./libraries/WebServer ./libraries/HTTPUpdateServer ./libraries/DNSServer \
|
||||||
./libraries/Joystick ./libraries/Keyboard ./libraries/Mouse \
|
./libraries/Joystick ./libraries/Keyboard ./libraries/Mouse \
|
||||||
./libraries/JoystickBT ./libraries/KeyboardBT ./variants ./libraries/BTstack \
|
./libraries/JoystickBT ./libraries/KeyboardBT ./variants ./libraries/BTstackLib \
|
||||||
./libraries/MouseBT ./libraries/SerialBT ./libraries/HID_Bluetooth \
|
./libraries/MouseBT ./libraries/SerialBT ./libraries/HID_Bluetooth \
|
||||||
./libraries/JoystickBLE ./libraries/KeyboardBLE ./libraries/MouseBLE ; do
|
./libraries/JoystickBLE ./libraries/KeyboardBLE ./libraries/MouseBLE ; do
|
||||||
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
|
find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue