Skip to content

Commit cff9f02

Browse files
committed
zephyr: Initial Zephyr RTOS port, MicroPython part.
1 parent fa5ac67 commit cff9f02

File tree

5 files changed

+237
-0
lines changed

5 files changed

+237
-0
lines changed

zephyr/Makefile

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#
2+
# This is main Makefile, which uses MicroPython build system, but
3+
# Zephyr arch-specific toolchain (setup by Zephyr's Makefile.toolchain.*).
4+
# Unfortunately, it's currently not possible to get target (as in: specific
5+
# board to run on) specific compile-time options from Zephyr, so these must
6+
# be set (duplicated) in this Makefile. Currently, these configured for
7+
# ARM Cortex-M3. This Makefile builds MicroPython as a library, and then
8+
# calls recursively Makefile.zephyr to build complete application using
9+
# Zephyr build system.
10+
#
11+
12+
ARCH ?= x86
13+
BOARD ?= qemu_x86
14+
# Zephyr 1.5.0
15+
#OUTDIR_PREFIX =
16+
# Zephyr 1.6.0
17+
OUTDIR_PREFIX = $(BOARD)
18+
19+
# Zephyr toolchain config is 2-pass, so included twice
20+
include $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)
21+
include $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)
22+
23+
CFLAGS_arm = -mthumb -mcpu=cortex-m3 -mabi=aapcs
24+
CFLAGS_x86 = -fno-asynchronous-unwind-tables -ffreestanding -fno-stack-protector \
25+
-fno-omit-frame-pointer -mpreferred-stack-boundary=2 -mno-sse -march=pentium
26+
CFLAGS_TARGET = $(CFLAGS_$(ARCH))
27+
28+
include ../py/mkenv.mk
29+
include ../py/py.mk
30+
31+
INC += -I.
32+
INC += -I..
33+
INC += -I$(BUILD)
34+
INC += -I$(ZEPHYR_BASE)/include -I$(ZEPHYR_BASE) \
35+
-Ioutdir/$(OUTDIR_PREFIX)/misc/generated/sysgen \
36+
-I$(dir $(Z_AUTOCONF_H))
37+
38+
SRC_C = main.c \
39+
uart_core.c \
40+
lib/utils/stdout_helpers.c \
41+
lib/utils/printf.c \
42+
lib/utils/pyexec.c \
43+
lib/mp-readline/readline.c \
44+
$(SRC_MOD)
45+
46+
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
47+
48+
COPT = -Os -DNDEBUG -fdata-sections -ffunction-sections
49+
CFLAGS = -std=gnu99 $(TOOLCHAIN_CFLAGS) $(INC) $(CFLAGS_MOD) $(COPT) $(CFLAGS_TARGET)
50+
51+
include ../py/mkrules.mk
52+
53+
all: $(LIBMICROPYTHON)
54+
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD)
55+
56+
qemu: all
57+
$(MAKE) -f Makefile.zephyr qemu BOARD=$(BOARD)
58+
59+
Z_AUTOCONF_H = outdir/$(OUTDIR_PREFIX)/include/generated/autoconf.h
60+
61+
$(LIBMICROPYTHON): $(Z_AUTOCONF_H)
62+
build/genhdr/qstr.i.last: $(Z_AUTOCONF_H)
63+
64+
$(Z_AUTOCONF_H):
65+
rm -f $(LIBMICROPYTHON)
66+
-$(MAKE) -f Makefile.zephyr BOARD=$(BOARD)
67+
68+
# Clean Zephyr things too
69+
CLEAN_EXTRA = outdir

zephyr/main.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <stdint.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
5+
#include "py/nlr.h"
6+
#include "py/compile.h"
7+
#include "py/runtime.h"
8+
#include "py/repl.h"
9+
#include "py/gc.h"
10+
#include "lib/utils/pyexec.h"
11+
12+
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
13+
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
14+
if (lex == NULL) {
15+
printf("MemoryError: lexer could not allocate memory\n");
16+
return;
17+
}
18+
19+
nlr_buf_t nlr;
20+
if (nlr_push(&nlr) == 0) {
21+
qstr source_name = lex->source_name;
22+
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
23+
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
24+
mp_call_function_0(module_fun);
25+
nlr_pop();
26+
} else {
27+
// uncaught exception
28+
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
29+
}
30+
}
31+
32+
static char *stack_top;
33+
static char heap[16 * 1024];
34+
35+
int real_main(void) {
36+
int stack_dummy;
37+
stack_top = (char*)&stack_dummy;
38+
39+
#if MICROPY_ENABLE_GC
40+
gc_init(heap, heap + sizeof(heap));
41+
#endif
42+
mp_init();
43+
#if MICROPY_REPL_EVENT_DRIVEN
44+
pyexec_event_repl_init();
45+
for (;;) {
46+
int c = mp_hal_stdin_rx_chr();
47+
if (pyexec_event_repl_process_char(c)) {
48+
break;
49+
}
50+
}
51+
#else
52+
pyexec_friendly_repl();
53+
#endif
54+
//do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT);
55+
//do_str("for i in range(10):\r\n print(i)", MP_PARSE_FILE_INPUT);
56+
mp_deinit();
57+
return 0;
58+
}
59+
60+
void gc_collect(void) {
61+
// WARNING: This gc_collect implementation doesn't try to get root
62+
// pointers from CPU registers, and thus may function incorrectly.
63+
void *dummy;
64+
gc_collect_start();
65+
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
66+
gc_collect_end();
67+
gc_dump_info();
68+
}
69+
70+
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
71+
return NULL;
72+
}
73+
74+
mp_import_stat_t mp_import_stat(const char *path) {
75+
return MP_IMPORT_STAT_NO_EXIST;
76+
}
77+
78+
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
79+
return mp_const_none;
80+
}
81+
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
82+
83+
void nlr_jump_fail(void *val) {
84+
}
85+
86+
void NORETURN __fatal_error(const char *msg) {
87+
while (1);
88+
}
89+
90+
#ifndef NDEBUG
91+
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
92+
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
93+
__fatal_error("Assertion failed");
94+
}
95+
#endif

zephyr/mpconfigport.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <alloca.h>
2+
3+
// Saving extra crumbs to make sure binary fits in 128K
4+
#define MICROPY_COMP_CONST_FOLDING (0)
5+
#define MICROPY_COMP_CONST (0)
6+
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
7+
8+
#define MICROPY_ENABLE_GC (1)
9+
#define MICROPY_HELPER_REPL (1)
10+
#define MICROPY_REPL_AUTO_INDENT (1)
11+
#define MICROPY_CPYTHON_COMPAT (0)
12+
#define MICROPY_PY_ASYNC_AWAIT (0)
13+
#define MICROPY_PY_ATTRTUPLE (0)
14+
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
15+
#define MICROPY_PY_BUILTINS_FILTER (0)
16+
#define MICROPY_PY_BUILTINS_MIN_MAX (0)
17+
#define MICROPY_PY_BUILTINS_PROPERTY (0)
18+
#define MICROPY_PY_BUILTINS_RANGE_ATTRS (0)
19+
#define MICROPY_PY_BUILTINS_REVERSED (0)
20+
#define MICROPY_PY_BUILTINS_SET (0)
21+
#define MICROPY_PY_BUILTINS_SLICE (0)
22+
#define MICROPY_PY_ARRAY (0)
23+
#define MICROPY_PY_COLLECTIONS (0)
24+
#define MICROPY_PY_CMATH (0)
25+
#define MICROPY_PY_IO (0)
26+
#define MICROPY_PY_STRUCT (0)
27+
#define MICROPY_PY_SYS_MODULES (0)
28+
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
29+
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
30+
#define MICROPY_PY_BUILTINS_COMPLEX (0)
31+
#define MICROPY_HW_BOARD_NAME "zephyr-generic"
32+
#define MICROPY_HW_MCU_NAME "unknown-cpu"
33+
34+
typedef int mp_int_t; // must be pointer size
35+
typedef unsigned mp_uint_t; // must be pointer size
36+
37+
typedef void *machine_ptr_t; // must be of pointer size
38+
typedef const void *machine_const_ptr_t; // must be of pointer size
39+
typedef long mp_off_t;
40+
41+
#define BYTES_PER_WORD (sizeof(mp_int_t))
42+
43+
#define MP_STATE_PORT MP_STATE_VM
44+
45+
#define MICROPY_PORT_ROOT_POINTERS \
46+
const char *readline_hist[8];
47+
48+
// Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles
49+
#include "autoconf.h"

zephyr/mphalport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
2+
static inline void mp_hal_set_interrupt_char(char c) {}

zephyr/uart_core.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <unistd.h>
2+
#include "py/mpconfig.h"
3+
#include "src/zephyr_getchar.h"
4+
5+
// Stopgap
6+
extern void printk(const char*, ...);
7+
8+
/*
9+
* Core UART functions to implement for a port
10+
*/
11+
12+
// Receive single character
13+
int mp_hal_stdin_rx_chr(void) {
14+
return zephyr_getchar();
15+
}
16+
17+
// Send string of given length
18+
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
19+
while (len--) {
20+
printk("%c", *str++);
21+
}
22+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy