Christian Walther 2024-04-26 20:17:15 +02:00 zatwierdzone przez GitHub
commit 8e27ad3264
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
19 zmienionych plików z 583 dodań i 13 usunięć

Wyświetl plik

@ -23,3 +23,12 @@ jobs:
run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding
- name: Run
run: ./examples/embedding/embed | grep "hello world"
embedding-full:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make -C examples/embedding-full -f micropython_embed.mk submodules && make -C examples/embedding-full -f micropython_embed.mk && make -C examples/embedding-full
- name: Run
run: ./examples/embedding-full/embed

Wyświetl plik

@ -0,0 +1,29 @@
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
#
# This is a very simple makefile that demonstrates how to build the embed port.
# All it needs to do is build all *.c files in the micropython_embed directory.
# This makefile would be replaced with your custom build system.
EMBED_DIR = micropython_embed
PROG = embed
CFLAGS += -I.
CFLAGS += -I$(EMBED_DIR)
CFLAGS += -I$(EMBED_DIR)/port
CFLAGS += -I$(EMBED_DIR)/lib/littlefs
CFLAGS += -Wall -Og -fno-common
SRC += main.c mphal.c modules/c_hello/modc_hello.c
SRC += $(wildcard $(EMBED_DIR)/*/*.c)
# Filter out lib because the files in there cannot be compiled separately, they
# are #included by other .c files.
SRC += $(filter-out $(EMBED_DIR)/lib/%.c,$(wildcard $(EMBED_DIR)/*/*/*.c))
OBJ += $(SRC:.c=.o)
$(PROG): $(OBJ)
$(CC) -o $@ $^ -lm
clean:
/bin/rm -f $(OBJ) $(PROG)

Wyświetl plik

@ -0,0 +1,43 @@
Example of embedding MicroPython in a standalone C application (full)
=====================================================================
This directory contains a simple example of how to embed a full-featured
version of MicroPython in an existing C application.
See also _embedding_ for a more minimal version.
A C application is represented here by the file `main.c`. It executes two
simple Python scripts which print things to the standard output.
Functions used by the MicroPython core that need to be provided by the
application are implemented in `mphal.c`.
Building the example
--------------------
First build the embed port using:
$ make -C mpy-cross
$ cd examples/embedding-full
$ make -f micropython_embed.mk submodules
$ make -f micropython_embed.mk
This will generate the `micropython_embed` directory which is a self-contained
copy of MicroPython suitable for embedding. The .c files in this directory need
to be compiled into your project, in whatever way your project can do that. The
example here uses make and a provided `Makefile`.
To build the example project, based on `main.c`, use:
$ make
That will create an executable called `embed` which you can run:
$ ./embed
Out of tree build
-----------------
This example is set up to work out of the box, being part of the MicroPython
tree. Your application will be outside of this tree, but the only thing you
need to do for that is to change `MICROPYTHON_TOP` (found in `micropython_embed.mk`)
to point to the location of the MicroPython repository. The MicroPython
repository may, for example, be a git submodule in your project.

Wyświetl plik

@ -0,0 +1,113 @@
/* This file is part of the MicroPython project, http://micropython.org/
* The MIT License (MIT)
* Copyright (c) 2022-2023 Damien P. George
*/
#include "port/micropython_embed.h"
#include "py/stackctrl.h"
// This is example 1 script, which will be compiled and executed.
static const char *example_1 =
"print('hello world!', list(x + 1.5 for x in range(10)), end='eol\\n')";
// This is example 2 script, which will be compiled and executed.
static const char *example_2 =
"for i in range(10):\n"
" print('iter {:08}'.format(i))\n"
"\n"
"try:\n"
" 1//0\n"
"except Exception as er:\n"
" print('caught exception', repr(er))\n"
"\n"
"import gc\n"
"print('run GC collect')\n"
"gc.collect()\n"
"\n"
"print('help(\\'modules\\'):')\n"
"help('modules')\n"
"import sys\n"
"help(sys)\n"
// Skip testing stdin when using the POSIX implementation, i.e. it is
// connected to actual stdin, because that makes the program wait for input,
// which can be inconvenient or confusing (giving the appearance of being
// stuck). There is no harm enabling it if you remember to provide some
// input.
#if !MICROPY_VFS_POSIX
"print('sys.stdin.read(3):', repr(sys.stdin.read(3)))\n"
"print('sys.stdin.buffer.read(3):', repr(sys.stdin.buffer.read(3)))\n"
#endif
"sys.stdout.write('hello stdout text\\n')\n"
"sys.stdout.buffer.write(b'hello stdout binary\\n')\n"
"sys.stdout.write('hello stderr text\\n')\n"
"sys.stdout.buffer.write(b'hello stderr binary\\n')\n"
"import os\n"
"help(os)\n"
"print('os.uname():', os.uname())\n"
"import random\n"
"help(random)\n"
"import time\n"
"help(time)\n"
"print('time.gmtime(736622952) = 2023-05-05T17:29:12Z:', time.gmtime(736622952))\n"
"import math\n"
"help(math)\n"
"import uctypes\n"
"help(uctypes)\n"
"import frozenhello\n"
"help(frozenhello)\n"
"print('frozenhello.hello():', frozenhello.hello())\n"
"import c_hello\n"
"help(c_hello)\n"
"print('c_hello.hello():', c_hello.hello())\n"
"import fsimage, vfs\n"
"vfs.mount(fsimage.BlockDev(), '/lfs', readonly=True)\n"
"print('os.listdir(\\'/lfs\\'):', os.listdir('/lfs'))\n"
"with open('/lfs/lfshello.py', 'rb') as f:\n"
" print('lfshello.py:', f.read())\n"
"sys.path.append('/lfs')\n"
"import lfshello\n"
"help(lfshello)\n"
"print('lfshello.hello():', lfshello.hello())\n"
"vfs.mount(vfs.VfsPosix('.'), '/posix')\n"
"print('os.listdir(\\'/posix\\'):', os.listdir('/posix'))\n"
"with open('/posix/posixhello.py', 'wb') as f:\n"
" f.write(b'def hello():\\n return \"Hello from a POSIX file!\"\\n')\n"
"with open('/posix/posixhello.py', 'rb') as f:\n"
" print('posixhello.py:', f.read())\n"
"sys.path.append('/posix')\n"
"import posixhello\n"
"help(posixhello)\n"
"print('posixhello.hello():', posixhello.hello())\n"
"os.unlink('/posix/posixhello.py')"
"\n"
"print('finish')\n"
;
// This array is the MicroPython GC heap.
static char heap[16 * 1024];
int main() {
#if MICROPY_STACK_CHECK
// Set the stack limit, otherwise the default is zero and we will end up in
// nlr_jump_fail() immediately.
mp_stack_set_limit(10240);
#endif
// Initialise MicroPython.
//
// Note: &stack_top below should be good enough for many cases.
// However, depending on environment, there might be more appropriate
// ways to get the stack top value.
// eg. pthread_get_stackaddr_np, pthread_getattr_np,
// __builtin_frame_address/__builtin_stack_address, etc.
int stack_top;
mp_embed_init(&heap[0], sizeof(heap), &stack_top);
// Run the example scripts (they will be compiled first).
mp_embed_exec_str(example_1);
mp_embed_exec_str(example_2);
// Deinitialise MicroPython.
mp_embed_deinit();
return 0;
}

Wyświetl plik

@ -0,0 +1,2 @@
module("frozenhello.py", base_path="modules")
module("fsimage.py", base_path="modules")

Wyświetl plik

@ -0,0 +1,32 @@
# This file is part of the MicroPython project, http://micropython.org/
# The MIT License (MIT)
# Copyright (c) 2022-2023 Damien P. George
# Set the location of the top of the MicroPython repository.
MICROPYTHON_TOP = ../..
# Include modules from extmod in the output.
EMBED_EXTRA = extmod
# Include helper sources for the time module in the output.
EMBED_EXTRA += \
shared/timeutils/timeutils.c \
shared/timeutils/timeutils.h \
shared/timeutils/modtime_mphal.h
# Include source for mphal-backed stdio in the output.
# Disable when using POSIX-backed stdio (MICROPY_VFS_POSIX).
#EMBED_EXTRA += \
# shared/runtime/sys_stdio_mphal.c
# Include library sources for littlefs 2 in the output.
EMBED_EXTRA += littlefs2
# Freeze Python modules.
FROZEN_MANIFEST ?= manifest.py
# Add C modules.
USER_C_MODULES = modules
# Include the main makefile fragment to build the MicroPython component.
include $(MICROPYTHON_TOP)/ports/embed/embed.mk

Wyświetl plik

@ -0,0 +1,2 @@
C_HELLO_MOD_DIR := $(USERMOD_DIR)
SRC_USERMOD_C += $(C_HELLO_MOD_DIR)/modc_hello.c

Wyświetl plik

@ -0,0 +1,23 @@
// Check examples/usercmodule for more info about how this works.
#include "py/runtime.h"
#include "py/objstr.h"
static mp_obj_t c_hello_hello() {
static const MP_DEFINE_STR_OBJ(hello_str, "Hello from C!");
return MP_OBJ_FROM_PTR(&hello_str);
}
static MP_DEFINE_CONST_FUN_OBJ_0(c_hello_hello_obj, c_hello_hello);
static const mp_rom_map_elem_t c_hello_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_c_hello) },
{ MP_ROM_QSTR(MP_QSTR_hello), MP_ROM_PTR(&c_hello_hello_obj) },
};
static MP_DEFINE_CONST_DICT(c_hello_module_globals, c_hello_module_globals_table);
const mp_obj_module_t c_hello_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&c_hello_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_c_hello, c_hello_module);

Wyświetl plik

@ -0,0 +1,2 @@
def hello():
return "Hello from the cold!"

Wyświetl plik

@ -0,0 +1,27 @@
# a minimal read-only block device containing a tiny littlefs image
class BlockDev:
def readblocks(self, block_num, buf, offset=0):
addr = block_num * 128 + offset
for i in range(len(buf)):
buf[i] = (
b"\x03\x00\x00\x00\xf0\x0f\xff\xf7littlefs/\xe0\x00\x10\x01\x00\x02\x00\x80\x00\x00\x00\x03\x00\x00\x00"
b"\xff\x00\x00\x00\xff\xff\xff\x7f\xfe\x03\x00\x00 \x00\x04\x13lfshello.py 0\x00\x03\x02"
b"\x00\x00\x006\x00\x00\x00\x100\x00\x00\x00\xda#\xed=!\xb7\x17`\x1f\xf8!\x99\xf8T\x19\xff\xff\xff\xff\xff"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x02\x00\x00\x00\xf0\x0f\xff\xf7littlefs/\xe0\x00\x10\x01\x00\x02\x00\x80\x00\x00\x00\x03\x00\x00\x00"
b"\xff\x00\x00\x00\xff\xff\xff\x7f\xfe\x03\x00\x00\x7f\xef\xfc\x10 \x00\x00\x00R\xaa\xf5\xe6\x0f\xe0\x00\x0cq)\x81\xa1"
b"\x90\x0f\xf8\x04@\x00\x00\x0blfshello.py \x00\x00\x0bp\x1f\xf8%\x12\xbc\x179\xff"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b'def hello():\n return "Hello f'
b'rom a littlefs file!"\n\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
)[addr + i]
def ioctl(self, op, arg):
if op == 4: # block count
return 3
if op == 5: # block size
return 128

Wyświetl plik

@ -0,0 +1,69 @@
/* This file is part of the MicroPython project, http://micropython.org/
* The MIT License (MIT)
* Copyright (c) 2022-2023 Damien P. George
*/
// Include common MicroPython embed configuration.
#include <port/mpconfigport_common.h>
// Use the same starting configuration as on most bare-metal targets.
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
// MicroPython configuration.
#define MICROPY_ENABLE_COMPILER (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_PY_GC (1)
#define MICROPY_PY_SYS_PLATFORM "embedded"
#define MICROPY_PY_OS_UNAME (1)
#define MICROPY_HW_BOARD_NAME "embedded"
#define MICROPY_HW_MCU_NAME "C"
// Enable the VFS subsystem, littlefs and POSIX VFS, importing from VFS, and
// the vfs module.
#define MICROPY_VFS (1)
#define MICROPY_VFS_LFS2 (1)
#define MICROPY_VFS_POSIX (1)
#define MICROPY_READER_VFS (1)
#define MICROPY_PY_VFS (1)
// Enable floating point numbers and the math module.
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
// Enable more functions in the time module. Requires additions to EMBED_EXTRA,
// see micropython_embed.mk.
#define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1)
#define MICROPY_PY_TIME_TIME_TIME_NS (1)
#define MICROPY_PY_TIME_INCLUDEFILE "shared/timeutils/modtime_mphal.h"
// Requires shared/readline/readline.h, don't bother as we have no input.
#define MICROPY_PY_BUILTINS_INPUT (0)
// Requires MICROPY_EVENT_POLL_HOOK, don't bother as we have no pollable objects.
#define MICROPY_PY_SELECT (0)
// On by default and works in this configuration, but disable it to avoid a
// linker error if you don't include extmod/moductypes.c in the build.
//#define MICROPY_PY_UCTYPES (0)
// Can be enabled once either shared/runtime/sys_stdio_mphal.c or
// extmod/vfs_posix_file.c is included in the build.
//#define MICROPY_PY_SYS_STDFILES (0)
// Can be enabled if you provide an implementation of
// mp_hal_set_interrupt_char() in mphal.c or include
// shared/runtime/interrupt_char.c in the build.
#define MICROPY_KBD_EXCEPTION (0)
// We have our own implementation of mp_hal_stdout_tx_strn_cooked().
#undef MP_PLAT_PRINT_STRN
// Enable freezing of Python modules. These would be set automatically for the
// port build based on the presence of FROZEN_MANIFEST by py/mkrules.mk, but
// must be set explicitly for the application build.
#define MICROPY_MODULE_FROZEN_MPY 1
#define MICROPY_MODULE_FROZEN_STR 1
#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool
// must match MPY_TOOL_FLAGS or defaults for mpy-tool.py arguments
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MPZ_DIG_SIZE (16)

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
*/
#include <stdio.h>
#include "py/builtin.h"
#include "py/compile.h"
#include "py/mperrno.h"
#if MICROPY_PY_SYS_STDFILES
#include "py/stream.h"
#endif
#if !MICROPY_VFS
mp_lexer_t *mp_lexer_new_from_file(qstr filename) {
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {
(void)path;
return MP_IMPORT_STAT_NO_EXIST;
}
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
#endif
#if MICROPY_PY_ASYNCIO
mp_uint_t mp_hal_ticks_ms(void) {
return 0;
}
#endif
#if MICROPY_PY_TIME
void mp_hal_delay_ms(mp_uint_t ms) {
}
void mp_hal_delay_us(mp_uint_t us) {
}
mp_uint_t mp_hal_ticks_us(void) {
return 0;
}
mp_uint_t mp_hal_ticks_cpu(void) {
return 0;
}
#endif
#if MICROPY_PY_TIME_TIME_TIME_NS
uint64_t mp_hal_time_ns(void) {
// Nanoseconds since the Epoch.
return 0;
}
#endif
// Text-mode standard output
// (When MICROPY_PY_SYS_STDFILES && MICROPY_VFS_POSIX, this is only used for
// mp_plat_print (mostly debug output), but not for print() and sys.stdout.)
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
// This is a simplistic implementation for demonstration purposes. A real
// one would probably want to prefix every line, not just at the start of a
// write operation.
static int start_of_line = 1;
if (start_of_line) printf("py: ");
printf("%.*s", (int)len, str);
start_of_line = (len > 0 && (str[len-1] == '\n' || str[len-1] == '\r'));
}
#if MICROPY_PY_SYS_STDFILES && !MICROPY_VFS_POSIX
// Binary-mode standard input
// Receive single character, blocking until one is available.
int mp_hal_stdin_rx_chr(void) {
return 'X';
}
// Binary-mode standard output
// Send the string of given length.
mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) {
printf("tx: %.*s", (int)len, str);
return len;
}
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
uintptr_t ret = 0;
if ((poll_flags & MP_STREAM_POLL_RD) /* && can_read */) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) /* && can_write */) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}
#endif

Wyświetl plik

@ -1,8 +1,9 @@
Example of embedding MicroPython in a standalone C application
==============================================================
Example of embedding MicroPython in a standalone C application (minimal)
========================================================================
This directory contains a simple example of how to embed MicroPython in an
existing C application.
This directory contains a simple example of how to embed a minimal version of
MicroPython in an existing C application.
See also _embedding-full_ for a more full-featured version.
A C application is represented here by the file `main.c`. It executes two
simple Python scripts which print things to the standard output.

Wyświetl plik

@ -29,9 +29,15 @@
#if MICROPY_PY_VFS
#include "extmod/vfs.h"
#if MICROPY_VFS_FAT
#include "extmod/vfs_fat.h"
#endif
#if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2
#include "extmod/vfs_lfs.h"
#endif
#if MICROPY_VFS_POSIX
#include "extmod/vfs_posix.h"
#endif
#if !MICROPY_VFS
#error "MICROPY_PY_VFS requires MICROPY_VFS"

Wyświetl plik

@ -12,6 +12,15 @@ include $(MICROPYTHON_TOP)/py/mkenv.mk
# Include py core make definitions.
include $(TOP)/py/py.mk
ifeq ($(filter extmod,$(EMBED_EXTRA)),extmod)
include $(TOP)/extmod/extmod.mk
endif
# The parts of EMBED_EXTRA that name literal files and don't need special handling.
EMBED_EXTRA_FILES = $(filter-out extmod littlefs1 littlefs2,$(EMBED_EXTRA))
# Extra files need to be searched for QSTRs.
SRC_QSTR += $(addprefix $(TOP)/,$(EMBED_EXTRA_FILES))
# Set the location of the MicroPython embed port.
MICROPYTHON_EMBED_PORT = $(MICROPYTHON_TOP)/ports/embed
@ -31,6 +40,11 @@ GENHDR_OUTPUT = $(addprefix $(BUILD)/genhdr/, \
root_pointers.h \
)
# Define the module freezing output.
ifneq ($(FROZEN_MANIFEST),)
FROZEN_OUTPUT = $(BUILD)/frozen_content.c
endif
# Define the top-level target, the generated output files.
.PHONY: all
all: micropython-embed-package
@ -43,23 +57,62 @@ clean-micropython-embed-package:
PACKAGE_DIR ?= micropython_embed
PACKAGE_DIR_LIST = $(addprefix $(PACKAGE_DIR)/,py extmod shared/runtime genhdr port)
ifeq ($(filter extmod,$(EMBED_EXTRA)),extmod)
PACKAGE_DIR_LIST += $(addprefix $(PACKAGE_DIR)/,lib/uzlib lib/crypto-algorithms lib/re1.5)
endif
ifneq ($(filter littlefs1 littlefs2,$(EMBED_EXTRA)),)
PACKAGE_DIR_LIST += $(addprefix $(PACKAGE_DIR)/,lib/littlefs libsrc/littlefs)
endif
ifneq ($(FROZEN_MANIFEST),)
PACKAGE_DIR_LIST += $(addprefix $(PACKAGE_DIR)/,frozen)
endif
ifneq ($(EMBED_EXTRA_FILES),)
PACKAGE_DIR_LIST += $(addprefix $(PACKAGE_DIR)/,$(filter-out ./,$(sort $(dir $(EMBED_EXTRA_FILES)))))
endif
.PHONY: micropython-embed-package
micropython-embed-package: $(GENHDR_OUTPUT)
micropython-embed-package: $(GENHDR_OUTPUT) $(FROZEN_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"
ifeq ($(filter extmod,$(EMBED_EXTRA)),extmod)
$(Q)$(CP) $(TOP)/extmod/*.[ch] $(PACKAGE_DIR)/extmod
$(ECHO) "- lib"
$(Q)$(CP) $(TOP)/lib/uzlib/*.[ch] $(PACKAGE_DIR)/lib/uzlib
$(Q)$(CP) $(TOP)/lib/crypto-algorithms/*.[ch] $(PACKAGE_DIR)/lib/crypto-algorithms
$(Q)$(CP) $(TOP)/lib/re1.5/*.[ch] $(PACKAGE_DIR)/lib/re1.5
else
$(Q)$(CP) $(TOP)/extmod/modplatform.h $(PACKAGE_DIR)/extmod
endif
ifneq ($(filter littlefs1 littlefs2,$(EMBED_EXTRA)),)
$(ECHO) "- libsrc"
ifeq ($(filter littlefs1,$(EMBED_EXTRA)),littlefs1)
$(Q)$(CP) $(TOP)/lib/littlefs/lfs1*.h $(PACKAGE_DIR)/lib/littlefs
$(Q)$(CP) $(TOP)/lib/littlefs/lfs1*.c $(PACKAGE_DIR)/libsrc/littlefs
endif
ifeq ($(filter littlefs2,$(EMBED_EXTRA)),littlefs2)
$(Q)$(CP) $(TOP)/lib/littlefs/lfs2*.h $(PACKAGE_DIR)/lib/littlefs
$(Q)$(CP) $(TOP)/lib/littlefs/lfs2*.c $(PACKAGE_DIR)/libsrc/littlefs
endif
endif
$(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
ifneq ($(FROZEN_MANIFEST),)
$(ECHO) "- frozen"
$(Q)$(CP) $(FROZEN_OUTPUT) $(PACKAGE_DIR)/frozen
endif
$(ECHO) "- port"
$(Q)$(CP) $(MICROPYTHON_EMBED_PORT)/port/*.[ch] $(PACKAGE_DIR)/port
ifneq ($(EMBED_EXTRA_FILES),)
$(ECHO) "- extra"
$(Q)$(foreach FILE,$(EMBED_EXTRA_FILES),$(CP) $(TOP)/$(FILE) $(dir $(PACKAGE_DIR)/$(FILE)) &&) true
endif
# Include remaining core make rules.
include $(TOP)/py/mkrules.mk

Wyświetl plik

@ -40,3 +40,13 @@ typedef long mp_off_t;
#endif
#define MICROPY_MPHALPORT_H "port/mphalport.h"
// Default implementation for applications that want output to go to the system
// printf(). If you don't, or don't have printf() available, or use
// shared/libc/printf.c (MICROPY_USE_INTERNAL_PRINTF) which would be a circular
// definition, #undef this and implement mp_hal_stdout_tx_strn_cooked().
#define MP_PLAT_PRINT_STRN(str, len) \
do { \
extern int printf(const char *fmt, ...); \
printf("%.*s", (int)len, str); \
} while (0)

Wyświetl plik

@ -1,2 +1,26 @@
// Define so there's no dependency on extmod/virtpin.h
#define mp_hal_pin_obj_t
#define mp_hal_pin_obj_t mp_obj_t
#if MICROPY_KBD_EXCEPTION
void mp_hal_set_interrupt_char(int c);
#endif
#if MICROPY_VFS_POSIX
// This macro is used to implement PEP 475 to retry specified syscalls on EINTR
#define MP_HAL_RETRY_SYSCALL(ret, syscall, raise) { \
for (;;) { \
MP_THREAD_GIL_EXIT(); \
ret = syscall; \
MP_THREAD_GIL_ENTER(); \
if (ret == -1) { \
int err = errno; \
if (err == EINTR) { \
mp_handle_pending(true); \
continue; \
} \
raise; \
} \
break; \
} \
}
#endif

Wyświetl plik

@ -251,8 +251,8 @@ endif
submodules:
$(ECHO) "Updating submodules: $(GIT_SUBMODULES)"
ifneq ($(GIT_SUBMODULES),)
$(Q)git submodule sync $(addprefix $(TOP)/,$(GIT_SUBMODULES))
$(Q)git submodule update --init $(addprefix $(TOP)/,$(GIT_SUBMODULES))
$(Q)cd $(TOP) && git submodule sync $(GIT_SUBMODULES)
$(Q)cd $(TOP) && git submodule update --init $(GIT_SUBMODULES)
endif
.PHONY: submodules

Wyświetl plik

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2022-2023 Damien P. George
* Copyright (c) 2013-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
@ -24,10 +24,29 @@
* THE SOFTWARE.
*/
#include <stdio.h>
#include "py/obj.h"
#include "py/mphal.h"
#include "shared/timeutils/timeutils.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);
// Return the localtime as an 8-tuple.
static mp_obj_t mp_time_localtime_get(void) {
mp_int_t seconds = mp_hal_time_ns() / 1000000000;
timeutils_struct_time_t tm;
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
mp_obj_t tuple[8] = {
tuple[0] = mp_obj_new_int(tm.tm_year),
tuple[1] = mp_obj_new_int(tm.tm_mon),
tuple[2] = mp_obj_new_int(tm.tm_mday),
tuple[3] = mp_obj_new_int(tm.tm_hour),
tuple[4] = mp_obj_new_int(tm.tm_min),
tuple[5] = mp_obj_new_int(tm.tm_sec),
tuple[6] = mp_obj_new_int(tm.tm_wday),
tuple[7] = mp_obj_new_int(tm.tm_yday),
};
return mp_obj_new_tuple(8, tuple);
}
// Returns the number of seconds, as an integer, since the Epoch.
static mp_obj_t mp_time_time_get(void) {
return mp_obj_new_int(mp_hal_time_ns() / 1000000000);
}