相對於上一篇調試日志,本文會在mm32f3平台上重現mm32f5平台上的操作,並且梳理一下文檔。之前的調試日志記錄的是試驗的過程,本文直接講述實踐方法。
總體的思路是:
MicroPython加載lfs使用了同之前加載fatfs不同的方式,通過向固件程序中集成Python語言編寫的腳本來加載lfs文件系統。在C語言編寫的MicroPython固件中加載Python語言程序的機制,就是所謂的“frozen”。在本節中,期望實現frozen機制,先引導一個普通的Python腳本文件,實現在啟動REPL之前閃爍電路板小燈的功能。在後續准備好底層文件系統後,再將引導Python文件中的內容替換成加載文件系統的腳本。
在ports/mm32f3-lfs-spiflash/boards目錄下創建manifest.py文件,指定編譯工程的過程中,預先處理ports/mm32f3-lfs-spiflash/modules目錄下的Python源文件。實際上,ports/mm32f3-lfs-spiflash/modules目錄下已經創建了_boot.py文件。
編寫manifest.py文件內容有:
freeze("$(PORT_DIR)/modules")
在ports/mm32f3-lfs-spiflash/boards/plus-f3270/mpconfigboard.mk文件中,添加腳本,引用新建的manifest.py文件,將其集成在編譯工程的過程中。
在已有mpconfigboard.mk文件中添加腳本:
FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py
在現有移植項目的mpconfigport.h文件中,添加配置宏,啟用MicroPython內核中的frozen機制:
#define MICROPY_MODULE_FROZEN (1) /* enable pyexec_frozen_module() in pyexec.c */
#define MICROPY_MODULE_FROZEN_MPY (1)
在現有移植項目中的main.c文件中,刪除原有從sd卡加載文件系統相關的代碼,在固件的執行過程中添加執行_boot.py腳本的語句:
#include "lib/mp-readline/readline.h"
...
int main(void)
{
...
for (;;)
{
...
// Initialise sub-systems.
readline_init0();
// Execute _boot.py to set up the filesystem.
pyexec_frozen_module("_boot.py");
...
}
}
試著編一下整個項目,應該是能編通的:
[email protected] MSYS /d/_git_repos/micropython-su/micropython-1.16/ports/mm32f3-lfs-spiflash
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-plus-f3270/genhdr/qstrdefs.collected.h
QSTR not updated
mkdir -p build-plus-f3270/build-plus-f3270/
MPY _boot.py
GEN build-plus-f3270/frozen_content.c
CC build-plus-f3270/frozen_content.c
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
135084 860 3396 139340 2204c build-plus-f3270/firmware.elf
從輸出的信息中可以看到,編譯過程已經處理了_boot.py
文件,生成並編譯了fromzen_content.c
文件。
再試著改寫_boot.py
文件,控制板子上的小燈閃爍,以驗證frozen的功能已經啟用。
改寫_boot.py
文件內容如下:
import time
from machine import Pin
led0 = Pin('PH2', mode=Pin.OUT_PUSHPULL, value=1)
for i in range(10):
time.sleep_ms(100)
led0(1-led0())
重新編譯,下載,運行。實際可以看到板子上的LED燈閃了5次,之後進入REPL。驗證frozen功能已經正常啟用。
sfud組件是一個開源的管理spiflash存儲芯片的組件,面向市面上主流的spiflash存儲芯片,提供一系列例如初始化、擦除塊、讀塊、寫塊等標准操作接口。使用sfud訪問spiflash存儲芯片,而不是直接使用spiflash存儲芯片的驅動程序,可以提高上層應用對底層設備的抽象程度,便於復用代碼。在很多基於微控制器的SDK軟件包中,都提供了sfud的移植樣例工程,這就為在MicroPython中通過sfud使用spiflash存儲芯片提供了便利。
在MicroPython代碼包的\lib
目錄下創建sfud
目錄,將sfud組件的源碼復制在其中:
另外,還需要在具體移植板子項目的目錄\ports\mm32f3-lfs-spiflash\boards\plus-f3270
下,添加sfud組件的移植源程序文件:
新添加的這兩個文件在MindSDK中plus-f3270板子的spiflash_sfud_spi樣例工程中都可以找到。
還有一個細節,需要更新\ports\mm32f3-lfs-spiflash\boards\plus-f3270
目錄下配置板子相關的文件。
board_init.h
文件,定義SPI接口的映射:/* SPI3. */
#define BOARD_FLASH_SPI_PORT SPI2
#define BOARD_FLASH_SPI_BAUDRATE 400000u /* 400khz. */
#define BOARD_FLASH_SPI_FREQ CLOCK_APB1_FREQ
#define BOARD_FLASH_CS_GPIO_PORT GPIOE
#define BOARD_FLASH_CS_GPIO_PIN GPIO_PIN_3
clock_init.c
文件,啟用總線訪問SPI外設的時鐘:void BOARD_InitBootClocks(void)
{
...
/* SPI2. */
RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_SPI2, true);
RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_SPI2);
}
pin_init.c
文件,配置SPI外設引腳復用功能:void BOARD_InitPins(void)
{
...
/* PE3 - SPI_CS. */
gpio_init.Pins = GPIO_PIN_3;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &gpio_init);
GPIO_PinAFConf(GPIOE, gpio_init.Pins, GPIO_AF_15);
GPIO_SetBits(GPIOE, gpio_init.Pins);
/* PB10 - SPI_SCK. */
gpio_init.Pins = GPIO_PIN_10;
gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5);
/* PB14 - SPI_MISO. */
gpio_init.Pins = GPIO_PIN_14;
gpio_init.PinMode = GPIO_PinMode_In_PullUp;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5);
/* PB15 - SPI_MOSI. */
gpio_init.Pins = GPIO_PIN_15;
gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_5);
}
將新增sfud組件及移植源程序的文件添加到Makefile文件中,進入編譯過程。
# includepath.
...
INC += -I$(TOP)/lib/sfud
...
SRC_BRD_C += \
...
$(BOARD_DIR)/sfud_port.c \
...
...
SRC_C += \
...
lib/sfud/sfud.c \
lib/sfud/sfud_sfdp.c \
...
...
編譯一下工程,確保當前添加到MicroPython中的代碼不會產生編譯錯誤。
[email protected] MSYS /d/_git_repos/micropython-su/micropython-1.16/ports/mm32f3-lfs-spiflash
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-plus-f3270/genhdr/qstrdefs.collected.h
QSTR not updated
CC boards/plus-f3270/sfud_port.c
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
135056 860 3396 139312 22030 build-plus-f3270/firmware.elf
MicroPython的lfs文件系統,實際上僅僅是一個文件系統框架,並沒有像fatfs一樣,通過源代碼靜態綁定。因此,可以獨立啟用lfs組件,而暫不實現具體的移植。
lfs組件相關的源碼,已經存放在MicroPython代碼倉庫的\extmod
目錄下。在現有工程的mpconfigboard.mk文件中,添加 配置開關,讓編譯過程能夠編譯lfs相關的源代碼。
MICROPY_VFS_LFS2 ?= 1
在現有移植項目的mpconfigport.h文件中,添加配置宏,啟用MicroPython內核中的lfs組件,並添加部分映射對象:
// Use VfsLfs2's types for fileio/textio
#define mp_type_fileio mp_type_vfs_lfs2_fileio
#define mp_type_textio mp_type_vfs_lfs2_textio
這是為了在os類模塊中,向vfs(虛擬文件系統,virtual file system)綁定io過程使用lfs相關的方法。
在後面集成實驗時,發現os類模塊的幾個函數尚未實現,趕緊在這裡補充說明。
在現有移植項目的moduos.c文件中,解鎖os類模塊中與vfs相關的屬性方法,特別是mount()和VfsLfs2()。
...
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "extmod/vfs_lfs.h"
...
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{
MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
//{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) },
{
MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
{
MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
{
MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) },
{
MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
{
MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
{
MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
{
MP_ROM_QSTR(MP_QSTR_rename),MP_ROM_PTR(&mp_vfs_rename_obj)},
{
MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
{
MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
{
MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
{
MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
{
MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mod_os_sync_obj) },
#if 1 /* unlock for vfs and lfs. */
/// \constant sep - separation character used in paths
{
MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
#if MICROPY_HW_ENABLE_RNG
{
MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) },
#endif
// these are MicroPython extensions
//{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&uos_dupterm_obj) },
{
MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
{
MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
#endif
#if MICROPY_VFS_FAT
{
MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
#endif
#if MICROPY_VFS_LFS1
{
MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) },
#endif
#if MICROPY_VFS_LFS2
{
MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) },
#endif
};
試著編譯一下當前的移植工程,報錯,說在lfs_get_mtime函數中引用的mp_hal_time_ns函數未被定義。
CC mphalport.c
CC ../../lib/mp-readline/readline.c
CC ../../lib/utils/gchelper_native.c
CC ../../lib/utils/pyexec.c
CC ../../lib/utils/stdout_helpers.c
CC ../../lib/timeutils/timeutils.c
CC fatfs_port.c
CC boards/plus-f3270/machine_pin_board_pins.c
CC ../../drivers/bus/softspi.c
LINK build-plus-f3270/firmware.elf
C:\msys64\usr\gcc-arm-none-eabi-10-2020-q4-major\bin\arm-none-eabi-ld.exe: build-plus-f3270/extmod/vfs_lfs.o: in function `lfs_get_mtime': vfs_lfs.c:(.text.lfs_get_mtime+0x4): undefined reference to `mp_hal_time_ns'
make: *** [Makefile:213: build-plus-f3270/firmware.elf] Error 1
顧名思義,lfs_get_mtime函數是為lfs創建文件時提供時間戳信息的,對主要功能影響不大,所以可以用一個“假”的實現消除錯誤。在mphalport.h文件中定義mp_hal_time_ns函數:
/* return the current ns from very start. */
static inline uint64_t mp_hal_time_ns(void)
{
return 0u;
}
再編譯一次,就應該通過了。
[email protected] MSYS /d/_git_repos/micropython-su/micropython-1.16/ports/mm32f3-lfs-spiflash
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
CC ../../py/mpprint.c
CC ../../py/modmicropython.c
CC ../../extmod/moduasyncio.c
CC ../../extmod/machine_pulse.c
CC ../../extmod/machine_i2c.c
CC ../../extmod/machine_spi.c
CC ../../extmod/modbluetooth.c
CC ../../extmod/vfs_posix.c
CC ../../extmod/vfs_posix_file.c
CC ../../extmod/vfs_fat_diskio.c
CC ../../extmod/vfs_lfs.c
CC ../../extmod/utime_mphal.c
CC ../../lib/utils/printf.c
CC modmachine.c
CC machine_spi.c
CC machine_i2c.c
CC mphalport.c
CC ../../lib/mp-readline/readline.c
CC ../../lib/utils/pyexec.c
CC ../../lib/utils/stdout_helpers.c
CC boards/plus-f3270/machine_pin_board_pins.c
CC ../../drivers/bus/softspi.c
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
174792 988 10572 186352 2d7f0 build-plus-f3270/firmware.elf
這裡需要創建一個同具體芯片平台相關的類模塊,用以包含flash子類。實際上,這個flash可以是片內flash,也可以是片外flash。早期的MicroPython是運行在使用STM32F4微控制器作為主控芯片的PyBoard上,PyBoard板子沒有搭載片外flash,就是用片內flash加載文件系統,因此,將flash作為芯片平台子類的做法就作為傳統保留了下來。
在\ports\mm32f3-lfs-spiflash
目錄下創建mm32f3_flash.c
文件,用於實現flash子類。flash子類中必須要實現的幾個函數,包括make_new()、readblocks()、writeblocks()和ioctl,內部都是通過調用sfud組件的接口訪問底層的spiflash存儲芯片。spiflash存儲芯片的差異性已經被sfud覆蓋掉了,所以實際上,當我從mm32f5移植項目(一個使用sfud組件訪問qspiflash存儲芯片的項目)中復制出mm32f5_flash.c
文件時,只是將其中的mm32f5
的字符串改成了mm32f3
,並停用了其中一個激活4線SPI功能的sfud調用而已。
...
STATIC const mp_rom_map_elem_t mm32f3_flash_locals_dict_table[] = {
{
MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&mm32f3_flash_readblocks_obj) },
{
MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&mm32f3_flash_writeblocks_obj) },
{
MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mm32f3_flash_ioctl_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mm32f3_flash_locals_dict, mm32f3_flash_locals_dict_table);
const mp_obj_type_t mm32f3_flash_type = {
{
&mp_type_type },
.name = MP_QSTR_Flash,
.make_new = mm32f3_flash_make_new,
.locals_dict = (mp_obj_dict_t *)&mm32f3_flash_locals_dict,
};
至於xxxx_flash.c文件中各個屬性方法的實現方法和內容,可以參閱具體的代碼。
前文提到,flash類模塊需要作為同主控芯片相關的一個類的子類集成在MicroPython內核中。這裡就創建一個僅包含flash類模塊的mm32f3類模塊。
創建modmm32f3.c文件,並編寫代碼:
#include "py/runtime.h"
#include "modmm32f3.h"
STATIC const mp_rom_map_elem_t mm32f3_module_globals_table[] = {
{
MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mm32f3) },
{
MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&mm32f3_flash_type) },
};
STATIC MP_DEFINE_CONST_DICT(mm32f3_module_globals, mm32f3_module_globals_table);
const mp_obj_module_t mp_module_mm32f3 = {
.base = {
&mp_type_module },
.globals = (mp_obj_dict_t *)&mm32f3_module_globals,
};
創建modmm32f3.h文件,並編寫代碼:
#ifndef MICROPY_INCLUDED_MM32F3_MODMM32F3_H
#define MICROPY_INCLUDED_MM32F3_MODMM32F3_H
#include "py/obj.h"
extern const mp_obj_type_t mm32f3_flash_type;
extern const mp_obj_module_t mp_module_mm32f3;
#endif // MICROPY_INCLUDED_MM32F3_MODMM32F3_H
將新建的mm32f3
模塊添加到MicroPython內核的內建模塊當中。
在當前移植項目的mpconfigport.h文件中,添加源代碼:
...
extern const struct _mp_obj_module_t mp_module_mm32f3;
#define MICROPY_PORT_BUILTIN_MODULES \ ...
{
MP_ROM_QSTR(MP_QSTR_mm32f3), MP_ROM_PTR(&mp_module_mm32f3) }, \
...
在當前移植項目的Makefile中,添加新建文件:
...
SRC_C += \
...
modmm32f3.c \
mm32f3_flash.c \
...
# list of sources for qstr extraction
SRC_QSTR += modmachine.c \
...
modmm32f3.c \
mm32f3_flash.c \
...
試著編譯一下當前的移植工程,應該是可以編通不報錯的。
[email protected] MSYS /d/_git_repos/micropython-su/micropython-1.16/ports/mm32f3-lfs-spiflash
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-plus-f3270/genhdr/qstr.i.last
GEN build-plus-f3270/genhdr/qstr.split
GEN build-plus-f3270/genhdr/qstrdefs.collected.h
QSTR updated
...
CC mm32f3_flash.c
CC modmm32f3.c
...
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
141004 988 3916 145908 239f4 build-plus-f3270/firmware.elf
此時,可以將固件下載到板子上,然後試著手工在REPL中逐行輸入腳本加載文件系統。在REPL中輸入Python腳本進行單步調試,如下:
MicroPython v1.16 on 2022-07-30; PLUS-F3270 with MM32F3277G9P
Type "help()" for more information.
>>>
>>>
>>>
>>>
>>> import os
>>> dir(os)
['__name__', 'remove', 'sep', 'VfsFat', 'VfsLfs2', 'chdir', 'getcwd', 'ilistdir', 'listdir', 'mkdir', 'mount', 'rename', 'rmdir', 'stat', 'statvfs', 'sync', 'umount', 'unlink']
>>> import mm32f3
>>> dir(mm32f3)
['__name__', 'Flash']
>>> bdev=mm32f3.Flash()
[SFUD](../../lib/sfud/sfud.c:116) Start initialize Serial Flash Universal Driver(SFUD) V1.1.0.
[SFUD](../../lib/sfud/sfud.c:117) You can get the latest version on https://github.com/armink/SFUD .
[SFUD](../../lib/sfud/sfud.c:865) The flash device manufacturer ID is 0xFF, memory type ID is 0xFF, capacity ID is 0xFF.
[SFUD](../../lib/sfud/sfud_sfdp.c:131) Check SFDP header is OK. The reversion isV1.0, NPN is 0.
[SFUD](../../lib/sfud/sfud_sfdp.c:173) Check JEDEC basic flash parameter headeris OK. The table id is 0, reversion is V1.0, length is 9, parameter table pointer is 0x000080.
[SFUD](../../lib/sfud/sfud_sfdp.c:203) JEDEC basic flash parameter table info:
[SFUD](../../lib/sfud/sfud_sfdp.c:204) MSB-LSB 3 2 1 0
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0001] 0xFF 0xF1 0x20 0xE5
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0002] 0x07 0xFF 0xFF 0xFF
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0003] 0x6B 0x08 0xEB 0x44
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0004] 0xBB 0x42 0x3B 0x08
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0005] 0xFF 0xFF 0xFF 0xFE
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0006] 0x00 0x00 0xFF 0xFF
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0007] 0xEB 0x21 0xFF 0xFF
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0008] 0x52 0x0F 0x20 0x0C
[SFUD](../../lib/sfud/sfud_sfdp.c:206) [0009] 0x00 0x00 0xD8 0x10
[SFUD](../../lib/sfud/sfud_sfdp.c:215) 4 KB Erase is supported throughout the device. Command is 0x20.
[SFUD](../../lib/sfud/sfud_sfdp.c:234) Write granularity is 64 bytes or larger.
[SFUD](../../lib/sfud/sfud_sfdp.c:245) Target flash status register is non-volatile.
[SFUD](../../lib/sfud/sfud_sfdp.c:271) 3-Byte only addressing.
[SFUD](../../lib/sfud/sfud_sfdp.c:305) Capacity is 16777216 Bytes.
[SFUD](../../lib/sfud/sfud_sfdp.c:311) Flash device supports 4KB block erase. Command is 0x20.
[SFUD](../../lib/sfud/sfud_sfdp.c:311) Flash device supports 32KB block erase. Command is 0x52.
[SFUD](../../lib/sfud/sfud_sfdp.c:311) Flash device supports 64KB block erase. Command is 0xD8.
[SFUD]Find a flash chip. Size is 16777216 bytes.
[SFUD](../../lib/sfud/sfud.c:844) Flash device reset success.
[SFUD]SPI Flash flash device is initialize success.
>>> os.VfsLfs2.mkfs(bdev, progsize=256)
>>> vfs=os.VfsLfs2(bdev, progsize=256)
>>> os.mount(vfs,'/')
>>> os.listdir()
[]
>>> with open('hello', 'w') as f:
... f.write('hello')
...
5
>>> os.listdir()
['hello']
>>> os.sync()
>>> os.listdir()
['hello']
>>>
看起來,文件系統已經准備好了。接下來就是讓MicroPython啟動的時候自動加載文件系統。
改寫_boot.py文件加載lfs
將上述手動加載文件系統的腳本寫到之前創建的_boot.py
文件中:
import os
import mm32f3
bdev = mm32f3.Flash()
try:
vfs = os.VfsLfs2(bdev, progsize=256)
except:
os.VfsLfs2.mkfs(bdev, progsize=256)
vfs = os.VfsLfs2(bdev, progsize=256)
os.mount(vfs, "/")
重新編譯工程,正常情況下應該通過編譯,無錯誤。
此時整個工程已經基本移植成功了,可以關掉sfud的調試選項。重新編譯工程,下載固件到開發板,在REPL中可以看到,在歡迎信息之前沒有報錯信息,系統正常被加載。
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-plus-f3270/genhdr/qstrdefs.collected.h
QSTR not updated
CC mm32f3_flash.c
CC ../../lib/sfud/sfud.c
CC ../../lib/sfud/sfud_sfdp.c
CC boards/plus-f3270/sfud_port.c
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
169528 988 10316 180832 2c260 build-plus-f3270/firmware.elf
下載代碼運行。
嘗試通過Thonny創建Python腳本文件,保存到MicroPython設備上。
如圖1所示,當要使用Thonny保存Python腳本文件時,Thonny的文件浏覽器已經可以看到之前實驗中創建的hello文件了。嘗試保存新腳本為main.py文件,是成功的。至此,說明移植成功。大功告成。
啟用文件系統之後,為了方便用戶使用,還需要繼續做兩件事:
在MicroPython的啟動過程中,添加執行boot.py和main.py文件的流程,位於進入REPL之前:
pyexec_file_if_exists("boot.py");
重新編譯工程,並下載到開發板中。
[email protected] MSYS /d/_git_repos/micropython-su/micropython-1.16/ports/mm32f3-lfs-spiflash
$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-plus-f3270/genhdr/qstrdefs.collected.h
QSTR not updated
CC main.c
LINK build-plus-f3270/firmware.elf
text data bss dec hex filename
169588 988 10316 180892 2c29c build-plus-f3270/firmware.elf
注意,這裡不能在main.c中直接執行main.py文件,需要通過boot.py有條件地引導進入main.py。
在Thonny IDE中新建boot.py文件,並保存到MicroPython設備中。boot.py文件源碼如下:
from machine import Pin
btn = Pin('PG15', mode=Pin.IN_PULLUP)
if 0==btn():
print('skip main.py')
else:
if 'main.py' in os.listdir():
import main
else:
print('no main.py in filesystem')
現在可以通過開發板上的撥碼開關選擇啟動MicroPython之後,在進入REPL之前,是否跳過可能包含無限循環的main.py。
最後,附送預編譯好的MicroPython可執行文件:https://download.csdn.net/download/suyong_yq/86267405
完整的項目源代碼,見gitee.com上的開源代碼庫:https://gitee.com/suyong_yq/micropython-su,其中的ports/mm32f3-lfs-spiflash。