minimal: Convert "bare-arm" port to "minimal" port.
This enable libc functions, GC, and line-editing function. Also, UART emulation for POSIX systems is added. Emulation build is set as default.
This commit is contained in:
parent
d511a20a6b
commit
5ebabcda41
|
@ -1,19 +1,29 @@
|
||||||
include ../py/mkenv.mk
|
include ../py/mkenv.mk
|
||||||
|
|
||||||
|
CROSS = 0
|
||||||
|
|
||||||
# qstr definitions (must come before including py.mk)
|
# qstr definitions (must come before including py.mk)
|
||||||
QSTR_DEFS = qstrdefsport.h
|
QSTR_DEFS = qstrdefsport.h
|
||||||
|
|
||||||
# include py core make definitions
|
# include py core make definitions
|
||||||
include ../py/py.mk
|
include ../py/py.mk
|
||||||
|
|
||||||
|
ifeq ($(CROSS), 1)
|
||||||
CROSS_COMPILE = arm-none-eabi-
|
CROSS_COMPILE = arm-none-eabi-
|
||||||
|
endif
|
||||||
|
|
||||||
INC = -I.
|
INC = -I.
|
||||||
INC += -I..
|
INC += -I..
|
||||||
|
INC += -I../lib/mp-readline
|
||||||
|
INC += -I$(PY_SRC) -I../stmhal
|
||||||
INC += -I$(BUILD)
|
INC += -I$(BUILD)
|
||||||
|
|
||||||
|
ifeq ($(CROSS), 1)
|
||||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||||
|
else
|
||||||
|
CFLAGS = -m32 $(INC) -Wall -Werror -ansi -std=gnu99 $(COPT)
|
||||||
|
endif
|
||||||
|
|
||||||
#Debugging/Optimization
|
#Debugging/Optimization
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
|
@ -22,15 +32,22 @@ else
|
||||||
CFLAGS += -Os -DNDEBUG
|
CFLAGS += -Os -DNDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CROSS), 1)
|
||||||
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
|
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
|
||||||
|
else
|
||||||
|
LD = gcc
|
||||||
|
LDFLAGS = -m32 -Wl,-Map=$@.map,--cref
|
||||||
|
endif
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
SRC_C = \
|
SRC_C = \
|
||||||
main.c \
|
main.c \
|
||||||
# printf.c \
|
uart_core.c \
|
||||||
string0.c \
|
uart_extra.c \
|
||||||
malloc0.c \
|
stmhal/printf.c \
|
||||||
gccollect.c \
|
stmhal/string0.c \
|
||||||
|
stmhal/pyexec.c \
|
||||||
|
lib/mp-readline/readline.c \
|
||||||
|
|
||||||
SRC_S = \
|
SRC_S = \
|
||||||
# startup_stm32f40xx.s \
|
# startup_stm32f40xx.s \
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/repl.h"
|
#include "py/repl.h"
|
||||||
#include "py/pfenv.h"
|
#include "py/pfenv.h"
|
||||||
|
#include "py/gc.h"
|
||||||
|
#include "pyexec.h"
|
||||||
|
#include "pybstdio.h"
|
||||||
|
|
||||||
void do_str(const char *src) {
|
void do_str(const char *src) {
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||||
|
@ -46,14 +49,31 @@ void do_str(const char *src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *stack_top;
|
||||||
|
static char heap[2048];
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
int stack_dummy;
|
||||||
|
stack_top = (char*)&stack_dummy;
|
||||||
|
|
||||||
|
#if MICROPY_ENABLE_GC
|
||||||
|
gc_init(heap, heap + sizeof(heap));
|
||||||
|
#endif
|
||||||
mp_init();
|
mp_init();
|
||||||
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\n')");
|
pyexec_friendly_repl();
|
||||||
|
//do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')");
|
||||||
mp_deinit();
|
mp_deinit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc_collect(void) {
|
void gc_collect(void) {
|
||||||
|
// WARNING: This gc_collect implementation doesn't try to get root
|
||||||
|
// pointers from CPU registers, and thus may function incorrectly.
|
||||||
|
void *dummy;
|
||||||
|
gc_collect_start();
|
||||||
|
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
|
||||||
|
gc_collect_end();
|
||||||
|
gc_dump_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||||
|
@ -83,39 +103,6 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
#if !MICROPY_MIN_USE_STDOUT
|
||||||
int _lseek() {return 0;}
|
|
||||||
int _read() {return 0;}
|
|
||||||
int _write() {return 0;}
|
|
||||||
int _close() {return 0;}
|
|
||||||
void _exit(int x) {for(;;){}}
|
|
||||||
int _sbrk() {return 0;}
|
|
||||||
int _kill() {return 0;}
|
|
||||||
int _getpid() {return 0;}
|
|
||||||
int _fstat() {return 0;}
|
|
||||||
int _isatty() {return 0;}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *malloc(size_t n) {return NULL;}
|
|
||||||
void *calloc(size_t nmemb, size_t size) {return NULL;}
|
|
||||||
void *realloc(void *ptr, size_t size) {return NULL;}
|
|
||||||
void free(void *p) {}
|
|
||||||
int printf(const char *m, ...) {return 0;}
|
|
||||||
void *memcpy(void *dest, const void *src, size_t n) {return NULL;}
|
|
||||||
int memcmp(const void *s1, const void *s2, size_t n) {return 0;}
|
|
||||||
void *memmove(void *dest, const void *src, size_t n) {return NULL;}
|
|
||||||
void *memset(void *s, int c, size_t n) {return NULL;}
|
|
||||||
int strcmp(const char *s1, const char* s2) {return 0;}
|
|
||||||
int strncmp(const char *s1, const char* s2, size_t n) {return 0;}
|
|
||||||
size_t strlen(const char *s) {return 0;}
|
|
||||||
char *strcat(char *dest, const char *src) {return NULL;}
|
|
||||||
char *strchr(const char *dest, int c) {return NULL;}
|
|
||||||
#include <stdarg.h>
|
|
||||||
int vprintf(const char *format, va_list ap) {return 0;}
|
|
||||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {return 0;}
|
|
||||||
|
|
||||||
#undef putchar
|
|
||||||
int putchar(int c) {return 0;}
|
|
||||||
int puts(const char *s) {return 0;}
|
|
||||||
|
|
||||||
void _start(void) {main(0, NULL);}
|
void _start(void) {main(0, NULL);}
|
||||||
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// options to control how Micro Python is built
|
// options to control how Micro Python is built
|
||||||
|
|
||||||
#define MICROPY_ALLOC_PATH_MAX (512)
|
#define MICROPY_ALLOC_PATH_MAX (256)
|
||||||
#define MICROPY_EMIT_X64 (0)
|
#define MICROPY_EMIT_X64 (0)
|
||||||
#define MICROPY_EMIT_THUMB (0)
|
#define MICROPY_EMIT_THUMB (0)
|
||||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||||
|
@ -10,8 +10,8 @@
|
||||||
#define MICROPY_COMP_CONST (0)
|
#define MICROPY_COMP_CONST (0)
|
||||||
#define MICROPY_MEM_STATS (0)
|
#define MICROPY_MEM_STATS (0)
|
||||||
#define MICROPY_DEBUG_PRINTERS (0)
|
#define MICROPY_DEBUG_PRINTERS (0)
|
||||||
#define MICROPY_ENABLE_GC (0)
|
#define MICROPY_ENABLE_GC (1)
|
||||||
#define MICROPY_HELPER_REPL (0)
|
#define MICROPY_HELPER_REPL (1)
|
||||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||||
|
@ -41,11 +41,15 @@
|
||||||
|
|
||||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||||
|
|
||||||
#define UINT_FMT "%lu"
|
// This port is intended to be 32-bit, but unfortunately, int32_t for
|
||||||
#define INT_FMT "%ld"
|
// different targets may be defined in different ways - either as int
|
||||||
|
// or as long. This requires different printf formatting specifiers
|
||||||
|
// to print such value. So, we avoid int32_t and use int directly.
|
||||||
|
#define UINT_FMT "%u"
|
||||||
|
#define INT_FMT "%d"
|
||||||
|
typedef int mp_int_t; // must be pointer size
|
||||||
|
typedef unsigned mp_uint_t; // must be pointer size
|
||||||
|
|
||||||
typedef int32_t mp_int_t; // must be pointer size
|
|
||||||
typedef uint32_t mp_uint_t; // must be pointer size
|
|
||||||
typedef void *machine_ptr_t; // must be of pointer size
|
typedef void *machine_ptr_t; // must be of pointer size
|
||||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||||
typedef long mp_off_t;
|
typedef long mp_off_t;
|
||||||
|
@ -57,3 +61,19 @@ extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||||
|
|
||||||
// We need to provide a declaration/definition of alloca()
|
// We need to provide a declaration/definition of alloca()
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|
||||||
|
#define HAL_GetTick() 0
|
||||||
|
|
||||||
|
static inline void mp_hal_set_interrupt_char(char c) {}
|
||||||
|
|
||||||
|
#define MICROPY_HW_BOARD_NAME "minimal"
|
||||||
|
#define MICROPY_HW_MCU_NAME "unknown-cpu"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#define MICROPY_MIN_USE_STDOUT (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MP_STATE_PORT MP_STATE_VM
|
||||||
|
|
||||||
|
#define MICROPY_PORT_ROOT_POINTERS \
|
||||||
|
const char *readline_hist[8];
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Core UART functions to implement for a port
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Receive single character
|
||||||
|
int stdin_rx_chr(void) {
|
||||||
|
unsigned char c = 0;
|
||||||
|
#if MICROPY_MIN_USE_STDOUT
|
||||||
|
int r = read(0, &c, 1);
|
||||||
|
(void)r;
|
||||||
|
#endif
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send string of given length
|
||||||
|
void stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||||
|
#if MICROPY_MIN_USE_STDOUT
|
||||||
|
int r = write(1, str, len);
|
||||||
|
(void)r;
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#include "pybstdio.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra UART functions
|
||||||
|
* These can be either optimized for a particular port, or reference,
|
||||||
|
* not very optimal implementation below can be used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Send "cooked" string of length, where every occurance of
|
||||||
|
// LF character is replaced with CR LF.
|
||||||
|
void stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||||
|
while (len--) {
|
||||||
|
if (*str == '\n') {
|
||||||
|
stdout_tx_strn("\r", 1);
|
||||||
|
}
|
||||||
|
stdout_tx_strn(str++, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send zero-terminated string
|
||||||
|
void stdout_tx_str(const char *str) {
|
||||||
|
stdout_tx_strn(str, strlen(str));
|
||||||
|
}
|
Loading…
Reference in New Issue