Unverified Commit 2bf249ff authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Avoid freezeing the core from LWIP under FreeRTOS (#1884)

Avoid issues with interrupts and priority inversions and other deadlocks
and use a SW based random generator for LWIP when under FreeRTOS.

This means removing any overrides for sleep_until and the two
get_rand_xx calls from the SDK, making things much saner.

Related to #1883, #1872, and other random FreeRTOS lockups.
parent 81070a0b
......@@ -252,14 +252,14 @@ If you want to contribute or have bugfixes, drop me a note at <earlephilhower@ya
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporation and licensed under the MIT license.
* Networking and filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
* DHCP server for AP host mode from the [Micropython Project](https://micropython.org), distributed under the MIT License.
* [FreeRTOS](https://freertos.org) is Copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
* [FreeRTOS](https://freertos.org) is copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
* [lwIP](https://savannah.nongnu.org/projects/lwip/) is (c) the Swedish Institute of Computer Science and licenced under the BSD license.
* [BearSSL](https://bearssl.org) library written by Thomas Pornin, is distributed under the [MIT License](https://bearssl.org/#legal-details).
* [UZLib](https://github.com/pfalcon/uzlib) is copyright (c) 2003 Joergen Ibsen and distributed under the zlib license.
* [LEAmDNS](https://github.com/LaborEtArs/ESP8266mDNS) is copyright multiple authors and distributed under the MIT license.
* [http-parser](https://github.com/nodejs/http-parser) is copyright Joyent, Inc. and other Node contributors.
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others.
* [Xoshiro-cpp](https://github.com/Reputeless/Xoshiro-cpp) is copyright (c) 2020 Ryo Suzuki and distributed under the MIT license.
-Earle F. Philhower, III
earlephilhower@yahoo.com
......@@ -60,45 +60,3 @@ SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
}
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);
}
}
}
This diff is collapsed.
......@@ -29,6 +29,7 @@
#include <pico/cyw43_arch.h>
#include <pico/mutex.h>
#include <sys/lock.h>
#include "_xoshiro.h"
extern void ethernet_arch_lwip_begin() __attribute__((weak));
extern void ethernet_arch_lwip_end() __attribute__((weak));
......@@ -68,11 +69,25 @@ public:
extern "C" {
static XoshiroCpp::Xoshiro256PlusPlus *_lwip_rng = nullptr;
// Random number generator for LWIP. Bare metal, use the HW. FreeRTOS, use xoshiro generator to avoid needing to freeze the other core
unsigned long __lwip_rand() {
if (__isFreeRTOS) {
return (unsigned long)(*_lwip_rng)();
} else {
return get_rand_32();
}
}
// Avoid calling lwip_init multiple times
extern void __real_lwip_init();
void __wrap_lwip_init() {
static bool initted = false;
if (!initted) {
if (__isFreeRTOS) {
_lwip_rng = new XoshiroCpp::Xoshiro256PlusPlus(rp2040.getCycleCount());
}
__real_lwip_init();
initted = true;
}
......
......@@ -13,8 +13,8 @@ extern void interrupts();
#define SYS_ARCH_PROTECT(lev) noInterrupts
#define SYS_ARCH_UNPROTECT(lev) interrupts
extern unsigned long get_rand_32(void);
#define LWIP_RAND() get_rand_32()
extern unsigned long __lwip_rand(void);
#define LWIP_RAND() __lwip_rand()
// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
......
No preview for this file type
......@@ -209,7 +209,3 @@
-Wl,--wrap=cyw43_tcpip_link_status
-Wl,--wrap=cyw43_cb_tcpip_init
-Wl,--wrap=cyw43_cb_tcpip_deinit
-Wl,--wrap=get_rand_64
-Wl,--wrap=get_rand_32
-Wl,--wrap=sleep_until
......@@ -13,8 +13,8 @@ extern void interrupts();
#define SYS_ARCH_PROTECT(lev) noInterrupts
#define SYS_ARCH_UNPROTECT(lev) interrupts
extern unsigned long get_rand_32(void);
#define LWIP_RAND() get_rand_32()
extern unsigned long __lwip_rand(void);
#define LWIP_RAND() __lwip_rand()
// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment