背景:
STEVAL-DRONE01上にSTM32F401CCが搭載されていて、普通にCとかRUSTとかで開発するにはサイズの問題が出ないと思うが、センサのデータ処理や姿勢制御アルゴリズムについて試行錯誤したいのでSTM32F401CC上でMicroPythonを動かしたいと思っている。が、マイコンに内蔵されているFlashMemoryが256KBのため、普通にビルドしたMicroPythonではサイズが大きすぎて搭載できない。だから、、他の省リソースマイコン用のMicroPythonをベースにSTM32F401CC用のMicroPythonをカスタマイズして動かそうとしている。。が、、動かない。そこで、ST-LINK経由でOpenOCD + GDBでデバッグ中
以下のコマンドでOpenOCDとgdbを起動
./bin-x64/openocd.exe -f ./scripts/interface/stlink-v2.cfg -f ./scripts/target/stm32f4x.cfg
/usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-gdb.exe ./build-NUCLEO_L073RZ_KAI2/firmware.elf
gdbのセットアップとロード
target remote localhost:3333 monitor reset halt load hbreak stm32_main cont
stm32_mainで一旦止めて、Cソース行の単位でステップ実行
320 MICROPY_BOARD_STARTUP(); (gdb) n 320 MICROPY_BOARD_STARTUP(); (gdb) n 367 HAL_InitTick(TICK_INT_PRIORITY); (gdb) n 370 SystemClock_Config(); (gdb) n Breakpoint 4, stm32_main (reset_mode=0) at main.c:312 312 SCB->VTOR = MICROPY_HW_VTOR; (gdb) n 316 SCB->CCR |= SCB_CCR_STKALIGN_Msk; (gdb) n 320 MICROPY_BOARD_STARTUP(); (gdb) n 367 HAL_InitTick(TICK_INT_PRIORITY); (gdb) n 370 SystemClock_Config(); (gdb) n Breakpoint 4, stm32_main (reset_mode=0) at main.c:312 312 SCB->VTOR = MICROPY_HW_VTOR; (gdb)
スタートアップの所でグルグル回っているようだ。ステップ実行で調べると、FLASH->ACRの値を変更しようとしてハードフォールトが発生している。多分番地が正しく設定されていないからでは?と推測
(gdb) n 109 FLASH->ACR |= FLASH_ACR_LATENCY; (gdb) n HardFault_Handler () at stm32_it.c:213 213 __asm volatile (
FLASHのが多分レジスタ用構造体の開始番地で->ACRでオフセットの番地を計算しているのだろうと推測。FLASHはマクロか何かで置換されているのか、シンボル不明になっている。
104 void SystemClock_Config(void) { 105 // Enable power control peripheral 106 __HAL_RCC_PWR_CLK_ENABLE(); 107 108 // Set flash latency to 1 because SYSCLK > 16MHz (gdb) l 109 FLASH->ACR |= FLASH_ACR_LATENCY; 110 111 // Enable the 16MHz internal oscillator 112 RCC->CR |= RCC_CR_HSION; 113 while (!(RCC->CR & RCC_CR_HSIRDY)) { 114 } 115 116 // Use HSI16 and the PLL to get a 32MHz SYSCLK 117 RCC->CFGR = 1 << RCC_CFGR_PLLDIV_Pos | 1 << RCC_CFGR_PLLMUL_Pos; 118 RCC->CR |= RCC_CR_PLLON; (gdb) p/x FLASH No symbol "FLASH" in current context. (gdb) disas $pc,+16 Dump of assembler code from 0x8023912 to 0x8023922: => 0x08023912 <SystemClock_Config+14>: ldr r2, [pc, #88] ; (0x802396c <SystemClock_Config+104>) 0x08023914 <SystemClock_Config+16>: ldr r1, [r2, #0] 0x08023916 <SystemClock_Config+18>: movs r0, #1 0x08023918 <SystemClock_Config+20>: orrs r1, r0 0x0802391a <SystemClock_Config+22>: str r1, [r2, #0] 0x0802391c <SystemClock_Config+24>: ldr r2, [r3, #0] 0x0802391e <SystemClock_Config+26>: orrs r2, r0 0x08023920 <SystemClock_Config+28>: str r2, [r3, #0] End of assembler dump. (gdb)
逆アセンブルを見てもイマイチどれがどう対応しているのか不明。だから、、nextiで機械語単位でステップをかけて落ちた所の操作対象レジスタが誤った番地だろうと推測。
アドレス: 0x08023914を実行した時点でハードフォールトになったので、この命令でしくじっていると判断。
(gdb) nexti 0x08023914 109 FLASH->ACR |= FLASH_ACR_LATENCY; 0x08023912 <SystemClock_Config+14>: 16 4a ldr r2, [pc, #88] ; (0x802396c <SystemClock_Conf ig+104>) => 0x08023914 <SystemClock_Config+16>: 11 68 ldr r1, [r2, #0] 0x08023916 <SystemClock_Config+18>: 01 20 movs r0, #1 0x08023918 <SystemClock_Config+20>: 01 43 orrs r1, r0 0x0802391a <SystemClock_Config+22>: 11 60 str r1, [r2, #0] (gdb) i r r0 0x0 0 r1 0x0 0 r2 0x40022000 1073881088 r3 0x40021000 1073876992 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0xe000ed00 -536810240 sp 0x2000ffb8 0x2000ffb8 lr 0x8022c8f 134360207 pc 0x8023914 0x8023914 <SystemClock_Config+16> xPSR 0x1000000 16777216 (gdb) nexti HardFault_Handler () at stm32_it.c:213 213 __asm volatile ( => 0x08022fd8 <HardFault_Handler+0>: 70 46 mov r0, lr 0x08022fda <HardFault_Handler+2>: c0 08 lsrs r0, r0, #3 0x08022fdc <HardFault_Handler+4>: ef f3 08 80 mrs r0, MSP 0x08022fe0 <HardFault_Handler+8>: 01 d3 bcc.n 0x8022fe6 <HardFault_Handler+14> 0x08022fe2 <HardFault_Handler+10>: ef f3 09 80 mrs r0, PSP 0x08022fe6 <HardFault_Handler+14>: 85 e7 b.n 0x8022ef4 <HardFault_C_Handler>
推測だが、間接アドレッシングで、r2で示される番地にr1の値を入れると。r2の値が0x40022000 なので、
この値がFLASHレジスタのベースアドレスと解釈してビルドされているのだろう。多分。
=> 0x08023914 <SystemClock_Config+16>: 11 68 ldr r1, [r2, #0]
STM32L073のFLASHレジスタの番地と、STM32F401のレジスタの番地が違ってるのではなかろうか。。
STM32L0x3 の仕様書を確認すると、0x4002_2000からFLASH Registerの領域で、オフセット0の番地が、FLASH_ACRとなっている。だから、STM32L073としての動作は正しい。一方、STM32F401CCの場合、FLASH InterfaceRegisterの領域は、0x4002 3C00 である。だから、間違った領域に値を書こうとしている。ちなみに、0x4002_2000はAHB用のレジスタ空間だけど、該当の番地にはレジスタが存在しない。だからアクセス異常になってリセットがかかったのだろう。これらのアドレス解決はソースを見ないと確実には分からないが、build用のマイコンシリーズ定義に従いifdefで切り替えられていると思う。マイコンシリーズ定義は、STM32L073を指定する、l0 (エルゼロ)を設定しているので、レジスタ群の番地がSTM32L073として解決されていると思う。悩みポイントとしては、マイコンシリーズ定義を本来のf0(エフゼロ)にしてしまうと、高機能関数群が一度に入ってくるので、サイズが大きくなってしまう。切り離しもむつかしい(中途半端に切り離すとシンボル未定義エラーになる)
やりたいこと:
サイズが大きくなるようなモリモリの機能はいらないから、レジスタマップだけはF401に合わせたい。だけど、レジスタマップと機能はペアで実装されるものだから、切り離して実装するのは無理だろう。。多分。
今回問題になっている、SystemClock_Config (file:powercontrolboot.c)のソースを確認すると、STM32L0のifdefが存在し、やはりマイコン種別として間違ったルーチンが呼び出されいる。STM32F4のマクロが有効になった状態でビルドされるようにしないと、正しい初期化等ができない。
#elif defined(STM32L0) void SystemClock_Config(void) { // Enable power control peripheral __HAL_RCC_PWR_CLK_ENABLE(); // Set flash latency to 1 because SYSCLK > 16MHz FLASH->ACR |= FLASH_ACR_LATENCY; // Set flash latency to 1 because SYSCLK > 24MHz FLASH->ACR = (FLASH->ACR & ~0x7) | 0x1;
マイコンシリーズの異なるSTM32L072RZをベースに、STM32F101CCに持っていくアプローチはif defが異なりすぎてなかなかまともにビルドできないので、STM32F401REから機能を削ってサイズを減らすアプローチに変更した。
この場合、エラーが出たら、機能を有効化すればよいので、ビルドエラーは容易に回避可能であるが、やはり、F4シリーズの場合ベースのビルドでは機能モリモリでサイズが大きくなる傾向が強く、ifdefで機能を削る程度ではあまり効果が得られない。ということで、、機能を付けたり減らしたりという程度ではなかなか小サイズのMicroPythonを作り出すのは難しいことが分かった。(MicroPython自体、機能を自由に選択してマイコンのFlashサイズにフィットさせるような考えでは作られていないので)
$ make BOARD=NUCLEO_F401CC V=1 DEBUG=1 *略* arm-none-eabi-ld: build-NUCLEO_F401CC/firmware.elf section `.text' will not fit in region `FLASH_TEXT' arm-none-eabi-ld: region `FLASH_TEXT' overflowed by 150800 bytes arm-none-eabi-ld: build-NUCLEO_F401CC/modpyb.o:(.rodata.pyb_module_globals_table+0x7c): undefined reference to `pyb_flash_type' make: *** [Makefile:714: build-NUCLEO_F401CC/firmware.elf] Error 1
$ make BOARD=NUCLEO_F401CC V=1 arm-none-eabi-size build-NUCLEO_F401CC/firmware.elf text data bss dec hex filename 254968 12 37140 292120 47518 build-NUCLEO_F401CC/firmware.elf GEN build-NUCLEO_F401CC/firmware0.bin arm-none-eabi-objcopy -O binary -j .isr_vector build-NUCLEO_F401CC/firmware.elf build-NUCLEO_F401CC/firmware0.bin GEN build-NUCLEO_F401CC/firmware1.bin arm-none-eabi-objcopy -O binary -j .text -j .data -j .ARM build-NUCLEO_F401CC/firmware.elf build-NUCLEO_F401CC/firmware1.bin GEN build-NUCLEO_F401CC/firmware.dfu python3 ../../tools/dfu.py -D 0x0483:0xDF11 -b 0x08000000:build-NUCLEO_F401CC/firmware0.bin -b 0x08020000:build-NUCLEO_F401CC/firmware1.bin build-NUCLEO_F401CC/firmware.dfu GEN build-NUCLEO_F401CC/firmware.hex arm-none-eabi-objcopy -O ihex build-NUCLEO_F401CC/firmware.elf build-NUCLEO_F401CC/firmware.hex
ST-Link Utilityでファームは焼けた
21:23:51 : ST-LINK SN : 18470000000000000 21:23:51 : V2J29S7 21:23:51 : Connected via SWD. 21:23:51 : SWD Frequency = 4,0 MHz. 21:23:51 : Connection mode : Normal. 21:23:51 : Debug in Low Power mode enabled. 21:23:52 : Device ID:0x423 21:23:52 : Device flash Size : 256KBytes 21:23:52 : Device family :STM32F401xB/C 21:24:01 : [firmware.hex] opened successfully. Address Ranges [0x08000000 0x080039D0] [0x08005000 0x0803FA34] 21:24:01 : [firmware.hex] checksum : 0x017CD635 21:24:15 : Memory programmed in 7s and 47ms.
焼くには焼いたが、、動かしてみるとやっぱりおかしい。デバッグ情報付いていないので詳細は分からないが、再起動を繰り返している印象。またどこかでアドレスの不一致か、あるいは、Flashメモリの使い方のまずさか?により異常が発生しているようだ。アセンブラコードを頼りにトレースするのか!?
最低、シンボルは見えるようなので、、おおよそどこらへんにいるかはわかりそうだ。
(gdb) disas $pc,+32 Dump of assembler code from 0x8026110 to 0x8026130: => 0x08026110 <stm32_main+12>: str r3, [r4, #8] 0x08026112 <stm32_main+14>: ldr r3, [r4, #20] 0x08026114 <stm32_main+16>: orr.w r3, r3, #512 ; 0x200 0x08026118 <stm32_main+20>: sub sp, #32 0x0802611a <stm32_main+22>: str r3, [r4, #20] 0x0802611c <stm32_main+24>: mov r6, r0 0x0802611e <stm32_main+26>: bl 0x8026c08 <powerctrl_check_enter_bootloader> 0x08026122 <stm32_main+30>: ldr r3, [pc, #504] ; (0x802631c <stm32_main+536>) 0x08026124 <stm32_main+32>: ldr r2, [r3, #0] 0x08026126 <stm32_main+34>: orr.w r2, r2, #512 ; 0x200 0x0802612a <stm32_main+38>: str r2, [r3, #0] 0x0802612c <stm32_main+40>: ldr r2, [r3, #0] 0x0802612e <stm32_main+42>: orr.w r2, r2, #1024 ; 0x400 End of assembler dump. (gdb) where #0 0x08026110 in stm32_main () #1 0x0802c8b2 in .bss_zero_entry () #2 0x0802c8b2 in .bss_zero_entry () Backtrace stopped: previous frame identical to this frame (corrupt stack?)
機械語単位でステップ実行してみると、init_flash_fsで異常が発生して再起動しているようだ。Flash上のファイルシステムが正しく初期化できないのだろう。
0x0802627e in stm32_main () => 0x0802627e <stm32_main+378>: ff f7 c7 fe bl 0x8026010 <init_flash_fs> (gdb) Breakpoint 1, 0x08026110 in stm32_main () => 0x08026110 <stm32_main+12>: a3 60 str r3, [r4, #8] (gdb)
init_flash_fsにHardware Breadpointを設定して再実行、
(gdb) i b Num Type Disp Enb Address What 1 hw breakpoint keep y 0x08026110 <stm32_main+12> breakpoint already hit 7 times (gdb) disable 1 (gdb) hb init_flash_fs Hardware assisted breakpoint 2 at 0x8026010 (gdb) cont Continuing. Breakpoint 2, 0x08026010 in init_flash_fs () => 0x08026010 <init_flash_fs+0>: 03 28 cmp r0, #3 (gdb) disas $pc,+32 Dump of assembler code from 0x8026010 to 0x8026030: => 0x08026010 <init_flash_fs+0>: cmp r0, #3 0x08026012 <init_flash_fs+2>: push {r4, lr} 0x08026014 <init_flash_fs+4>: mov r4, r0 0x08026016 <init_flash_fs+6>: bne.n 0x802601c <init_flash_fs+12> 0x08026018 <init_flash_fs+8>: bl 0x8026f10 <factory_reset_create_filesystem> 0x0802601c <init_flash_fs+12>: ldr r0, [pc, #52] ; (0x8026054 <init_flash_fs+68>) 0x0802601e <init_flash_fs+14>: movw r1, #1906 ; 0x772 0x08026022 <init_flash_fs+18>: bl 0x801e384 <mp_vfs_mount_and_chdir_protected> 0x08026026 <init_flash_fs+22>: cmn.w r0, #19 0x0802602a <init_flash_fs+26>: bne.n 0x802604c <init_flash_fs+60> 0x0802602c <init_flash_fs+28>: cmp r4, #3 0x0802602e <init_flash_fs+30>: bne.n 0x802603a <init_flash_fs+42> End of assembler dump. (gdb) nexti 0x08026012 in init_flash_fs () => 0x08026012 <init_flash_fs+2>: 10 b5 push {r4, lr}
最後の手段として、、FLASHを無効化にするオプションを有効にして再度ビルド、サイズもきちきち収まって、REPLが動いた。
MPY: soft reboot MicroPython v1.16-243-g8c4ba575f-dirty on 2021-08-29; NUCLEO-F401CC with STM32F401CC Type "help()" for more information. >>> import gc >>> gc.mem_free() 46000 >>> help('modules') __main__ micropython uhashlib uselect _onewire pyb uio ustruct _uasyncio uarray ujson usys builtins ubinascii umachine utime cmath ucollections uos uzlib gc uctypes urandom math uerrno ure Plus any modules on the filesystem >>>
こうやってみると、_uasyncio、_onewire、uhashlib、ujson、ure、uselect、uzlib等もいらないと思うけど、、
これらが切りはせるのかは不明
Flashが無いことになっているので、、uos.mkdir()などを実行するとエラーになる。ハングしないのでよく作りこまれていますね。。
>>> uos.mkdir('/hoge') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 19] ENODEV
GPIOの番号とかずれてるかもしれないので、I2CやSPIを動かすにはしばらくかかるかもしれませんが、インタープリタでマイコン操作できるのは楽だ~。特に使い慣れないマイコンの場合、周辺I/O等の試行錯誤が繰り返しできるので理解もはかどるはず。
忘れないように最終設定を記録
file:boards/NUCLEO_F401CC/mpconfigboard.h
(UARTのPINを修正、機能無効化を定義、それ以外は、STM32F401REのまま。だから、、Pin配置が多分違っていてSPI, I2C等は動かないと思われる)
#define MICROPY_HW_BOARD_NAME "NUCLEO-F401CC" #define MICROPY_HW_MCU_NAME "STM32F401CC" #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_PY_GENERATOR_PEND_THROW (0) #define MICROPY_PY_MACHINE_BITSTREAM (0) #define MICROPY_PY_FRAMEBUF (0) #define MICROPY_PY_USOCKET (0) #define MICROPY_PY_NETWORK (0) #define MICROPY_PY_STM (0) #define MICROPY_PY_PYB_LEGACY (0) #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UTIMEQ (0) //# trial (8/29 22:09) //#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) #define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) #define MICROPY_HW_HAS_SWITCH (1) #define MICROPY_HW_HAS_FLASH (0) // trial (8/29 22:43) #define MICROPY_HW_HAS_LCD (0) // trial (8/29 22:43) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_SDCARD (0) // trial (8/29 22:43) #define MICROPY_HW_ENABLE_SERVO (0) // trial (8/29 22:43) #define MICROPY_HW_ENABLE_USB (0) // trial (8/29 22:43) #define MICROPY_HW_ENABLE_DAC (0) // trial (8/29 22:43) // HSE is 8MHz, HSI is 16MHz CPU freq set to 84MHz // Default source for the clock is HSI. // For revisions of the board greater than C-01, HSE can be used as a // clock source by removing the #define MICROPY_HW_CLK_USE_HSE line #define MICROPY_HW_CLK_USE_HSI (1) #if MICROPY_HW_CLK_USE_HSI #define MICROPY_HW_CLK_PLLM (16) #else #define MICROPY_HW_CLK_PLLM (8) #endif #define MICROPY_HW_CLK_PLLN (336) #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4) #define MICROPY_HW_CLK_PLLQ (7) // UART config #define MICROPY_HW_UART1_TX (pin_A9) #define MICROPY_HW_UART1_RX (pin_A10) #define MICROPY_HW_UART2_TX (pin_A2) #define MICROPY_HW_UART2_RX (pin_A3) // UART 2 connects to the STM32F103 (STLINK) on the Nucleo board // and this is exposed as a USB Serial port. #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 // I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 #define MICROPY_HW_I2C2_SDA (pin_B3) // Arduino D3, pin 31 on CN10 #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 // SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 #define MICROPY_HW_SPI1_MOSI (pin_A7) // Arduino D11, pin 15 on CN10 #define MICROPY_HW_SPI2_NSS (pin_B12) // pin 16 on CN10 #define MICROPY_HW_SPI2_SCK (pin_B13) // pin 30 on CN10 #define MICROPY_HW_SPI2_MISO (pin_B14) // pin 28 on CN10 #define MICROPY_HW_SPI2_MOSI (pin_B15) // pin 26 on CN10 #define MICROPY_HW_SPI3_NSS (pin_A4) // Arduino A2, pin 32 on CN7 #define MICROPY_HW_SPI3_SCK (pin_B3) // Arduino D3, pin 31 on CN10 #define MICROPY_HW_SPI3_MISO (pin_B4) // Arduino D5, pin 27 on CN10 #define MICROPY_HW_SPI3_MOSI (pin_B5) // Arduino D4, pin 29 on CN10 // USRSW is pulled low. Pressing the button makes the input go high. #define MICROPY_HW_USRSW_PIN (pin_C13) #define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) #define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING) #define MICROPY_HW_USRSW_PRESSED (0) // LEDs #define MICROPY_HW_LED1 (pin_A5) // Green LD2 LED on Nucleo #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
boards/NUCLEO_F401CC/mpconfigboard.mk
MCU_SERIES = f4 CMSIS_MCU = STM32F401xE AF_FILE = boards/stm32f401_af.csv LD_FILES = boards/stm32f401cc.ld boards/common_ifs.ld TEXT0_ADDR = 0x08000000 TEXT1_ADDR = 0x08020000 # trial (8/29 22:09) # MicroPython settings MICROPY_VFS_FAT = 0 # Don't include default frozen modules because MCU is tight on flash space FROZEN_MANIFEST ?=
boards/stm32f401cc.ld
/* GNU linker script for STM32F401CC */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K /* entire flash */ FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 4K /* sectors 1 16K but use 4K*/ FLASH_TEXT (rx) : ORIGIN = 0x08005000, LENGTH = 236K /* 12K + sectors 2,3 are 16K sectors 4 is 64K 5 are 128K */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K } /* produce a link error if there is not this amount of RAM for these sections */ _minimum_stack_size = 2K; _minimum_heap_size = 16K; /* tunable */ /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ _estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* RAM extents for the garbage collector */ _ram_start = ORIGIN(RAM); _ram_end = ORIGIN(RAM) + LENGTH(RAM); _heap_start = _ebss; /* heap starts just after statically allocated memory */ _heap_end = _sstack;
$ pwd .... ports/stm32/boards/NUCLEO_F401CC $ ls mpconfigboard.h mpconfigboard.mk pins.csv stm32f4xx_hal_conf.h
pins.csv , stm32fxx_hal_conf.hは、../NUCLEO_F401RE/からコピー
さらに不要なライブラリを外した。起動時の標準ライブラリは以下
>>> help('modules') __main__ math uctypes urandom _onewire micropython uerrno uselect builtins pyb uio ustruct cmath uarray umachine usys gc ucollections uos utime Plus any modules on the filesystem
現在のファームのサイズ、sizeコマンドによると、223776B (219KB)、割り当てた領域が236KBなので、ほとんど余裕がない。きちきちで収まっている。
$ /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-size.exe firmware.elf text data bss dec hex filename 203584 12 20180 223776 36a20 firmware.elf
STEVAL-DRONE01の制御基板にはLEDが2つ付いているのだが、、Lチカも以下の記述で実行可能。楽だ。
>>> import pyb >>> led1 = pyb.LED(1) >>> led1.toggle() >>> led1.toggle()
■追記
MicroPythonを使って長いけど、普段はビルドされたESP32用ファームを使ってるだけなので、内部構造とか全く分かっていなかった。こうやってデバッグしていると、分からないながらも少しずつ知識が増える。だから。。?? 課題が発生するとそれを解決しようとあれこれ調べるので勉強になる。