zephyr: Build MicroPython as a cmake target.

Refactors the zephyr build infrastructure to build MicroPython as a
cmake target, using the recently introduced core cmake rules.

This change makes it possible to build the zephyr port like most other
zephyr applications using west or cmake directly. It simplifies building
with extra cmake arguments, such as specifying an alternate conf file or
adding an Arduino shield. It also enables building the zephyr port
anywhere in the host file system, which will allow regressing across
multiple boards with the zephyr twister script.

Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
This commit is contained in:
Maureen Helm 2020-10-11 13:11:31 -05:00 committed by Damien George
parent 51fa1339f1
commit f573e73bae
8 changed files with 198 additions and 185 deletions

View File

@ -1 +0,0 @@
outdir/

View File

@ -1,24 +1,118 @@
# This file is part of the MicroPython project, http://micropython.org/
#
# The MIT License (MIT)
#
# Copyright 2020 NXP
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(NONE)
project(micropython)
target_sources(app PRIVATE src/zephyr_start.c src/zephyr_getchar.c)
set(MICROPY_PORT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(MICROPY_DIR ${MICROPY_PORT_DIR}/../..)
set(MICROPY_TARGET micropython)
add_library(libmicropython STATIC IMPORTED)
set_target_properties(libmicropython PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libmicropython.a)
target_link_libraries(app PUBLIC libmicropython)
include(${MICROPY_DIR}/py/py.cmake)
include(${MICROPY_DIR}/extmod/extmod.cmake)
zephyr_get_include_directories_for_lang_as_string(C includes)
zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
zephyr_get_compile_definitions_for_lang_as_string(C definitions)
zephyr_get_compile_options_for_lang_as_string(C options)
add_custom_target(
outputexports
COMMAND echo CC="${CMAKE_C_COMPILER}"
COMMAND echo AR="${CMAKE_AR}"
COMMAND echo Z_CFLAGS=${system_includes} ${includes} ${definitions} ${options}
VERBATIM
USES_TERMINAL
set(MICROPY_SOURCE_PORT
main.c
help.c
machine_i2c.c
machine_pin.c
machine_uart.c
modmachine.c
moduos.c
modusocket.c
modutime.c
modzephyr.c
modzsensor.c
uart_core.c
zephyr_storage.c
)
list(TRANSFORM MICROPY_SOURCE_PORT PREPEND ${MICROPY_PORT_DIR}/)
set(MICROPY_SOURCE_LIB
timeutils/timeutils.c
utils/mpirq.c
utils/stdout_helpers.c
utils/printf.c
utils/pyexec.c
utils/interrupt_char.c
mp-readline/readline.c
oofatfs/ff.c
oofatfs/ffunicode.c
littlefs/lfs1.c
littlefs/lfs1_util.c
littlefs/lfs2.c
littlefs/lfs2_util.c
)
list(TRANSFORM MICROPY_SOURCE_LIB PREPEND ${MICROPY_DIR}/lib/)
set(MICROPY_SOURCE_QSTR
${MICROPY_SOURCE_PY}
${MICROPY_SOURCE_EXTMOD}
${MICROPY_SOURCE_LIB}
${MICROPY_SOURCE_PORT}
)
zephyr_get_include_directories_for_lang(C includes)
zephyr_get_system_include_directories_for_lang(C system_includes)
zephyr_get_compile_definitions_for_lang(C definitions)
zephyr_get_compile_options_for_lang(C options)
set(MICROPY_CPP_FLAGS_EXTRA ${includes} ${system_includes} ${definitions} ${options})
zephyr_library_named(${MICROPY_TARGET})
zephyr_library_include_directories(
${MICROPY_DIR}
${MICROPY_PORT_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
zephyr_library_compile_options(
-std=gnu99 -fomit-frame-pointer
)
zephyr_library_compile_definitions(
NDEBUG
MP_CONFIGFILE=<${CONFIG_MICROPY_CONFIGFILE}>
MICROPY_HEAP_SIZE=${CONFIG_MICROPY_HEAP_SIZE}
FFCONF_H=\"${MICROPY_OOFATFS_DIR}/ffconf.h\"
MICROPY_VFS_FAT=$<BOOL:${CONFIG_MICROPY_VFS_FAT}>
MICROPY_VFS_LFS1=$<BOOL:${CONFIG_MICROPY_VFS_LFS1}>
MICROPY_VFS_LFS2=$<BOOL:${CONFIG_MICROPY_VFS_LFS2}>
)
zephyr_library_sources(${MICROPY_SOURCE_QSTR})
add_dependencies(${MICROPY_TARGET} zephyr_generated_headers)
include(${MICROPY_DIR}/py/mkrules.cmake)
target_sources(app PRIVATE
src/zephyr_start.c
src/zephyr_getchar.c
)
target_link_libraries(app PRIVATE ${MICROPY_TARGET})

46
ports/zephyr/Kconfig Normal file
View File

@ -0,0 +1,46 @@
# This file is part of the MicroPython project, http://micropython.org/
#
# The MIT License (MIT)
#
# Copyright 2020 NXP
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
menu "MicroPython Options"
config MICROPY_CONFIGFILE
string "Configuration file"
default "mpconfigport_minimal.h"
config MICROPY_HEAP_SIZE
int "Heap size"
default 16384
config MICROPY_VFS_FAT
bool "FatFS file system"
config MICROPY_VFS_LFS1
bool "LittleFs version 1 file system"
config MICROPY_VFS_LFS2
bool "LittleFs version 2 file system"
endmenu # MicroPython Options
source "Kconfig.zephyr"

View File

@ -1,116 +0,0 @@
#
# This is the main Makefile, which uses MicroPython build system,
# but Zephyr arch-specific toolchain and target-specific flags.
# This Makefile builds MicroPython as a library, and then calls
# recursively Makefile.zephyr to build complete application binary
# using Zephyr build system.
#
# To build a "minimal" configuration, use "make-minimal" wrapper.
BOARD ?= qemu_x86
OUTDIR_PREFIX = $(BOARD)
# Default heap size is 16KB, which is on conservative side, to let
# it build for smaller boards, but it won't be enough for larger
# applications, and will need to be increased.
MICROPY_HEAP_SIZE = 16384
FROZEN_DIR = scripts
MICROPY_VFS_FAT ?= 1
MICROPY_VFS_LFS1 ?= 0
MICROPY_VFS_LFS2 ?= 1
# Default target
all:
include ../../py/mkenv.mk
include $(TOP)/py/py.mk
# Zephyr (generated) config files - must be defined before include below
Z_EXPORTS = outdir/$(OUTDIR_PREFIX)/Makefile.export
ifneq ($(MAKECMDGOALS), clean)
include $(Z_EXPORTS)
endif
INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
INC += -I$(ZEPHYR_BASE)/net/ip
INC += -I$(ZEPHYR_BASE)/net/ip/contiki
INC += -I$(ZEPHYR_BASE)/net/ip/contiki/os
SRC_C = main.c \
help.c \
moduos.c \
modusocket.c \
modutime.c \
modzephyr.c \
modzsensor.c \
modmachine.c \
machine_i2c.c \
machine_pin.c \
machine_uart.c \
uart_core.c \
zephyr_storage.c \
lib/timeutils/timeutils.c \
lib/utils/mpirq.c \
lib/utils/stdout_helpers.c \
lib/utils/printf.c \
lib/utils/pyexec.c \
lib/utils/interrupt_char.c \
lib/mp-readline/readline.c \
$(SRC_MOD)
# List of sources for qstr extraction
SRC_QSTR += $(SRC_C)
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
CFLAGS = $(Z_CFLAGS) \
-std=gnu99 -fomit-frame-pointer -DNDEBUG -DMICROPY_HEAP_SIZE=$(MICROPY_HEAP_SIZE) $(CFLAGS_MOD) $(CFLAGS_EXTRA) $(INC)
include $(TOP)/py/mkrules.mk
GENERIC_TARGETS = all zephyr run qemu qemugdb flash debug debugserver \
ram_report rom_report
KCONFIG_TARGETS = \
initconfig config nconfig menuconfig xconfig gconfig \
oldconfig silentoldconfig defconfig savedefconfig \
allnoconfig allyesconfig alldefconfig randconfig \
listnewconfig olddefconfig
CLEAN_TARGETS = pristine mrproper
$(GENERIC_TARGETS): $(LIBMICROPYTHON)
$(CLEAN_TARGETS): clean
$(GENERIC_TARGETS) $(KCONFIG_TARGETS) $(CLEAN_TARGETS):
$(MAKE) -C outdir/$(BOARD) $@
$(LIBMICROPYTHON): | $(Z_EXPORTS)
build/genhdr/qstr.i.last: | $(Z_EXPORTS)
# If we recreate libmicropython, also cause zephyr.bin relink
LIBMICROPYTHON_EXTRA_CMD = -$(RM) -f outdir/$(OUTDIR_PREFIX)/zephyr.lnk
# MicroPython's global clean cleans everything, fast
CLEAN_EXTRA = outdir libmicropython.a
# Clean Zephyr things in Zephyr way
z_clean:
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) clean
test:
cd $(TOP)/tests && ./run-tests --target minimal --device "execpty:make -C ../ports/zephyr run BOARD=$(BOARD) QEMU_PTY=1"
cmake: outdir/$(BOARD)/Makefile
ifneq ($(CONF_FILE),)
CMAKE_MOD += -DCONF_FILE=$(CONF_FILE)
endif
outdir/$(BOARD)/Makefile:
mkdir -p outdir/$(BOARD) && cmake -DBOARD=$(BOARD) $(CMAKE_MOD) -Boutdir/$(BOARD) -H.
$(Z_EXPORTS): outdir/$(BOARD)/Makefile
make --no-print-directory -C outdir/$(BOARD) outputexports CMAKE_COMMAND=: >$@
make -C outdir/$(BOARD) syscall_list_h_target kobj_types_h_target

View File

@ -50,48 +50,49 @@ switch from master to a tagged release, you can instead do:
With Zephyr installed you may then need to configure your environment,
for example by sourcing `zephyrproject/zephyr/zephyr-env.sh`.
Once Zephyr is ready to use you can build the MicroPython port.
In the port subdirectory `ports/zephyr/` run:
Once Zephyr is ready to use you can build the MicroPython port just like any
other Zephyr application. You can do this anywhere in your file system, it does
not have to be in the `ports/zephyr` directory. Assuming you have cloned the
MicroPython repository into your home directory, you can build the Zephyr port
for a frdm_k64f board like this:
$ make BOARD=<board>
$ west build -b frdm_k64f ~/micropython/ports/zephyr
If you don't specify BOARD, the default is `qemu_x86` (x86 target running
in QEMU emulator). Consult the Zephyr documentation above for the list of
To build for QEMU instead:
$ west build -b qemu_x86 ~/micropython/ports/zephyr
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
additional options enabled, like filesystem support.
Running
-------
To flash the resulting firmware to your board:
$ west flash
Or, to flash it to your board and start a gdb debug session:
$ west debug
To run the resulting firmware in QEMU (for BOARDs like qemu_x86,
qemu_cortex_m3):
make run
$ west build -t run
With the default configuration, networking is now enabled, so you need to
follow instructions in https://wiki.zephyrproject.org/view/Networking-with-Qemu
to setup host side of TAP/SLIP networking. If you get error like:
Networking is enabled with the default configuration, so you need to follow
instructions in
https://docs.zephyrproject.org/latest/guides/networking/qemu_setup.html#networking-with-qemu
to setup the host side of TAP/SLIP networking. If you get an error like:
could not connect serial device to character backend 'unix:/tmp/slip.sock'
it's a sign that you didn't followed instructions above. If you would like
it's a sign that you didn't follow the instructions above. If you would like
to just run it quickly without extra setup, see "minimal" build below.
For deploying/flashing a firmware on a real board, follow Zephyr
documentation for a given board, including known issues for that board
(if any). (Mind again that networking is enabled for the default build,
so you should know if there're any special requirements in that regard,
cf. for example QEMU networking requirements above; real hardware boards
generally should not have any special requirements, unless there're known
issues).
For example, to deploy firmware on the FRDM-K64F board run:
$ make BOARD=frdm_k64f flash
Quick example
-------------
@ -151,9 +152,10 @@ enabled over time.
To make a minimal build:
./make-minimal BOARD=<board>
$ west build -b qemu_x86 ~/micropython/ports/zephyr -- -DCONF_FILE=prj_minimal.conf
To run a minimal build in QEMU without requiring TAP networking setup
run the following after you built image with the previous command:
run the following after you built an image with the previous command:
$ west build -t run
./make-minimal BOARD=<qemu_x86_nommu|qemu_x86|qemu_cortex_m3> run

View File

@ -1,18 +0,0 @@
#!/bin/sh
#
# This is a wrapper for make to build a "minimal" Zephyr port.
# It should be run just like make (i.e. extra vars can be passed on the
# command line, etc.), e.g.:
#
# ./make-minimal BOARD=qemu_cortex_m3
# ./make-minimal BOARD=qemu_cortex_m3 run
#
make \
CONF_FILE=prj_minimal.conf \
CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_minimal.h>"' \
MICROPY_VFS_FAT=0 \
MICROPY_VFS_LFS2=0 \
FROZEN_DIR= \
QEMU_NET=0 \
"$@"

View File

@ -69,3 +69,8 @@ CONFIG_NET_BUF_POOL_USAGE=y
#CONFIG_NET_DEBUG_NET_BUF=y
# Change to 4 for "DEBUG" level
#CONFIG_SYS_LOG_NET_LEVEL=3
# MicroPython options
CONFIG_MICROPY_CONFIGFILE="mpconfigport.h"
CONFIG_MICROPY_VFS_FAT=y
CONFIG_MICROPY_VFS_LFS2=y

View File

@ -460,6 +460,7 @@ function ci_zephyr_setup {
-v "$(pwd)":/micropython \
-e ZEPHYR_SDK_INSTALL_DIR=/opt/sdk/zephyr-sdk-0.11.3 \
-e ZEPHYR_TOOLCHAIN_VARIANT=zephyr \
-e ZEPHYR_BASE=/zephyrproject/zephyr \
-w /micropython/ports/zephyr \
zephyrprojectrtos/ci:v0.11.8
docker ps -a
@ -472,10 +473,10 @@ function ci_zephyr_install {
}
function ci_zephyr_build {
docker exec zephyr-ci bash -c "make clean; ./make-minimal ${MAKEOPTS}"
docker exec zephyr-ci bash -c "make clean; ./make-minimal ${MAKEOPTS} BOARD=frdm_k64f"
docker exec zephyr-ci bash -c "make clean; make ${MAKEOPTS}"
docker exec zephyr-ci bash -c "make clean; make ${MAKEOPTS} BOARD=frdm_k64f"
docker exec zephyr-ci bash -c "make clean; make ${MAKEOPTS} BOARD=mimxrt1050_evk"
docker exec zephyr-ci bash -c "make clean; make ${MAKEOPTS} BOARD=reel_board"
docker exec zephyr-ci west build -p auto -b qemu_x86 -- -DCONF_FILE=prj_minimal.conf
docker exec zephyr-ci west build -p auto -b frdm_k64f -- -DCONF_FILE=prj_minimal.conf
docker exec zephyr-ci west build -p auto -b qemu_x86
docker exec zephyr-ci west build -p auto -b frdm_k64f
docker exec zephyr-ci west build -p auto -b mimxrt1050_evk
docker exec zephyr-ci west build -p auto -b reel_board
}