diff --git a/cores/arduino/CMakeLists.txt b/cores/arduino/CMakeLists.txt index 49b0e645..dc077db1 100644 --- a/cores/arduino/CMakeLists.txt +++ b/cores/arduino/CMakeLists.txt @@ -19,6 +19,7 @@ zephyr_sources(api/String.cpp) if(DEFINED CONFIG_ARDUINO_ENTRY) zephyr_sources(main.cpp) +zephyr_sources(threads.cpp) endif() endif() diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index dff4d605..ee68b238 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -9,10 +9,19 @@ #include #endif +#ifdef CONFIG_MULTITHREADING +void start_static_threads(); +#endif + int main(void) { #if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) Serial.begin(115200); #endif + +#ifdef CONFIG_MULTITHREADING + start_static_threads(); +#endif + setup(); for (;;) { diff --git a/cores/arduino/threads.cpp b/cores/arduino/threads.cpp new file mode 100644 index 00000000..99a4a141 --- /dev/null +++ b/cores/arduino/threads.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "Arduino.h" + +#ifdef CONFIG_MULTITHREADING +void start_static_threads() { + #define _FOREACH_STATIC_THREAD(thread_data) \ + STRUCT_SECTION_FOREACH(_static_thread_data, thread_data) + + _FOREACH_STATIC_THREAD(thread_data) { + k_thread_create(thread_data->init_thread, thread_data->init_stack, thread_data->init_stack_size, thread_data->init_entry, + thread_data->init_p1, thread_data->init_p2, thread_data->init_p3, thread_data->init_prio, + thread_data->init_options, thread_data->init_delay); + k_thread_name_set(thread_data->init_thread, thread_data->init_name); + thread_data->init_thread->init_data = thread_data; + } + + /* + * Take a sched lock to prevent them from running + * until they are all started. + */ + k_sched_lock(); + _FOREACH_STATIC_THREAD(thread_data) { + k_thread_start(thread_data->init_thread); + } + k_sched_unlock(); +} +#endif \ No newline at end of file diff --git a/loader/llext_exports.c b/loader/llext_exports.c index f427ccbc..2fca0199 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -48,6 +48,8 @@ EXPORT_SYMBOL(isupper); EXPORT_SYMBOL(islower); EXPORT_SYMBOL(isxdigit); +EXPORT_SYMBOL(k_sched_lock); +EXPORT_SYMBOL(k_sched_unlock); #if defined(CONFIG_USB_DEVICE_STACK) EXPORT_SYMBOL(usb_enable); diff --git a/variants/llext/linker_script.ld b/variants/llext/linker_script.ld index e9e89a42..47d35365 100644 --- a/variants/llext/linker_script.ld +++ b/variants/llext/linker_script.ld @@ -34,6 +34,10 @@ SECTIONS { KEEP (*(.ctors)) KEEP (*(.dtors)) KEEP (*(.fini)) + + __static_thread_data_list_start = .; + KEEP(*(SORT_BY_NAME(.__static_thread_data.static.*))); + __static_thread_data_list_end = .; } .rodata : {