It's a python on STM32F4dicovery.

sorry. japanese only. これは何ですか? STM32F4discoveryで動作するpython言語の実装の一つ,python-on-a-chip(省略してp14p, かつてはpymiteと呼ばれていました)です。 とりあえずボードに出荷時に書き込まれているデモプログラム程度がpythonで記述できる ようになったので,AS-ISで公開しています。 STM32F4discovery用のpymiteアーカイブはこ↑こ↓ HERE it is. and more... BitbucketでPython-On-A-Chipをstm32f4-discovery向けにも色々とやってるみたいです。 より洗練された対応ソースやビルド方法なども記載されているようなので,興味のある方 は覗いてみてはいかがでしょうか。 ビルド&実行させるには 対話使用するにあたりPC上でipmというフロントエンドを実行させる必要がありますので 必ずビルドする必要があると思います。とりあえず以下の手順を参考にしてみてください。 python-on-a-chipサイトダウンロードページからダウンロードした pymite-09.tar.gz を展開します。 そのディレクトリで↑のアーカイブを展開すると,src/platform/にstm32f4というディレ クトリ以下が展開されると思います。 とりあえず,そこにあるビルド済みバイナリsrc/platform/stm32f4/main.binを,フラッ シュROMに書き込めば,pymiteが使えるようになります。 ビルド済みバイナリは,対話pymite(ipm)部分とデモ部分から構成されているmain.pyを コンパイルしたものです。 そのバイナリをフラッシュROMに書き込んで,リセットボタンなどを押して起動します。 USERボタンを押した状態で起動すると,ボタンを離した時に,デモ部分が実行されて, 以後,USERボタンを押して離すたびに,LEDの明滅と加速度センサのデモ表示が交替で 行われます。(ボードの出荷時書込み済みのデモと同じような感じです) また,USERボタンを押さないで起動すると,ipm.ipm()が実行されて,USART2からのバイ トコード入力待ちになり,ipm.pyを起動したPCと接続することで,対話型pymiteが使用 可能となります。 USART2は,9600bps8N1で,入出力はPA2(P1の14番ピン)がTx,PA3(P1の13番ピン)がRxです。 ここにレベル変換なり,USBシリアル変換をかますなりして,PCを接続します。 ここからpythonのバイトコードを食わしてやればpythonコードを実行することが可能です。 (普通にターミナルを繋いで,何か文字を入れると,無効なバイトコードだと判別して, 多分エラーメッセージが表示されます) pymiteは,このバイトコードの生成をPC上でやらせて,それをターゲットチップ上で実行 する様になっています。 対話pymite(ipm)は,PC上で動作してpythonコードのバイトコード化をPCで行い,ターゲッ トに送りつけて,その結果返されてくる情報をそのまま表示します。 これで対話的に大きな負担もなく,マイコン上でpythonコードが実行できるようになります。 もちろん,スタンドアロンでも使えます。 ↑のアーカイブでビルドしたものは,起動時にUSERボタンでスタンドアロンでのデモ実行と, ipmを使っての対話型実行を選択するようにしてあります。 ビルドする場合には,pymite-09のディレクトリで,scons PLATFORM=stm32f4と実行する と,src/platform/stm32f4/main.binが出来ます。(稿末にビルドの様子があります) 具体的には,下にある実行例のように,PCのpymite-09ディレクトリで,ipm.pyを実行 すると対話プロンプトが表示されます。(pyserialのインストールが必要かもしれません) src/tools/ipm.py -f src/platform/stm32f4/pmfeatures.py -s /dev/ttyS0 9600 ※ 当方はcygwin環境ですので,COM1接続を/dev/ttyS0として接続指示しています。 ipm上で何かを入力すると,それをPC上でバイトコンパイルして,STM32F4discoveryに そのバイトコードを送りつけて,結果をそのまま表示するだけのことを延々とやるわけ です。 このように対話的にもpymiteが使えて,ちょっとした実験ならビルドして焼き直すこと なく,色々と試行錯誤ができます。カンタンな電卓程度には使えると思います ipmを使ってpymiteを対話的に実行するとこんな感じです。 $ src/tools/ipm.py -f src/platform/stm32f4/pmfeatures.py -s /dev/ttyS0 9600 Python-on-a-Chip is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall and others. Python-on-a-Chip is licensed under the GNU LESSER GENERAL PUBLIC LICENSE V 2.1 PyMite is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall. PyMite is licensed under the GNU GENERAL PUBLIC LICENSE V 2. This software is offered with NO WARRANTY. See LICENSE for details. Type the Python code that you want to run on the target device. If you see no prompt, type two consecutive returns to exit multiline mode. Type Ctrl+C to interrupt and Ctrl+D to quit (or Ctrl+Z <enter> on Win32). ipm> dir() [] ipm> a=(1,2,3) ipm> dir() ['a'] ipm> import sys ipm> print sys.heap() (96816, 102400) ipm> sys.exit() PM_RET_EX_EXIT: System exit Error: 0xE1 Release: 0x08 FileId: 0x00 LineNum: 0 Traceback (top first): <ipm>() ipm() main() <module>. ipm> print "%30.28f" % (355.0/113) 3.1415929794311523437500000000 ipm> print "%30.28f" % 0.1 0.1000000014901161193847656250 ipm> "Hello world!" 'Hello world!' ipm> "Hello world!"[2:10] NotImplementedError:Illegal bytecode (33/0x21/SLICE+3) comes at offset 9 in file <ipm>. ipm> "Hello world!"[2:] NotImplementedError:Illegal bytecode (31/0x1f/SLICE+1) comes at offset 6 in file <ipm>. ipm> import string ipm> string.find("Hello world!","rld") 8 ipm> string.find("Hello world!","blx") -1 ipm> len("Hello world!") 12 ipm> 12*32/5.0 76.800003 ipm> "%02x" % 11 '0b' ipm> I/Oサポートライブラリについて stm32fdiscoveryという,長ったらしい名前のI/Oサポートライブラリを添えてあります。 やっつけですが,IOレジスタを操作する関数(メソッド)がありますので,IOレジスタを 操作してのポートのI/Oくらいならできるようになっています。 デモ用に作った,USERボタン入力とLEDの明滅出力,MEMS加速度センサーの値を取得する メソッドもありますので,拡張の際の参考にしてください。 import stm32f4discovery stm32f4discovery.BTN() USERボタンが押されていれば1,押されてなければ0を返してきます stm32f4discovery.LED(n[,val]) 4つあるユーザLEDを明滅させます。 nは,0:LED_Green, 1:LED_Orange, 2:LED_Red, 3:LED_Blue を指定します valは明るさです。256段階のPWMなので256以上でフル点灯。0で消灯となります。 valを省略すると0と見做して,消灯します。 stm32f4discovery.AXEL([flag]) MEMS3軸加速度センサのアクセスメソッドです。 引数flagで,MEMSセンサのインターフェイス(SPI1等)を有効化/無効化します。 flagが0で無効化,1で有効化します。フラグを省略すると,インターフェイスが 有効化されていれば,4項目のタプルでMEMSセンサの値を返してきます。 タプルの項目は,(X軸,Y軸,Z軸,センサのステータスフラグ)です。 インターフェイスが無効の場合は,NONEが返ります。 [低レベルメソッド] stm32f4discovery.IOREG(addr[,val]) I/Oレジスタのアクセスメソッドです。 addrにペリフェラルアドレス(0x40000000)からのオフセットアドレスを指定します。 (例:GPIOA->IDRならば0x200010, TIM4->CCR1ならば0x834) valが指定されていれば,その値で32ビットワードの更新をします。 返り値は,更新前の値を32ビットワードで返してきます。 最低限のアクセス手段を追加しましたw stm32f4discovery.IOWRT(addr,val) I/Oレジスタの書き込み専用のアクセスメソッドです。 引数の意味は,IOREGと同様です。こちらは読み込みをしません。データレジスタや ステータスレジスタなどの読み/書きで,別の意味を持つIOレジスタへの書き込みは, このメソッドを使用して書き込みをします。 stm32f4discovery.AXEL_REG(addr,[val]) MEMS3軸加速度センサのレジスタのアクセスメソッドです。 addrにセンサのレジスタアドレスを指定します。 valが指定されていれば,その値で更新をします。 返り値は,更新前の値を返してきます。 ↓実行例 最後の複文実行でユーザボタンが押されるまで順次LEDがホワホワしたり,傾きに応じてモワモワします ipm> import stm32f4discovery ipm> x=stm32f4discovery # クラス名が長いのでxという名前でaliasします ipm> stm32f4discovery.BTN() 0 ipm> x.BTN() 0 ipm> stm32f4discovery.BTN() 1 ipm> x.BTN() 1 ipm> x.BTN() 0 ipm> x.LED(0,20) ipm> x.LED(1,40) ipm> x.LED(2,80) ipm> x.LED(3,160) ipm> x.LED(3) ipm> x.LED(2) ipm> x.LED(1) ipm> x.LED(0) ipm> stm32f4discovery.IOREG(0x20010) 8446 ipm> stm32f4discovery.IOREG(0x20010) 8447 ipm> ipm> x.AXEL(0) ipm> x.AXEL() ipm> import stm32f4discovery ipm> dir(stm32f4discovery) ['AXEL_REG', 'AXEL', '_get_AXEL', '_conf_AXEL', '_deconf_AXEL', 'LED', 'BTN', 'I OWRT', 'IOREG', '__rise_TypeError', '__doc__'] ipm> stm32f4discovery.AXEL(1) ipm> stm32f4discovery.AXEL() (7, -9, 52, 0) ipm> ipm> import sys ipm> import stm32f4discovery ipm> x=stm32f4discovery ipm> i=0 ipm> def wait_a_bit(): .... global i; .... i= (i+1) & 0xfff .... if(15==i & 15): .... sys.gc() # clean up .... else: .... sys.wait(5) # wait a bit .... ipm> def wait_BTN_release(): .... while 1==x.BTN(): # waiting for release USER BUTTON .... sys.wait(100) .... ipm> def LED_all(v=0): .... x.LED(0,v) .... x.LED(1,v) .... x.LED(2,v) .... x.LED(3,v) .... ipm> def LED_glow_seq(a): .... if(a & 0x800): .... if(a & 0x100): .... LED_all((0x100-(a&0xff))) .... else: .... LED_all((a&0xff)) .... else: .... if(a & 0x100): .... x.LED( (a>>9) & 3, (0x100-(a&0xff))) .... else: .... x.LED( (a>>9) & 3, (a&0xff)) .... ipm> def LED_axel_indicate(ax): .... LED_all() .... if(ax[1]>0): x.LED(0,ax[1]<<1 ) .... if(ax[0]>0): x.LED(1,ax[0]<<1 ) .... if(ax[1]<0): x.LED(2,(1-ax[1])<<1 ) .... if(ax[0]<0): x.LED(3,(1-ax[0])<<1 ) .... ipm> sys.gc() ipm> ipm> while True: .... wait_BTN_release() .... x.AXEL(0) .... LED_all(); .... while 0==x.BTN(): # until push USER BUTTON .... LED_glow_seq(i) .... wait_a_bit() .... wait_BTN_release() .... x.AXEL(1) .... while 0==x.BTN(): # until push USER BUTTON .... axel= x.AXEL() .... LED_axel_indicate(axel) .... wait_a_bit() .... Connection read error, type Ctrl+D to quit. ipm> ↓HTMLコメント中に,デモっぽいサンプルスケッチをおいておきます。 ipm経由で食わせても,main.pyと置き換えてもビルドしなおしてもいけるはずです。 実行にあたっての留意事項 実行でエラーがでるとシステムリセットを発行して,pyvmをコールドスタートします。 これはipmで対話的に操作をしている場合,それまでの実行結果が消えることを意味し ます。 オブジェクト生成でメモリがガンガン使われますので,sys.gc()を明示的に定期発行 しておくと変なエラーに悩まされることが減ると思います。 heapサイズは,plat.hで指示しています(とりあえず100kBとしてあります)。 ちなみに for i in range(0,10000): print i; とかやるには全然足りないですw (xrange()ないんだね。巨大リストはメモリバカ食いするってのがわかんだよね。はっきりと) コンパイルなどについて 実行バイナリのビルドに当たっては,当方ではcygwin環境(sconsのインストールが必要) で行いました。 コンパイルに使用したtoolchainは,Sourcery CodeBench Lite 2011.09-69です。 使用しているI/Oについて(init.c,usart2.cやI/Oサポートライブラリから使用) SysTickを1msタイマーに USART2を標準入出力に TIM4をPWMでCH1〜4に出力する設定に(TIM4のCCR1〜4に書込んだ値の明るさでLEDが光る) SPI1をMEMS加速度センサのI/O用に src/platform/stm32f4/以下のファイルについて SConscript # ← sconsで使用されるMakefileみたいなもの pmfeatures.py # ← 実装するpymiteで使う機能を選択定義する plat.h # ← Heapサイズを指定しているヘッダファイル usart.h # ← USARTの入出力関数の実体 usart2.c # ← USART2の入出力関数の定義 syscalls.c # ← newlibから使用されるシステムコールを定義した関数 vector.c # ← STM32F4xxのリセットや例外処理のベクタテーブル定義 sysclk_config.h # ← STM32F4xxのクロック設定の定義 init.c # ← STM32F4xxを初期化してCプログラムの実行準備処理 main.c # ← pyvmを起動する大元のメインプログラム plat.c # ← コンソール入出力やタイマなどのpyvmで必要なI/O関連処理 main.py # ← pyvmで実行されるpython(pymite)コード stm32f4xx.ld # ← STM32F4discovery用のリンカスクリプト stm32f4discovery.py # ← STM32F4discovery用のpymiteライブラリ FWlib/inc/*.h # ← STmicroで配布しているCMSISのヘッダファイル 元ネタについて Python-on-a-chipのプロジェクトページ Python-on-a-chip(p14p) Its called pymite. pymite-09のアーカイブに含まれているsrc/platform/stm32を元にSTM32F4discovery用に 調整修正したものです。 FWlib以下にSTmicroが配布している,CMSISやデバイスのヘッダを含んでいます。 以下はメモです さすがにフラッシュが1MB,RAMが192KBもあると楽勝で動作します。 cortex-M系はオブジェクトがコンパクトで,フラッシュROMが余りまくりになりますね。 (H8SXで同じように動作させたときには,ROMイメージでオーバー100KBでしたがcortex-M だと80KBに余裕で収まります) 出来損ないのアーカイブはこ↑こ↓ HERE it is.(←これはipmがコケるバージョンです) pymite-09で展開すればビルドできるはず...一応ビルド済みのバイナリも中にあります。 src/platform/stm32を元にSTM32F4-discovery向けに修正(というか大体作り直し)した ものです。実機へは,src/platform/stm32f4/main.binをフラッシュに焼いてください。 USART2で9600bpsでコンソール入出力します。 出来損ないのアーカイブに含まれるmain.pyソース(参考) HERE it is. 出来損ないの実行ログ(コンソールはteratermでUSART2に接続。通信条件は9600bps8N1) HERE it is. ビルドログ $ pwd /tmp/work/pymite-09 以下HTMLコメントの中 [ご注意] ・このページの記載事項については,一切無保証です。
inserted by FC2 system