Skip to content

Commit

Permalink
examples/embedding-full: Add a more full-featured embedding example.
Browse files Browse the repository at this point in the history
It compiles and runs in this state, but a lot of functionality is still
missing, to be extended over the following commits.

Signed-off-by: Christian Walther <cwalther@gmx.ch>
  • Loading branch information
cwalther committed Jun 18, 2023
1 parent ed962f1 commit a211d7c
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 4 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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@v3
- 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
25 changes: 25 additions & 0 deletions examples/embedding-full/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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 += -Wall -Og

SRC += main.c mphal.c
SRC += $(wildcard $(EMBED_DIR)/*/*.c) $(wildcard $(EMBED_DIR)/*/*/*.c)
OBJ += $(SRC:.c=.o)

$(PROG): $(OBJ)
$(CC) -o $@ $^

clean:
/bin/rm -f $(OBJ) $(PROG)
40 changes: 40 additions & 0 deletions examples/embedding-full/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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 -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.
55 changes: 55 additions & 0 deletions examples/embedding-full/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* 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 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"
"\n"
"print('finish')\n"
;

// This array is the MicroPython GC heap.
static char heap[8 * 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.
mp_embed_init(&heap[0], sizeof(heap));

// 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;
}
9 changes: 9 additions & 0 deletions examples/embedding-full/micropython_embed.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 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 the main makefile fragment to build the MicroPython component.
include $(MICROPYTHON_TOP)/ports/embed/embed.mk
31 changes: 31 additions & 0 deletions examples/embedding-full/mpconfigport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* 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"

// Requires shared/readline/readline.h, don't bother as we have no input.
#define MICROPY_PY_BUILTINS_INPUT (0)

// Can be enabled once extmod/moductypes.c is included 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.
#define MICROPY_KBD_EXCEPTION (0)
26 changes: 26 additions & 0 deletions examples/embedding-full/mphal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* This file is part of the MicroPython project, http://micropython.org/
* The MIT License (MIT)
* Copyright (c) 2022-2023 Damien P. George
*/

#include "py/builtin.h"
#include "py/compile.h"
#include "py/mperrno.h"

#if !MICROPY_VFS

mp_lexer_t *mp_lexer_new_from_file(const char *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
9 changes: 5 additions & 4 deletions examples/embedding/README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 4 additions & 0 deletions ports/embed/port/mphalport.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
// Define so there's no dependency on extmod/virtpin.h
#define mp_hal_pin_obj_t

#if MICROPY_KBD_EXCEPTION
void mp_hal_set_interrupt_char(int c);
#endif

0 comments on commit a211d7c

Please sign in to comment.