aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2024-05-09 15:18:51 +0200
committerlonkaars <loek@pipeframe.xyz>2024-05-09 15:18:51 +0200
commit21bfc93676c56e2265f330170d319da2c480987d (patch)
tree78caa1526cf0c570118d893e52df3301eb9e02a8
parentefc9870fb1ddd286954fc056b79dddf39f68353a (diff)
working FreeRTOS + lwIP blink/wifi connect example again
-rw-r--r--main/init.cpp30
-rw-r--r--main/init.h35
-rw-r--r--main/main.cpp27
3 files changed, 76 insertions, 16 deletions
diff --git a/main/init.cpp b/main/init.cpp
index 425f591..48f3774 100644
--- a/main/init.cpp
+++ b/main/init.cpp
@@ -1,9 +1,15 @@
#include "config.h"
#include "init.h"
+#include <FreeRTOS.h>
+#include <task.h>
+#include <event_groups.h>
+
#include <pico/stdio.h>
#include <pico/cyw43_arch.h>
+EventGroupHandle_t init_complete;
+
static void init_stdio() {
stdio_init_all();
}
@@ -20,13 +26,29 @@ static void init_wifi() {
if (cyw43_arch_wifi_connect_timeout_ms(CONF_NET_SSID, CONF_NET_PASS, CYW43_AUTH_WPA2_AES_PSK, CONF_NET_CONN_TIMEOUT))
panic("cyw43_arch_wifi_connect failed\n");
- // TODO: announce hostname
+ // TODO: announce hostname(?)
}
void init() {
+ init_complete = xEventGroupCreate();
+
+ // used for debug `printf` and `panic` on errors
init_stdio();
- init_cyw34();
- init_wifi();
- // TODO: initialize i2c
+
+ // defer other initialization until the task scheduler is running (important)
+ xTaskCreate((TaskFunction_t) [](void*) {
+ init_cyw34();
+ init_wifi();
+ // TODO: initialize i2c
+
+ xEventGroupSetBits(init_complete, 1);
+
+ // delete self
+ vTaskDelete(NULL);
+ }, "init", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, NULL);
+}
+
+void await_init() {
+ xEventGroupWaitBits(init_complete, 1, pdFALSE, pdFALSE, portMAX_DELAY);
}
diff --git a/main/init.h b/main/init.h
index 1f931dc..97b2e20 100644
--- a/main/init.h
+++ b/main/init.h
@@ -1,5 +1,38 @@
#pragma once
-/** @brief initialize all peripherals on the pico */
+#include <FreeRTOS.h>
+#include <event_groups.h>
+
+/**
+ * @brief init function complete event group handle
+ *
+ * This is required to make sure the main task waits until initialization is
+ * complete. Due to the combination of FreeRTOS + lwIP, the initialization
+ * should be done while the task scheduler is running. Specifically the
+ * cyw43_arch_init functions make the pico hang indefinitely when used while
+ * the task scheduler is not running.
+ *
+ * @note `init_complete` only utilizes LSB, so `uxBitsToWaitFor` should always
+ * be set to *1*
+ */
+extern EventGroupHandle_t init_complete;
+
+/**
+ * @brief initialize all peripherals on the pico
+ *
+ * This function only synchronously initializes the standard input/output (used
+ * for `printf` and `panic`), and queues all other types of initialization in
+ * the `init` task using FreeRTOS.
+ *
+ * @note Tasks dependent on the wifi being initialized should use the
+ * `init_complete` event group to wait for initialization to complete!
+ */
void init();
+/**
+ * @brief block task until all initialization is complete
+ *
+ * utility function, see above comments
+ */
+void await_init();
+
diff --git a/main/main.cpp b/main/main.cpp
index ace9f01..c97a808 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -7,11 +7,13 @@
#include "config.h"
#include "init.h"
-#include <lwip/sockets.h>
-#include <lwip/sys.h>
-#include <lwip/opt.h>
+// #include <lwip/sockets.h>
+// #include <lwip/sys.h>
+// #include <lwip/opt.h>
void blink_task() {
+ await_init(); // `blink_task` uses GPIO
+
while (true) {
cyw43_arch_gpio_put(LED_PIN, 0);
vTaskDelay(250 / portTICK_PERIOD_MS);
@@ -20,18 +22,21 @@ void blink_task() {
}
}
+void test_task() {
+ int i = 0;
+ while (true) {
+ // stdio is initialized synchronously, so no `await_init` is needed
+ printf("hello #%d...\n", ++i);
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
+ }
+}
+
int main() {
init();
- for (int i = 5; i > 0; i--) {
- printf("starting in %d...\n", i);
- sleep_ms(1000);
- }
-
- // this should compile but not work
- lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ xTaskCreate((TaskFunction_t) blink_task, "blink", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
+ xTaskCreate((TaskFunction_t) test_task, "test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
- xTaskCreate((TaskFunction_t) blink_task, "blink", 128, NULL, 1, NULL);
vTaskStartScheduler();
}