本文主要介紹一下,在Linux環境下編譯micropython固件的方法和流程。html
首先,咱們先來看一下MicroPython的源碼結構。python
github地址:https://github.com/micropython/micropythongit
你會發現,micropython根據不一樣的MCU運行平臺進行了分類,好比esp8266目錄下就是esp8266-WIFI模塊上的micropython的源碼,stmhal是運行在stm32上的,還有cc3200等。github
py/ubuntu |
Python實現的核心部分,包括編譯器、運行時、核心庫框架 |
mpy-cross/socket |
MicroPython 自帶的交叉編譯器,能夠將python腳本編譯爲mpy加密文件函數 |
unix/工具 |
在UNIX上運行的MicroPython測試 |
stmhal/ |
在TPYBoard和相似的STM32開發板上運行的MicroPython |
minimal/ |
MicroPthon的最小集,用於移植到其餘微處理器 |
tests/ |
測試框架和測試腳本 |
docs/ |
MicroPython官方的reStructuredText文檔資料。地址:http://docs.micropython.org |
bare-arm/ |
在ARM上MicroPython的最小版本 |
teensy/ |
在Teensy 3.1上運行的MicroPython |
pic16bit/ |
在16 位 PIC 微控制器上運行的MicroPython |
esp8266/ |
在ESP8266 WIFI模塊上運行的MicroPython |
extmod/ |
C 實現的模塊 |
tools/ |
各類工具 |
examples/ |
Python腳本實例 |
READ.md |
說明文檔 |
開始編譯固件
本人的系統環境:ubuntu15.0464位系統
Ubuntu官網:http://cn.ubuntu.com/?_ga=2.264511627.56850772.1502953593-1795108721.1502953593
一、安裝arm-none-eabi-gcc交叉編譯工具和gcc編譯器
打開終端執行命令
sudo apt-get install gcc-arm-none-eabi sudo apt-get install gcc
二、下載micropython的源碼包
我放在了/opt目錄下
git clone --recursive https://github.com/micropython/micropython.git
等待git完畢,進入stmhal/boards/目錄下,裏面又根據不一樣型號的芯片進行了分類。
三、開始編譯
切換到stmhal目錄
cd /opt/micropython/stmhal
執行編譯命令,等待編譯完成。
make BOARD=PYBV10
BOARD參數爲stmhal/boards/目錄下相應的開發板名稱。
本次教程用的是TPYBoardv102(藍色)開發板,兼容PYBV10,因此選擇PYBV10開發板繼續編譯。
如果TPYBoardv102(綠色)基礎板,一樣選擇PYBV10。
如果TPYBoardv102(黑色)開發板,需選擇PYBV11。
編譯成功。生成的固件文件stmhal/build-PYBV10/firmware.dfu和firmware.hex。
四、燒寫固件
請參考教程:http://tpyboard.com/support/reference11/302.html
增長自定義類庫
使用過micropython的小夥伴都知道,裏面有一個重要的模塊pyb。下面咱們就嘗試在micropython源碼中新建一個名爲tpyboard的pyb子類,裏面添加一個簡單的函數display,輸出一句」HelloTPYBoard」。
五、首先大致來看一下stmhal目錄下的各類.c和.h文件。基本上根據他們的名稱就能判斷出功能來。
六、先來參考一下led.c文件,瞭解一下大致的流程。
找到了led_obj_on函數,這就是咱們平時用的pyb.LED(1).on()
/// Turn the LED on mp_obj_t led_obj_on(mp_obj_t self_in) { pyb_led_obj_t *self = self_in; led_state(self->led_id, 1); return mp_const_none; }
聲明註冊一下on函數,MP_DEFINE_CONST_FUN_OBJ_1最後的數字跟參數的數量相對應。
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
再往下能夠看到led_locals_dict_table,將上面聲明的函數添加到led模塊函數字典中。
STATIC const mp_rom_map_elem_t led_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj) }, { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj) }, { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj) }, { MP_ROM_QSTR(MP_QSTR_intensity), MP_ROM_PTR(&led_obj_intensity_obj) }, }; STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
創建micropython對象,遵循如下原則。
const mp_obj_type_t pyb_led_type = { { &mp_type_type }, .name = MP_QSTR_LED, .print = led_obj_print, .make_new = led_obj_make_new, .locals_dict = (mp_obj_dict_t*)&led_locals_dict, };
七、接下來咱們在stmhal目錄下新建一個tpyboard.c文件,內容以下:
#include <stdio.h> #include "py/nlr.h" #include "py/runtime.h" #include "py/mphal.h" mp_obj_t tpyboard_obj_display() { printf("Hello TPYBoard\n"); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_0(tpyboard_obj_display_obj, tpyboard_obj_display); STATIC const mp_rom_map_elem_t tpyboard_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_display), MP_ROM_PTR(&tpyboard_obj_display_obj) }, }; STATIC MP_DEFINE_CONST_DICT(tpyboard_locals_dict, tpyboard_locals_dict_table); const mp_obj_type_t pyb_tpyboard_type = { { &mp_type_type }, .name = MP_QSTR_tpyboard, .locals_dict = (mp_obj_dict_t*)&tpyboard_locals_dict, };
八、新建tpyboard.h文件,內容以下:
extern const mp_obj_type_t pyb_tpyboard_type;
找到modpyb.c文件,將tpybaord子模塊添加到pyb的pyb_module_globals_table[]子類表中。
{ MP_ROM_QSTR(MP_QSTR_tpyboard), MP_ROM_PTR(&pyb_tpyboard_type) },
記得在modpyb.c中添加tpyboard.h的引用。
#include "tpyboard.h"
九、添加完畢後,將tpyboard.c文件添加到Makefile文件中,進行編譯。我就直接放到了led.c\下面。
SRC_C = \ main.c \ system_stm32.c \ stm32_it.c \ usbd_conf.c \ usbd_desc.c \ usbd_cdc_interface.c \ usbd_hid_interface.c \ usbd_msc_storage.c \ mphalport.c \ mpthreadport.c \ irq.c \ pendsv.c \ systick.c \ pybthread.c \ timer.c \ led.c \ tpyboard.c \ pin.c \ pin_defs_stmhal.c \ pin_named_pins.c \ bufhelper.c \ dma.c \ i2c.c \ spi.c \ uart.c \ can.c \ usb.c \ wdt.c \ gccollect.c \ help.c \ machine_i2c.c \ modmachine.c \ modpyb.c \ modstm.c \ moduos.c \ modutime.c \ modusocket.c \ modnetwork.c \ extint.c \ usrsw.c \ rng.c \ rtc.c \ flash.c \ storage.c \ sdcard.c \ fatfs_port.c \ lcd.c \ accel.c \ servo.c \ dac.c \ adc.c \ $(wildcard boards/$(BOARD)/*.c)
十、執行命令開始編譯,編譯經過,從新將編譯好的固件燒寫到TPYBoard開發板上。
十一、燒寫完畢後,用putty鏈接TPYBoardv102,輸入如下內容:
pyb.tpyboard.display()