embed: Add new "embed" port which builds a simple C package.

Signed-off-by: Damien George <damien@micropython.org>
pull/9529/head
Damien George 2022-10-06 11:14:13 +11:00
rodzic abaa4abd2d
commit a8a1ad1391
7 zmienionych plików z 303 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,18 @@
MicroPython embed port
======================
This is a port of MicroPython that outputs a set of .c and .h files for embedding
into a wider project. This port essentially targets the C language, instead of a
particular hardware architecture or platform.
To use this port in a project there are three main steps:
1. Provide configuration for the project via an `mpconfigport.h` file.
2. Build this embed port against that configuration, using the provided `embed.mk`.
The output is a set of self-contained source files for building MicroPython.
These files can be placed outside this repository.
3. Build the project. This requires compiling all .c files from the above step.
See `examples/embedding` for an example.

Wyświetl plik

@ -0,0 +1,65 @@
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
#
# This file is intended to be included by a Makefile in a custom project.
# Set the build output directory for the generated files.
BUILD = build-embed
# Include the core environment definitions; this will set $(TOP).
include $(MICROPYTHON_TOP)/py/mkenv.mk
# Include py core make definitions.
include $(TOP)/py/py.mk
# Set the location of the MicroPython embed port.
MICROPYTHON_EMBED_PORT = $(MICROPYTHON_TOP)/ports/embed
# Set default makefile-level MicroPython feature configurations.
MICROPY_ROM_TEXT_COMPRESSION ?= 0
# Set CFLAGS for the MicroPython build.
CFLAGS += -I. -I$(TOP) -I$(BUILD) -I$(MICROPYTHON_EMBED_PORT)
CFLAGS += -Wall -Werror -std=c99
# Define the required generated header files.
GENHDR_OUTPUT = $(addprefix $(BUILD)/genhdr/, \
moduledefs.h \
mpversion.h \
qstrdefs.generated.h \
root_pointers.h \
)
# Define the top-level target, the generated output files.
.PHONY: all
all: micropython-embed-package
clean: clean-micropython-embed-package
.PHONY: clean-micropython-embed-package
clean-micropython-embed-package:
$(RM) -rf $(PACKAGE_DIR)
PACKAGE_DIR ?= micropython_embed
PACKAGE_DIR_LIST = $(addprefix $(PACKAGE_DIR)/,py extmod shared/runtime genhdr port)
.PHONY: micropython-embed-package
micropython-embed-package: $(GENHDR_OUTPUT)
$(ECHO) "Generate micropython_embed output:"
$(Q)$(RM) -rf $(PACKAGE_DIR_LIST)
$(Q)$(MKDIR) -p $(PACKAGE_DIR_LIST)
$(ECHO) "- py"
$(Q)$(CP) $(TOP)/py/*.[ch] $(PACKAGE_DIR)/py
$(ECHO) "- extmod"
$(Q)$(CP) $(TOP)/extmod/moduplatform.h $(PACKAGE_DIR)/extmod
$(ECHO) "- shared"
$(Q)$(CP) $(TOP)/shared/runtime/gchelper.h $(PACKAGE_DIR)/shared/runtime
$(Q)$(CP) $(TOP)/shared/runtime/gchelper_generic.c $(PACKAGE_DIR)/shared/runtime
$(ECHO) "- genhdr"
$(Q)$(CP) $(GENHDR_OUTPUT) $(PACKAGE_DIR)/genhdr
$(ECHO) "- port"
$(Q)$(CP) $(MICROPYTHON_EMBED_PORT)/port/*.[ch] $(PACKAGE_DIR)/port
# Include remaining core make rules.
include $(TOP)/py/mkrules.mk

Wyświetl plik

@ -0,0 +1,106 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 Damien P. George
*
* 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.
*/
#include <string.h>
#include "py/compile.h"
#include "py/gc.h"
#include "py/persistentcode.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "shared/runtime/gchelper.h"
#include "port/micropython_embed.h"
// Initialise the runtime.
void mp_embed_init(void *gc_heap, size_t gc_heap_size) {
mp_stack_ctrl_init();
gc_init(gc_heap, (uint8_t *)gc_heap + gc_heap_size);
mp_init();
}
#if MICROPY_ENABLE_COMPILER
// Compile and execute the given source script (Python text).
void mp_embed_exec_str(const char *src) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// Compile, parse and execute the given string.
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun);
nlr_pop();
} else {
// Uncaught exception: print it out.
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
#endif
#if MICROPY_PERSISTENT_CODE_LOAD
void mp_embed_exec_mpy(const uint8_t *mpy, size_t len) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// Execute the given .mpy data.
mp_module_context_t *ctx = m_new_obj(mp_module_context_t);
ctx->module.globals = mp_globals_get();
mp_compiled_module_t cm = mp_raw_code_load_mem(mpy, len, ctx);
mp_obj_t f = mp_make_function_from_raw_code(cm.rc, ctx, MP_OBJ_NULL);
mp_call_function_0(f);
nlr_pop();
} else {
// Uncaught exception: print it out.
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
#endif
// Deinitialise the runtime.
void mp_embed_deinit(void) {
mp_deinit();
}
#if MICROPY_ENABLE_GC
// Run a garbage collection cycle.
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
}
#endif
// Called if an exception is raised outside all C exception-catching handlers.
void nlr_jump_fail(void *val) {
for (;;) {
}
}
#ifndef NDEBUG
// Used when debugging is enabled.
void __assert_func(const char *file, int line, const char *func, const char *expr) {
for (;;) {
}
}
#endif

Wyświetl plik

@ -0,0 +1,41 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 Damien P. George
*
* 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.
*/
#ifndef MICROPY_INCLUDED_MICROPYTHON_EMBED_H
#define MICROPY_INCLUDED_MICROPYTHON_EMBED_H
#include <stddef.h>
#include <stdint.h>
void mp_embed_init(void *gc_heap, size_t gc_heap_size);
void mp_embed_deinit(void);
// Only available if MICROPY_ENABLE_COMPILER is enabled.
void mp_embed_exec_str(const char *src);
// Only available if MICROPY_PERSISTENT_CODE_LOAD is enabled.
void mp_embed_exec_mpy(const uint8_t *mpy, size_t len);
#endif // MICROPY_INCLUDED_MICROPYTHON_EMBED_H

Wyświetl plik

@ -0,0 +1,38 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 Damien P. George
*
* 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.
*/
#include <stdint.h>
// Type definitions for the specific machine
typedef intptr_t mp_int_t; // must be pointer size
typedef uintptr_t mp_uint_t; // must be pointer size
typedef long mp_off_t;
// Need to provide a declaration/definition of alloca()
#include <alloca.h>
#define MICROPY_MPHALPORT_H "port/mphalport.h"

Wyświetl plik

@ -0,0 +1,33 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 Damien P. George
*
* 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.
*/
#include <stdio.h>
#include "py/mphal.h"
// Send string of given length to stdout, converting \n to \r\n.
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
printf("%.*s", (int)len, str);
}

Wyświetl plik

@ -0,0 +1,2 @@
// Define so there's no dependency on extmod/virtpin.h
#define mp_hal_pin_obj_t