@@ -60,6 +60,72 @@ include $(TOP)/extmod/extmod.mk
6060
6161GIT_SUBMODULES += lib/libhydrogen lib/stm32lib lib/tinyusb
6262
63+ # Zephyr threading integration (optional)
64+ MICROPY_ZEPHYR_THREADING ?= 0
65+
66+ ifeq ($(MICROPY_ZEPHYR_THREADING ) ,1)
67+ # Add Zephyr submodule
68+ GIT_SUBMODULES += lib/zephyr
69+
70+ # Remove -Werror for Zephyr headers
71+ CFLAGS := $(filter-out -Werror,$(CFLAGS ) )
72+
73+ # Set architecture for Zephyr
74+ ZEPHYR_ARCH := arm
75+
76+ # Enable idle thread for k_msleep() support in EVENT_POLL_HOOK
77+ # MUST be set BEFORE including zephyr_kernel.mk so idle.c is compiled
78+ MICROPY_ZEPHYR_USE_IDLE_THREAD = 1
79+
80+ # Include Zephyr kernel build
81+ include $(TOP ) /extmod/zephyr_kernel/zephyr_kernel.mk
82+
83+ # Add Zephyr includes and flags
84+ CFLAGS += $(ZEPHYR_INC )
85+ CFLAGS += -Wno-error -Wno-macro-redefined
86+ # Define MICROPY_ZEPHYR_THREADING as a preprocessor symbol for C code
87+ CFLAGS += -DMICROPY_ZEPHYR_THREADING=1
88+ CFLAGS += -DMICROPY_ZEPHYR_USE_IDLE_THREAD=1
89+
90+ # CRITICAL: Explicitly add optimization flags for Zephyr builds
91+ # Without this, code is compiled with no optimization, causing 50-100x code size bloat
92+ CFLAGS += -Os -DNDEBUG
93+
94+ # Add STM32-specific Zephyr architecture implementation
95+ SRC_C += zephyr_arch_stm32.c
96+
97+ # Ensure Zephyr objects depend on generated headers
98+ $(addprefix $(BUILD ) /, $(SRC_THIRDPARTY_C :.c=.o)): $(ZEPHYR_GEN_HEADERS )
99+
100+ # Pattern-specific CFLAGS for Zephyr objects
101+ # Zephyr kernel files: Use STM32 CMSIS headers + Zephyr config (for CONFIG_* symbols)
102+ $(BUILD ) /$(TOP ) /lib/zephyr/% .o : CFLAGS += -include $(TOP ) /extmod/zephyr_kernel/zephyr_config_cortex_m.h -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-return-type
103+ $(BUILD ) /$(TOP ) /extmod/zephyr_kernel/% .o : CFLAGS += -Wno-unused-parameter -Wno-unused-function
104+
105+ # Build Zephyr assembly files (context switching, PSP initialization)
106+ ZEPHYR_SWAP_HELPER_O = $(BUILD ) /swap_helper.o
107+ ZEPHYR_PSP_SWITCH_O = $(BUILD ) /zephyr_psp_switch.o
108+ OBJ += $(ZEPHYR_SWAP_HELPER_O )
109+ OBJ += $(ZEPHYR_PSP_SWITCH_O )
110+ OBJ += $(BUILD ) /zephyr_offsets.o
111+
112+ # Common assembler flags for Zephyr .S files
113+ ZEPHYR_AS_FLAGS = -x assembler-with-cpp -D_ASMLANGUAGE \
114+ $(filter-out -std=% -Wdouble-promotion -Wfloat-conversion -Werror,$(CFLAGS ) ) \
115+ $(CFLAGS_MCU_$(MCU_SERIES ) ) \
116+ -include $(TOP ) /extmod/zephyr_kernel/zephyr_config_cortex_m.h \
117+ -Wa,-mimplicit-it=thumb
118+
119+ $(ZEPHYR_SWAP_HELPER_O ) : $(TOP ) /lib/zephyr/arch/arm/core/cortex_m/swap_helper.S $(ZEPHYR_GEN_HEADERS )
120+ $(ECHO ) " CC $<"
121+ $(Q )$(CC ) $(ZEPHYR_AS_FLAGS ) -c -o $@ $<
122+
123+ $(ZEPHYR_PSP_SWITCH_O ) : $(TOP ) /extmod/zephyr_kernel/zephyr_psp_switch.S
124+ $(ECHO ) " CC $<"
125+ $(Q )$(CC ) $(ZEPHYR_AS_FLAGS ) -c -o $@ $<
126+
127+ endif
128+
63129CROSS_COMPILE ?= arm-none-eabi-
64130LD_DIR =boards
65131USBDEV_DIR =usbdev
@@ -114,7 +180,11 @@ INC += -I$(TOP)/lib/tinyusb/src
114180INC += -I$(TOP ) /shared/tinyusb/
115181INC += -Ilwip_inc
116182
183+ ifneq ($(MICROPY_ZEPHYR_THREADING ) ,1)
117184CFLAGS += $(INC ) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA )
185+ else
186+ CFLAGS += $(INC ) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA )
187+ endif
118188CFLAGS += -D$(CMSIS_MCU ) -DUSE_FULL_LL_DRIVER
119189CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES ) )
120190CFLAGS += $(COPT )
@@ -507,13 +577,21 @@ $(BUILD)/mpremoteprocport.o: $(BUILD)/openamp/metal/config.h
507577endif
508578endif
509579
580+ # Conditionally exclude legacy threading files when using Zephyr
581+ # Note: pendsv.c and systick.c are kept because they contain utility functions,
582+ # but their interrupt handlers are conditionally compiled out via #if !MICROPY_ZEPHYR_THREADING
583+ ifeq ($(MICROPY_ZEPHYR_THREADING ) ,1)
584+ SRC_C := $(filter-out pybthread.c mpthreadport.c,$(SRC_C ) )
585+ endif
586+
510587# SRC_O should be placed first to work around this LTO bug with binutils <2.35:
511588# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83967
512589OBJ += $(addprefix $(BUILD ) /, $(SRC_O ) )
513590OBJ += $(PY_O )
514591OBJ += $(addprefix $(BUILD ) /, $(LIB_SRC_C:.c=.o ) )
515592OBJ += $(addprefix $(BUILD ) /, $(LIBM_SRC_C:.c=.o ) )
516593OBJ += $(addprefix $(BUILD ) /, $(SHARED_SRC_C:.c=.o ) )
594+ OBJ += $(addprefix $(BUILD ) /, $(SRC_THIRDPARTY_C:.c=.o ) )
517595OBJ += $(addprefix $(BUILD ) /, $(DRIVERS_SRC_C:.c=.o ) )
518596OBJ += $(addprefix $(BUILD ) /, $(HAL_SRC_C:.c=.o ) )
519597OBJ += $(addprefix $(BUILD ) /, $(USBDEV_SRC_C:.c=.o ) )
@@ -682,6 +760,10 @@ $(BUILD)/firmware-trusted.bin: $(BUILD)/firmware.bin
682760
683761# List of sources for qstr extraction
684762SRC_QSTR += $(SRC_C ) $(SRC_CXX ) $(SHARED_SRC_C ) $(GEN_PINS_SRC )
763+ # Add MicroPython-Zephyr integration files for root pointer extraction
764+ ifeq ($(MICROPY_ZEPHYR_THREADING ) ,1)
765+ SRC_QSTR += $(ZEPHYR_MP_SRC_C )
766+ endif
685767
686768# Making OBJ use an order-only dependency on the generated pins.h file
687769# has the side effect of making the pins.h file before we actually compile
0 commit comments