Skip to content

Commit

Permalink
zephyr: Add threading support.
Browse files Browse the repository at this point in the history
This commit implements the `_thread` module on the zephyr port.

Due to the fact that we are still using a rather old version of Zephyr,
`CONFIG_DYNAMIC_THREAD` is not available and therefore the stack for
threads cannot be allocated dynamically, only at compile time.  So for the
time being and for the purpose of this commit, a maximum of 4 Zephyr
threads (besides the main thread) can be created.  Once we manage to update
to the latest version of Zephyr this won't be a problem anymore.

Configuration for the nrf52840dk is added as part of this change, because
this board was used to test the threading support.

The Zephyr option `CONFIG_THREAD_CUSTOM_DATA` is used to enable threading
on a per board basis.  The `thread.conf` file is added as a convenient way
to enable threading.

Signed-off-by: danicampora <[email protected]>
  • Loading branch information
danicampora authored and dpgeorge committed Sep 6, 2024
1 parent aefd48b commit 6833f3d
Show file tree
Hide file tree
Showing 9 changed files with 419 additions and 3 deletions.
1 change: 1 addition & 0 deletions ports/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ set(MICROPY_SOURCE_PORT
mphalport.c
uart_core.c
zephyr_storage.c
mpthreadport.c
)
list(TRANSFORM MICROPY_SOURCE_PORT PREPEND ${MICROPY_PORT_DIR}/)

Expand Down
5 changes: 5 additions & 0 deletions ports/zephyr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ To build for QEMU instead:

$ west build -b qemu_x86 ~/micropython/ports/zephyr

To build any board with the `_thread` module enabled,
add `-DOVERLAY_CONFIG=thread.conf`, for instance:

$ west build -b frdm_k64f ~/micropython/ports/zephyr -DOVERLAY_CONFIG=thread.conf

Consult the Zephyr documentation above for the list of
supported boards. Board configuration files appearing in `ports/zephyr/boards/`
correspond to boards that have been tested with MicroPython and may have
Expand Down
13 changes: 13 additions & 0 deletions ports/zephyr/boards/nrf52840dk_nrf52840.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_NETWORKING=n
CONFIG_BT=y
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y

CONFIG_MICROPY_HEAP_SIZE=98304
CONFIG_MAIN_STACK_SIZE=8192

# CONFIG_DYNAMIC_THREAD=y
CONFIG_THREAD_CUSTOM_DATA=y
CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_STACK_INFO=y
23 changes: 20 additions & 3 deletions ports/zephyr/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,20 @@ static void vfs_init(void) {
#endif // MICROPY_VFS

int real_main(void) {
mp_stack_ctrl_init();
// Make MicroPython's stack limit somewhat smaller than full stack available
mp_stack_set_limit(CONFIG_MAIN_STACK_SIZE - 512);
volatile int stack_dummy = 0;

#if MICROPY_PY_THREAD
struct k_thread *z_thread = (struct k_thread *)k_current_get();
mp_thread_init((void *)z_thread->stack_info.start, z_thread->stack_info.size / sizeof(uintptr_t));
#endif

init_zephyr();
mp_hal_init();

soft_reset:
mp_stack_set_top((void *)&stack_dummy);
// Make MicroPython's stack limit somewhat smaller than full stack available
mp_stack_set_limit(CONFIG_MAIN_STACK_SIZE - 512);
#if MICROPY_ENABLE_GC
gc_init(heap, heap + sizeof(heap));
#endif
Expand Down Expand Up @@ -160,6 +166,14 @@ int real_main(void) {
machine_pin_deinit();
#endif

#if MICROPY_PY_THREAD
mp_thread_deinit();
gc_collect();
#endif

gc_sweep_all();
mp_deinit();

goto soft_reset;

return 0;
Expand All @@ -171,6 +185,9 @@ void gc_collect(void) {
void *dummy;
gc_collect_start();
gc_collect_root(&dummy, ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
#if MICROPY_PY_THREAD
mp_thread_gc_others();
#endif
gc_collect_end();
}

Expand Down
25 changes: 25 additions & 0 deletions ports/zephyr/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@
#define MICROPY_COMP_CONST (0)
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)

// When CONFIG_THREAD_CUSTOM_DATA is enabled, MICROPY_PY_THREAD is enabled automatically
#ifdef CONFIG_THREAD_CUSTOM_DATA
#define MICROPY_PY_THREAD (1)
#define MICROPY_PY_THREAD_GIL (1)
#define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32)
#endif

void mp_hal_signal_event(void);
#define MICROPY_SCHED_HOOK_SCHEDULED mp_hal_signal_event()

Expand All @@ -139,3 +146,21 @@ typedef long mp_off_t;
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },

#if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool); \
mp_handle_pending(true); \
MP_THREAD_GIL_EXIT(); \
k_msleep(1); \
MP_THREAD_GIL_ENTER(); \
} while (0);
#else
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool); \
mp_handle_pending(true); \
k_msleep(1); \
} while (0);
#endif
2 changes: 2 additions & 0 deletions ports/zephyr/mpconfigport_minimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,5 @@ typedef unsigned mp_uint_t; // must be pointer size
typedef long mp_off_t;

#define MP_STATE_PORT MP_STATE_VM

#define MICROPY_EVENT_POLL_HOOK
Loading

0 comments on commit 6833f3d

Please sign in to comment.