Skip to content

Commit 1e77e25

Browse files
committed
examples/embedding: Example for embedding MicroPython in an app.
1 parent e47c2ec commit 1e77e25

5 files changed

Lines changed: 421 additions & 0 deletions

File tree

examples/embedding/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
MPTOP = ../..
2+
CFLAGS = -std=c99 -I. -I$(MPTOP) -DNO_QSTR
3+
LDFLAGS = -L.
4+
5+
hello-embed: hello-embed.o -lmicropython
6+
7+
-lmicropython:
8+
$(MAKE) -f $(MPTOP)/examples/embedding/Makefile.upylib MPTOP=$(MPTOP)

examples/embedding/Makefile.upylib

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
MPTOP = ../..
2+
-include mpconfigport.mk
3+
include $(MPTOP)/py/mkenv.mk
4+
5+
all: lib
6+
7+
# OS name, for simple autoconfig
8+
UNAME_S := $(shell uname -s)
9+
10+
# include py core make definitions
11+
include $(MPTOP)/py/py.mk
12+
13+
INC += -I.
14+
INC += -I..
15+
INC += -I$(MPTOP)
16+
INC += -I$(MPTOP)/unix
17+
#INC += -I../lib/timeutils
18+
INC += -I$(BUILD)
19+
20+
# compiler settings
21+
CWARN = -Wall -Werror
22+
CWARN += -Wpointer-arith -Wuninitialized
23+
CFLAGS = $(INC) $(CWARN) -ansi -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
24+
25+
# Debugging/Optimization
26+
ifdef DEBUG
27+
CFLAGS += -g
28+
COPT = -O0
29+
else
30+
COPT = -Os #-DNDEBUG
31+
# _FORTIFY_SOURCE is a feature in gcc/glibc which is intended to provide extra
32+
# security for detecting buffer overflows. Some distros (Ubuntu at the very least)
33+
# have it enabled by default.
34+
#
35+
# gcc already optimizes some printf calls to call puts and/or putchar. When
36+
# _FORTIFY_SOURCE is enabled and compiling with -O1 or greater, then some
37+
# printf calls will also be optimized to call __printf_chk (in glibc). Any
38+
# printfs which get redirected to __printf_chk are then no longer synchronized
39+
# with printfs that go through mp_printf.
40+
#
41+
# In MicroPython, we don't want to use the runtime library's printf but rather
42+
# go through mp_printf, so that stdout is properly tied into streams, etc.
43+
# This means that we either need to turn off _FORTIFY_SOURCE or provide our
44+
# own implementation of __printf_chk. We've chosen to turn off _FORTIFY_SOURCE.
45+
# It should also be noted that the use of printf in MicroPython is typically
46+
# quite limited anyways (primarily for debug and some error reporting, etc
47+
# in the unix version).
48+
#
49+
# Information about _FORTIFY_SOURCE seems to be rather scarce. The best I could
50+
# find was this: https://securityblog.redhat.com/2014/03/26/fortify-and-you/
51+
# Original patchset was introduced by
52+
# https://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html .
53+
#
54+
# Turning off _FORTIFY_SOURCE is only required when compiling with -O1 or greater
55+
CFLAGS += -U _FORTIFY_SOURCE
56+
endif
57+
58+
# On OSX, 'gcc' is a symlink to clang unless a real gcc is installed.
59+
# The unix port of micropython on OSX must be compiled with clang,
60+
# while cross-compile ports require gcc, so we test here for OSX and
61+
# if necessary override the value of 'CC' set in py/mkenv.mk
62+
ifeq ($(UNAME_S),Darwin)
63+
CC = clang
64+
# Use clang syntax for map file
65+
LDFLAGS_ARCH = -Wl,-map,$@.map
66+
else
67+
# Use gcc syntax for map file
68+
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref
69+
endif
70+
LDFLAGS = $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA)
71+
72+
ifeq ($(MICROPY_FORCE_32BIT),1)
73+
# Note: you may need to install i386 versions of dependency packages,
74+
# starting with linux-libc-dev:i386
75+
ifeq ($(MICROPY_PY_FFI),1)
76+
ifeq ($(UNAME_S),Linux)
77+
CFLAGS_MOD += -I/usr/include/i686-linux-gnu
78+
endif
79+
endif
80+
endif
81+
82+
ifeq ($(MICROPY_USE_READLINE),1)
83+
INC += -I../lib/mp-readline
84+
CFLAGS_MOD += -DMICROPY_USE_READLINE=1
85+
LIB_SRC_C_EXTRA += mp-readline/readline.c
86+
endif
87+
ifeq ($(MICROPY_USE_READLINE),2)
88+
CFLAGS_MOD += -DMICROPY_USE_READLINE=2
89+
LDFLAGS_MOD += -lreadline
90+
# the following is needed for BSD
91+
#LDFLAGS_MOD += -ltermcap
92+
endif
93+
ifeq ($(MICROPY_PY_TIME),1)
94+
CFLAGS_MOD += -DMICROPY_PY_TIME=1
95+
SRC_MOD += modtime.c
96+
endif
97+
ifeq ($(MICROPY_PY_TERMIOS),1)
98+
CFLAGS_MOD += -DMICROPY_PY_TERMIOS=1
99+
SRC_MOD += modtermios.c
100+
endif
101+
ifeq ($(MICROPY_PY_SOCKET),1)
102+
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
103+
SRC_MOD += modsocket.c
104+
endif
105+
106+
ifeq ($(MICROPY_PY_FFI),1)
107+
108+
ifeq ($(MICROPY_STANDALONE),1)
109+
LIBFFI_CFLAGS_MOD := -I$(shell ls -1d ../lib/libffi/build_dir/out/lib/libffi-*/include)
110+
ifeq ($(MICROPY_FORCE_32BIT),1)
111+
LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib32/libffi.a
112+
else
113+
LIBFFI_LDFLAGS_MOD = ../lib/libffi/build_dir/out/lib/libffi.a
114+
endif
115+
else
116+
LIBFFI_CFLAGS_MOD := $(shell pkg-config --cflags libffi)
117+
LIBFFI_LDFLAGS_MOD := $(shell pkg-config --libs libffi)
118+
endif
119+
120+
ifeq ($(UNAME_S),Linux)
121+
LIBFFI_LDFLAGS_MOD += -ldl
122+
endif
123+
124+
CFLAGS_MOD += $(LIBFFI_CFLAGS_MOD) -DMICROPY_PY_FFI=1
125+
LDFLAGS_MOD += $(LIBFFI_LDFLAGS_MOD)
126+
SRC_MOD += modffi.c
127+
endif
128+
129+
MAIN_C = main.c
130+
131+
# source files
132+
SRC_C = $(addprefix $(MPTOP)/unix/,\
133+
$(MAIN_C) \
134+
gccollect.c \
135+
unix_mphal.c \
136+
input.c \
137+
file.c \
138+
modmachine.c \
139+
modos.c \
140+
moduselect.c \
141+
alloc.c \
142+
coverage.c \
143+
fatfs_port.c \
144+
$(SRC_MOD) \
145+
)
146+
147+
LIB_SRC_C = $(addprefix lib/,\
148+
$(LIB_SRC_C_EXTRA) \
149+
utils/printf.c \
150+
timeutils/timeutils.c \
151+
)
152+
153+
ifeq ($(MICROPY_FATFS),1)
154+
LIB_SRC_C += $(addprefix lib/,\
155+
fatfs/ff.c \
156+
fatfs/option/ccsbcs.c \
157+
)
158+
endif
159+
160+
OBJ = $(PY_O)
161+
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
162+
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
163+
OBJ += $(addprefix $(BUILD)/, $(STMHAL_SRC_C:.c=.o))
164+
165+
# List of sources for qstr extraction
166+
SRC_QSTR += $(SRC_C) $(LIB_SRC_C)
167+
# Append any auto-generated sources that are needed by sources listed in
168+
# SRC_QSTR
169+
SRC_QSTR_AUTO_DEPS +=
170+
171+
include $(MPTOP)/py/mkrules.mk
172+
173+
# Value of configure's --host= option (required for cross-compilation).
174+
# Deduce it from CROSS_COMPILE by default, but can be overriden.
175+
ifneq ($(CROSS_COMPILE),)
176+
CROSS_COMPILE_HOST = --host=$(patsubst %-,%,$(CROSS_COMPILE))
177+
else
178+
CROSS_COMPILE_HOST =
179+
endif
180+
181+
deplibs: libffi axtls
182+
183+
# install-exec-recursive & install-data-am targets are used to avoid building
184+
# docs and depending on makeinfo
185+
libffi:
186+
cd ../lib/libffi; git clean -d -x -f
187+
cd ../lib/libffi; ./autogen.sh
188+
mkdir -p ../lib/libffi/build_dir; cd ../lib/libffi/build_dir; \
189+
../configure $(CROSS_COMPILE_HOST) --prefix=$$PWD/out CC="$(CC)" CXX="$(CXX)" LD="$(LD)"; \
190+
make install-exec-recursive; make -C include install-data-am
191+
192+
axtls: ../lib/axtls/README
193+
cd ../lib/axtls; cp config/upyconfig config/.config
194+
cd ../lib/axtls; make oldconfig -B
195+
cd ../lib/axtls; make clean
196+
cd ../lib/axtls; make all CC="$(CC)" LD="$(LD)"
197+
198+
../lib/axtls/README:
199+
@echo "You cloned without --recursive, fetching submodules for you."
200+
(cd ..; git submodule update --init --recursive)

examples/embedding/hello-embed.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Paul Sokolovsky
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <string.h>
28+
#include <stdio.h>
29+
#include <stdlib.h>
30+
31+
#include "py/compile.h"
32+
#include "py/runtime.h"
33+
#include "py/gc.h"
34+
#include "py/stackctrl.h"
35+
36+
static char heap[16384];
37+
38+
mp_obj_t execute_from_lexer(mp_lexer_t *lex) {
39+
nlr_buf_t nlr;
40+
if (nlr_push(&nlr) == 0) {
41+
mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT);
42+
mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false);
43+
mp_call_function_0(module_fun);
44+
nlr_pop();
45+
return 0;
46+
} else {
47+
// uncaught exception
48+
return (mp_obj_t)nlr.ret_val;
49+
}
50+
}
51+
52+
int main() {
53+
// Initialized stack limit
54+
mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));
55+
// Initialize heap
56+
gc_init(heap, heap + sizeof(heap));
57+
// Initialize interpreter
58+
mp_init();
59+
60+
const char str[] = "print('Hello world of easy embedding!')";
61+
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
62+
if (execute_from_lexer(lex)) {
63+
printf("Error\n");
64+
}
65+
}
66+
67+
uint mp_import_stat(const char *path) {
68+
return MP_IMPORT_STAT_NO_EXIST;
69+
}
70+
71+
void nlr_jump_fail(void *val) {
72+
printf("FATAL: uncaught NLR %p\n", val);
73+
exit(1);
74+
}

examples/embedding/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mpconfigport_minimal.h

0 commit comments

Comments
 (0)