2015年09月07日

ARM: Micro Python 発見編(1) 2015

Micro Python 発見編(1) 2015

* Micro Pythonとは
    その他動作可能なマイコン/ボード:
    * PyBoardの回路図等
    * Micro Pythonの言語仕様
    * 実行速度
    * オリジナル(PyBoard)のMCUはSTM32F405RG

* Micro Pythonに於けるSTM32F4-Discovery情報

* Micro PythonのPythonパーサ/字句解析についての記述
* Ethernet対応
* スケジューラの作成と実行
* マンデルブローとライフゲームのグラフィック・サンプルコード
* ガベージコレクションについてのヒント
* 消費電力についての記述

* STM32F4-Discoveryで実際に動かしてみた
    必要条件:
    注意ポイント:
    コンパイル時に必要なもの:
    コンパイル:
* 加速度センサ(STM32F4-Discovery)
    STM32F4-Discoveryで加速度センサを使う方法:
    バグ修正版 staccel.py:

* STM32F411-Discovery対応
* Nucleo-F401/F411RE対応
    Nucleo-F401で使う方法:
    Nucleo-F411で使ってみる:
    外部スクリプトをロードする方法:
    注意ポイント:

* dsPIC33FJ256GP506版
    コンパイル:
* その他,用意されているプロジェクト,フォルダ
    bare-metal:
    minimal:
    esp8266:

* 今後,参考になりそうな情報や参考ページ
    * LCDやHIDモードを使った例
    * モジュールの作り方


Micro Pythonというものを発見した。
詳細は調査中。

* Micro Pythonリンク集
Micro Python で組み込み Python by Hirotaka Kawata さん
http://sssslide.com/www.slideshare.net/hktechno/micro-python-python

Micro Python本家トップページ
    https://micropython.org/
Micro Python wiki
未読だけどかなり詳しい情報がありそう
http://wiki.micropython.org/Home
Github: Micro Python wiki
ここにも別なWikiがある。情報ありそう。
https://github.com/micropython/micropython/wiki
フォーラム
    http://forum.micropython.org/
ドキュメントや関数仕様等々
    http://docs.micropython.org/en/latest/
PyBoardをちゃちゃっと使ってみるサンプルコード
    http://docs.micropython.org/en/latest/pyboard/quickref.html
クイックスタート
    https://micropython.org/help/
ダウンロード:
    https://micropython.org/download/
Github:
    https://github.com/micropython/micropython

* Micro Pythonとは
(1) Python v3.4の言語仕様に基づき,マイコン上で仮想マシン・インタプリタ/コンパイラを実行する。
(2) STM32F405RGT6(168MHz動作)を使った専用ボード(PyBoard)が発売されている。
    https://micropython.org/store/#/store
    28ポンド
    1ポンド/180円(2015/09)なので5000円くらい。
その他動作可能なマイコン/ボード:
    今回はSTM32F4-Discoveryで動かしますが,
    STM32F746-Discovery, 
    STM32F411-Discovery,
    Nucleo-F401/F411,
    dsPIC33F, 
    NetDuino+2(STM32F405RG), 
    Teensy3.1,
    その他のマイコン,ボードで動く様です。
(3) ソースコードはMITライセンス。
    http://docs.micropython.org/en/latest/license.html
(4) ANSI Cで記述されている。
(5) インライン・アセンブラを装備。(ARMのみ)
(6) 高速実行。
(7) メモリ使用量と実行速度を考慮した3つの"コード生成/実行"。
    詳細は以下の原文とコメントのやりとりを参照。
    The 3 different code emitters 
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/664832
    以下のコード生成(b),(c)を指示する場合,関数定義時にデコレータ指令を使う。
    通常は(a)を使い,少しスピードが欲しい時は(b)を使うといいだろう。
    (a) 通常の仮想マシンコード生成モード(Bytecode emitter)
        デフォルトでは仮想マシンコードが生成され,
        Micro Python内蔵の仮想マシンで実行される。(一部を除きCPythonと同等)
        メモリ(SRAM)使用量は一番小さい。
        デコレータ: @micropython.byte_code (デフォルトは無指定でこれになる)
    (b) Native emitterによるコード生成
        個々のバイトコードを等価なARM-Thumbコードに変換後実行する。
        ローカル変数はC言語のスタック領域に保存され,C言語レベルのランタイムルーチンを
        呼び出して実行する。
        メモリ使用量は中間程度。
        デコレータ: @micropython.native
    (c) Viper emitterによるコード生成
        Native emitterに整数演算の最適化を施したコードを生成する。
        例えば2つの整数の加算はC言語レベルのランタイムルーチンを呼ばず,
        直接ARM-Thumbコードの"adds命令"を生成する。
        状況に依っては,Native emitterより7倍程度高速実行可能な場合があるらしい。
        メモリ使用量は一番大きい。
        欠点: 全てのPython命令をサポートしている訳ではない。
        デコレータ: @micropython.viper
    boot.py内のオプションでデフォルトemitterを変更可能。

以下はViper emitterがデフォルトのBytecode emitterより24倍高速実行可能な例を
説明している。
The 3 different code emitters, part 2 
https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/665145

(8) バイトコードはSRAM上に展開され実行される様だ。
(9) 基本ペリフェラル・ライブラリ
    GPIO, SPI, UART, I2C, Ethernet, Servo, PWM, Timer, ADC, DAC等々は
    標準で用意されている。
    SDカード, 加速度センサーも使える。

* PyBoardの回路図等
    http://micropython.org/resources/PYBv10b.pdf
    http://docs.micropython.org/en/latest/pyboard/hardware/index.html

* Micro Pythonの言語仕様
(1) Python v3.4 の仕様とほとんど同じである。
    ドキュメントは以下
    docs.python.org 
    より詳細な差異: Differences to CPython
(2) 違う部分の説明
    ARM Thumb2のサブセットを使ったインライン・アセンブラ仕様説明
    Inline Assembler for Thumb2 architectures
    http://docs.micropython.org/en/latest/reference/asm_thumb2_index.html    
(3) インラインアセンブラ関連情報
    Inline assembler 
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/667580
    インラインアセンブラのチュートリアル
    http://docs.micropython.org/en/latest/pyboard/tutorial/assembler.html#pyboard-tutorial-assembler

* 実行速度
LEDチカチカの単純ループの比較であるけれど,
Arduino Uno 16MHzのC(++)言語で記述されたものと同等の速度が出る。
最適な書き方をすればMicro Pythonの方が2倍速いらしい。
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/664832
Performance:
別な視点から比較ベンチマークを行っている
https://github.com/micropython/micropython/wiki/Performance

* オリジナル(PyBoard)のMCUはSTM32F405RG
F407(STM32F4-Discovery)との違いはF405側に「カメラIF」と「Ethernet IF」がないこと。
マニュアルが同じなので親和性が高い可能性があるが,
STM32F4-Discoveryボードは使用済みのI/Oが多いので,そのあたりが注意ポイントかも。
STM32F405RG
http://www.st.com/web/jp/jp/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144

* Micro Pythonに於けるSTM32F4-Discovery情報
    Board STM32F407 Discovery
    https://github.com/micropython/micropython/wiki/Board-STM32F407-Discovery

* Micro PythonのPythonパーサ/字句解析についての記述
    Stretch goal ideas, and the parser 
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/669549

* Ethernet対応
    Wiznet 5x00系対応
        Wiznet WIZ820io等に対応
    WiFiモジュール Adafruit CC3000に対応
    http://www.adafruit.com/products/1469
    日本で使えるかは不明
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/681998

* スケジューラの作成と実行
    Progress, and some more example code
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/675393

* マンデルブローとライフゲームのグラフィック・サンプルコード
    https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/664040
    examplesフォルダにソースあり。

* ガベージコレクションについてのヒント
コメント欄参照
The C API in Micro Python 
https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/679050

* 消費電力についての記述
Power consumption of the board 
https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers/posts/685745

* STM32F4-Discoveryで実際に動かしてみた
必要条件:
    (1) MicroUSBケーブル: CN5に繋いでその先をPCに繋ぐ。
        Raspberry Pi用の物が使えた。 (^^)/
        CN5系由でUSB-Flash-MassStorage機能とUSB-UART(VCP)機能(REPL用)を使う。
    (2) デバッグ用のミニUSB端子 : ケーブルでPCに繋ぐ。
        (a) Micro Python的には単なる電源供給端子である。
        (b) ここにSTLink-UtilityのGUI版を繋いで「firmware.hex」を書き込めばMicro Pythonが動く。
            firmware.hexは自分でコンパイルしたものを使いました。
            コンパイル方法は下記,参考情報ページを参照。
注意ポイント:
    (1) インタラクティブシェル(REPL)用の仮想UART(COM)ポートが出現するので,
        Windows10ならTeraTerm等で115200bpsで接続,Enterキーでメッセージが出る。
        >>>help()
        と入力してみよう。
        Win8/7系は出現したドライブ中の「pybcdc.inf」をデバイスマネージャで
        不明になっているUSB(-COM)デバイスに対して「更新」でインストールする。
        Win10も後からinfファイルをインストールした。識別が容易になるので。
    (2) インタラクティブシェルにコードをコピペする時の注意
            これハマリました。 orz
            TeraTerm上へPyhtonコードをコピペする時は,
            <CR>付きコピペを使うこと。
            CRなしコピペだとうまくコードが認識されず文法エラーが起きたりします。
            orz
    (3) Flashドライブは必ず「取り出し」する
        マスストレージでマウントされた「main.py」が存在するドライブ(Flashドライブ)の取り扱いはSDカード等と同じく,
        ボードリセットやボードの電源を切る前に,必ずエクスプローラから「取り出し」を実行しておきます。
        取り出し完了までに結構時間がかかります。(Windows10)
        これを忘れてFlashファイルシステムが破壊されると以後編集不能になりファーム書き換えでも復活しません。
        orz
    (4) 破壊されたFlashドライブを初期化する
        上記で編集やコピーが不能になった場合,STLink-Utilityから
        「Target」-「Erase Chip」を実行後,ファームを書き込みなおします。
        これで全て初期化された状態で復帰します。
    (5) 「取り出し」なしで編集,実行を繰り返す方法
        main.pyを編集した後,REPLターミナルから「CTRL-D」を押すとMicro Pythonのソフトリセットがかかり,
        Flashドライブとターミナルの接続状態を保持したまま「main.py等」が再読込みされます。
        通常はこの方法で使うのが良いと思います。
        但し,今ひとつ挙動が微妙なところがあるので,結局ハードリセット使ったりします。orz
コンパイル時に必要なもの:
    (1) arm-none-eabi-gcc.exeにパスを通す。
    (2) Python v3.4.x(2.7.x)にもパスを通す。
        https://www.python.org/downloads/
        Pythonはv3.4系を推奨します。一部のツール(tools/pyboard.py)がv2.7系未対応だったりします。
    (3) make.exe も必要。
コンパイル:
stmhalフォルダで,
make BOARD=STM32F4DISC
...
CC usbdev/class/src/usbd_msc_scsi.c
CC usbdev/class/src/usbd_msc_data.c
CC build-STM32F4DISC/pins_STM32F4DISC.c
LINK build-STM32F4DISC/firmware.elf
   text    data     bss     dec     hex filename
 267528      96   27676  295300   48184 build-STM32F4DISC/firmware.elf
Create build-STM32F4DISC/firmware.dfu
Create build-STM32F4DISC/firmware.hex
build-STM32F4DISCフォルダ内の「firmware.hex」をSTLink-Utilityで書き込みます。 * 加速度センサ(STM32F4-Discovery) STM32F4-Discoveryの加速度センサライブラリはバグで動かない様です。orz PyBoardとは関数の呼び出し方が違います。 STM32F4-Discoveryで加速度センサを使う方法: (1) stmhal/boards/STM32F4DISC/staccel.pyをFlashドライブにコピーします。 (2) REPLターミナルから
>>> import staccel
>>> ac = staccel.STAccel()
でオブジェクト化します。 後は, ac.x() ac.y() ac.z() ac.tilt() ac.filtered_xyz() 等の関数が使えるはずですが, 初期化時のバグで加速度センサのIDが正しく取得できず,上記のオブジェクト化で失敗します。 orz 以下その話題。 STM32F4-Discoveryのバグ http://forum.micropython.org/viewtopic.php?f=2&t=595&start=10 現時点で上記「やっつけバグ修正」をしても初期化で失敗します。 orz バグ修正版 staccel.py: STM32F4-Discoveryボード上の加速度センサは2種類あって, 古いボードはLIS320DL 新しいボードはLIS3DSHが載っているようです。 自分のは古い方のICでした。 IC判別は自動で行われるので気にする必要はありませんが,ボードをよく見ると上記文字の一部が 読み取れます。 動作可能な様に修正したものをここに置いておきます。 micropython-fixed-staccel-py-201509-v2.zip : DMA禁止版 準備中 micropython-fixed-staccel-py-201509.zip : 古い版 本家にプルリクエストしておいたので将来反映されるかもしれません。 古いICでしか動作確認していません。 注意ポイント: 初回の加速度センサID取得が失敗するので2度読みするという,やっつけで 動作可能にしていますが根本原因は分かっていないようです。 上記自分の修正版は,それに加えてSPIクロックの極性(Porarity)を1(=CPOL)に変更してあります。 基にしたと思われるSTMicroのサンプルコードはCPOL=0となっていてバグっている様です。 あと,SPIクロックが約330KHz(328125Hz)と低速だったので2MHzに修正しておきました。 328125Hzに何か意味があるのか今のところ不明です。 追記: 「プルリクエストにコメントくれた人がいて,実は最初動いていたけどSPIをDMA化した時に おかしくなったことが判っていて,read_bytes()関数内を割り込み禁止にすればIDを2度読み する必要はない。割り込みを禁止するとDMAは自動で禁止されるから。 でも,どうしてそうしないといけないのかは判っていない」と言われた。 DMA禁止版をプルリクエストしておいた。 * STM32F411-Discovery対応 Audio DACやセンサ山盛り。STM32F4-Discovery(STM32F407)のMCUをF411VEに変えた様なボード。 http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260946?s_searchtype=keyword 数日前にコミットされたばかり。 stmhalフォルダで,
make BOARD=STM32F411DISC
* Nucleo-F401/F411RE対応 以下のページでNucleo-F401で使う方法が解説されている。 Running micropyton on STM32Nucleo-F4 http://www.carminenoviello.com/en/2015/06/03/running-micropyton-stm32nucleo-f4/ 現在のところ,本家とは別リポジトリなので注意。 https://github.com/cnoviello/micropython Nucleo-F401で使う方法: 上記リポジトリを取得して stmhalフォルダで,
make BOARD=STM32F4NUCLEO
Nucleo-F411で使ってみる: F401は持っていないのでF411で動かしてみた。 上記F401はデフォルトでコンパイル可能だがF411はソースの修正が必要。 追記 2016/02 : ソース無修正でF401のバイナリをF411に書き込んだほうが良いと思います。 STM32F4NUCLEOフォルダ内の (1) mpconfigboard.h 内の定義を以下に修正
#define MICROPY_HW_MCU_NAME         "STM32F411xE"
(2) mpconfigboard.mk 内の定義を以下に修正
CMSIS_MCU = STM32F411xE
AF_FILE = boards/stm32f411_af.csv
LD_FILE = boards/stm32f411.ld
システムクロック周りやリンカスクリプトはよく見る必要があるかもしれないが, 今回はそのままで実験してみた。
make BOARD=STM32F4NUCLEO
で「build-STM32F4NUCLEO」に生成された「firmware.hex」をSTLink-Utilityで 書き込みます。 仮想COMポートが出現するので、115200bpsで接続してEnterキーを押せば、 インタラクティブシェルが起動します。 外部スクリプトをロードする方法: Windows上のやり方です。 toolsフォルダにあるpyboard.pyを使います。 PC側のPythonはバージョン3.x系である必要があります。 (1) $ python pyboard.py --device=COM4 foo.py これで任意のfoo.pyスクリプトをロード/実行できます。 (COMポート番号はデバイスマネージャから見つけてください) (実際にはpyboard.pyの前にtoolsフォルダまで,foo.pyの前にそこまでの 相対フォルダ又は絶対フォルダが必要です)(必要ならですが) 上記コマンド実行後,自動でソフトリセットがかかるので,foo.pyに実行可能命令が有る場合 自動実行されます。 関数・クラス定義だけならREPLコンソールから呼び出しできます。 注意ポイント: この方法は電源OFFでfoo.pyが消えてしまいます。 Flashに書き込むには次の方法を使います。 (2) $ python pyboard.py --device=COM4 --send foo.py これでFlashにfoo.pyが書き込まれ実行されるはずですがF411の場合, 今のところうまく動きません。 orz * dsPIC33FJ256GP506版 PICの16bitマイコンでも動く様だ。 ただし,現時点ではコンパイル可能なスタートポイントという感じで,必要最小限なLEDチカチカ, UART,ベタ待ちdelay,Switch程度しかインプリメントされていないので, ペリフェラル操作関数は自分で作り込む必要がある。 dsPIC33Fで動くならPIC24F系で動かすことも可能だろう。 コンパイル: pic16bitフォルダで,
make XC16=/c/xc16/v1.23
でコンパイル可能。 XC16はコンパイラへのパス。 「unistd.h」が存在しないエラーが出たら「../py/stream.c」内の「#include <unistd.h>」をコメントし, 代わりに「#include <stdio.h>」を追加する。 コンパイラはv1.23, v1.11でOK。 v1.25はリンクエラーとなった。 orz
...
CC main.c
CC board.c
CC pic16bit_mphal.c
CC modpyb.c
CC modpybswitch.c
CC modpybled.c
CC ../stmhal/pybstdio.c
CC ../stmhal/pyexec.c
CC ../lib/mp-readline/readline.c
LINK build/firmware.elf
   text    data     bss     dec     hex filename
 180248     488    9692  190428   2e7dc build/firmware.elf
Create build/firmware.hex
ペリフェラルIFがほとんどない状態でFlash 180kbyteなので 256Kbyte以上のマイコンが必要そう。 * その他,用意されているプロジェクト,フォルダ bare-metal: STM32F405RGT6 ARM用の仮想マシンのみをコンパイルする最小プロジェクトと思われる。 コンパイル結果は以下,
LINK build/firmware.elf
   text    data     bss     dec     hex filename
  71488       0     404   71892   118d4 build/firmware.elf
minimal: 上記bare-metalよりも現実的なプロジェクト。STM32版はUART経由で使える風。 (1)PC用: minimalフォルダ内でmakeと打つとPC用のバイナリを生成します。 このバイナリでそのままPC上(MS-DOS窓/xterm等)でREPLが動きます。
LINK build/firmware.elf
    text       data        bss        dec        hex    filename
  141528        296       2524     144348      233dc    build/firmware.elf
Windows上だと"alloca.h"がないと言ってコンパイルできない。 Linux上なら問題ない。orz (2)STM32F4xx用: minimalフォルダ内で make clean make CROSS=1 と打てばSTM32Fxx用(デフォルトはSTM32F405)のバイナリができます。 UART1経由でREPLができます。9600bps 。
CC main.c
CC uart_core.c
CC uart_extra.c
CC ../lib/utils/printf.c
CC ../lib/utils/pyexec.c
CC ../lib/libc/string0.c
CC ../lib/mp-readline/readline.c
LINK build/firmware.elf
   text    data     bss     dec     hex filename
  77812       4    2524   80340   139d4 build/firmware.elf
Create build/firmware.dfu
esp8266: WiFiモジュール esp8266内蔵マイコン上でMicro Pythonを動かすプロジェクト。 コンパイラである xtensa-lx106-elf-gcc.exeはArduino1.6.5 IDE用のものが使用できる。 コンパイラへのパスはMsys/MinGWの場合,以下の様に設定する。(Windows10)
export PATH=/c/Users/user_name/AppData/Local/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9/bin:$PATH
現時点ではコンパイルエラーとなる。orz * 今後,参考になりそうな情報や参考ページ * LCDやHIDモードを使った例 planset blogさんのブログ Micro Python http://dkpyn.com/blog/2375 STM32F4-Discovery * モジュールの作り方 MicroPython で遊ぶ(2014/9) http://moxi.jp/wiki/wiki.cgi?page=MicroPython+%A4%C7%CD%B7%A4%D6%282014%2F9%29 MicroPython Pyboard を使ってカラーディスプレイ(μOled128)を動かす http://takesan.hatenablog.com/entry/2015/08/12/204937
posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(1) | Python | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
とてつもなく参考になりました!
ありがとうございます。
Posted by Hanpa at 2016年11月14日 16:27
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。