移植 MicroPython
??MicroPython項(xiàng)目支持多個(gè)不同的MCU或平臺(tái),他們?cè)?MicroPython的port 目錄里面。當(dāng)我們的項(xiàng)目能夠在port 目錄里面找到支持的單片機(jī)時(shí),我們可以直接應(yīng)用port 目錄里面的工程,但是當(dāng)port 目錄里面沒有支持我們的單片機(jī)時(shí),就需要我們自己移植MicroPython到相應(yīng)的的單片機(jī)上。
??通常來說,向單片機(jī)移植MicroPython時(shí)需要的工作有:
??1、設(shè)置工具鏈(配置 Makefile 等)
??2、初始化CPU和編寫bootloader
??3、初始化一切開發(fā)和調(diào)試所需的基本驅(qū)動(dòng)程序(例如 GPIO、UART)。
??4、編寫特定的配置
??5、實(shí)現(xiàn)單片機(jī)的modules。
??下面以一個(gè)最小的MicroPython 固件為演示案例:
??在port 目錄下創(chuàng)建一個(gè)example_port文件夾,該文件夾就是放置工程文件的地方。該文件夾最少要包含5個(gè)文件,分別為main.c、 Makefile、mpconfigport.h、 mphalport.c、 mphalport.h。結(jié)構(gòu)如下:
??其中main.c文件是工程的主文件,Makefile是編譯文件,mpconfigport.h文件的作用是MicroPython 配置文件,mphalport.c是單片機(jī)特有的一些其他配置,mphalport.c文件的作用是實(shí)現(xiàn)標(biāo)準(zhǔn)輸入/輸出。
一、各文件代碼內(nèi)容
1.1、main.c文件
#include "py/compile.h" #include "py/gc.h" #include "py/mperrno.h" #include "py/stackctrl.h" #include "lib/utils/gchelper.h" #include "lib/utils/pyexec.h"// Allocate memory for the MicroPython GC heap. static char heap[4096];int main(int argc, char **argv) {// Initialise the MicroPython runtime.mp_stack_ctrl_init();gc_init(heap, heap + sizeof(heap));mp_init();mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0);mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0);// Start a normal REPL; will exit when ctrl-D is entered on a blank line.pyexec_friendly_repl();// Deinitialise the runtime.gc_sweep_all();mp_deinit();return 0; }// Handle uncaught exceptions (should never be reached in a correct C implementation). void nlr_jump_fail(void *val) {for (;;) {} }// Do a garbage collection cycle. void gc_collect(void) {gc_collect_start();gc_helper_collect_regs_and_stack();gc_collect_end(); }// There is no filesystem so stat'ing returns nothing. mp_import_stat_t mp_import_stat(const char *path) {return MP_IMPORT_STAT_NO_EXIST; }// There is no filesystem so opening a file raises an exception. mp_lexer_t *mp_lexer_new_from_file(const char *filename) {mp_raise_OSError(MP_ENOENT); }1.2、Makefile文件
# Include the core environment definitions; this will set $(TOP). include ../../py/mkenv.mk# Include py core make definitions. include $(TOP)/py/py.mk# Set CFLAGS and libraries. CFLAGS = -I. -I$(BUILD) -I$(TOP) LIBS = -lm# Define the required source files. SRC_C = \main.c \mphalport.c \lib/mp-readline/readline.c \lib/utils/gchelper_generic.c \lib/utils/pyexec.c \lib/utils/stdout_helpers.c \# Define the required object files. OBJ = $(PY_CORE_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))# Define the top-level target, the main firmware. all: $(BUILD)/firmware.elf# Define how to build the firmware. $(BUILD)/firmware.elf: $(OBJ)$(ECHO) "LINK $@"$(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)$(Q)$(SIZE) $@# Include remaining core make rules. include $(TOP)/py/mkrules.mk1.3、mpconfigport.h文件
#include <stdint.h>// Python internal features. #define MICROPY_ENABLE_GC (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)// Fine control over Python builtins, classes, modules, etc. #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_SET (0) #define MICROPY_PY_ATTRTUPLE (0) #define MICROPY_PY_COLLECTIONS (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_IO (0) #define MICROPY_PY_STRUCT (0)// Type definitions for the specific machine.typedef intptr_t mp_int_t; // must be pointer size typedef uintptr_t mp_uint_t; // must be pointer size typedef long mp_off_t;// We need to provide a declaration/definition of alloca(). #include <alloca.h>// Define the port's name and hardware. #define MICROPY_HW_BOARD_NAME "example-board" #define MICROPY_HW_MCU_NAME "unknown-cpu"#define MP_STATE_PORT MP_STATE_VM#define MICROPY_PORT_ROOT_POINTERS \const char *readline_hist[8];1.4、mphalport.h文件
static inline void mp_hal_set_interrupt_char(char c) {}1.5、mphalport.c文件
#include <unistd.h> #include "py/mpconfig.h"// Receive single character, blocking until one is available. int mp_hal_stdin_rx_chr(void) {unsigned char c = 0;int r = read(STDIN_FILENO, &c, 1);(void)r;return c; }// Send the string of given length. void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {int r = write(STDOUT_FILENO, str, len);(void)r; }二、添加module
??要添加一個(gè)自定義module名字為myport,首先在文件夾中添加module定義的文件名字為modmyport.c
#include "py/runtime.h"STATIC mp_obj_t myport_info(void) {mp_printf(&mp_plat_print, "info about my port\n");return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_0(myport_info_obj, myport_info);STATIC const mp_rom_map_elem_t myport_module_globals_table[] = {{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_myport) },{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&myport_info_obj) }, }; STATIC MP_DEFINE_CONST_DICT(myport_module_globals, myport_module_globals_table);const mp_obj_module_t myport_module = {.base = { &mp_type_module },.globals = (mp_obj_dict_t *)&myport_module_globals, };MP_REGISTER_MODULE(MP_QSTR_myport, myport_module, 1);??編寫完modmyport.c文件后,還需要再次編輯 Makefile ,作用是添加modmyport.c到SRC_C列表中。如下所示:
SRC_C = \main.c \modmyport.c \mphalport.c \...SRC_QSTR += modport.c總結(jié)
以上是生活随笔為你收集整理的移植 MicroPython的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学生信息管理系统错误汇总(一)
- 下一篇: 定时给ta讲笑话python3.x