2018年04月09日

MicroPythonにPinクラスを追加する(RPiベアメタル)

pinclass.png

少しずつ進めているRaspberry Pi用ベアメタルMicroPythonですが、今日は基本中の基本のPinクラスを実装し、Lチカができるようになりました。
I2CやSPIを実装するにも、まずどのPinを使うか指定する必要がありますので、とにかくPinクラスが使えるようにしなければなりません。

クラスの定義はモジュールの定義と似ています。
モジュールの定義方法は、下記の記事で以前紹介した通りです。

MicroPythonからラズパイのフレームバッファへ描画する: 楽しくやろう。

これと対比してクラスの定義の記述の仕方をまとめておきます。

●クラスの追加
・新しいクラスが所属するモジュールのためのCソースファイルを(無ければ)作り、Makefileに追加する。
・Cソースの中で、mp_obj_type_t型(構造体)の定数を宣言する。これがクラスの実体となる。メンバ変数はいろいろあるが(py/obj.hで定義されている)、base(この定数自体の型)、name(クラス名)、print(REPLでオブジェクトを文字列として出力する)、make_new(新しいインスタンスを作る)が必須。locals_dict(インスタンスが共有するクラス変数やインスタンスメソッドのリスト)もほぼ必須。baseは必ず&mp_type_typeとする。(mp_type_typeはobjtype.cの中で定義されている定数で、型を作るクラス、つまりメタクラス。)
・このクラスが所属するモジュールの定義の中で、そのモジュール内のグローバルオブジェクトのリストであるmp_rom_map_elem_t型の定数に
{ MP_ROM_QSTR(MP_QSTR_クラス名), MP_ROM_PTR(&上記の定数) }
を追加する。

●クラス内グローバルオブジェクトの追加
・mp_rom_map_elem_t型の定数配列を宣言する。これがクラス内グローバルオブジェクトのリストとなる。
・MP_DEFINE_CONST_DICT(定数名,上記の定数配列の名前)でmp_obj_dict_t型の定数を宣言する。
・mp_obj_dict_t型の定数を、クラスを表すmp_obj_type_t型の定数(上記で定義済み)のlocals_dictからポイントする。
・グローバルオブジェクトのリストへ、
{ MP_ROM_QSTR(MP_QSTR_オブジェクト名), マクロ(オブジェクトの実体) }
という形式でオブジェクトを追加する。
「マクロ」はオブジェクトの実体がintならMP_ROM_INT(整数値)、それ以外ならMP_ROM_PTR(ポインタ)。

●インスタンスの定義とインスタンスメソッドの追加
・インスタンスを表す型を構造体として定義する。このとき、最初のメンバ変数は必ず
mp_obj_base_t base;
とし、その値は常にクラスを表すmp_obj_type_t型の定数とする。
・コンストラクタは、クラス・positional argsの個数・keyword argsの個数・引数の配列を受け取り、インスタンスのためのメモリを確保し、初期化してmp_obj_t型を返す関数として定義する。
その関数へのポインタを、mp_obj_type_t型のメンバ変数make_newへ代入する。
メモリ確保のための手段はpy/misc.hに各種定義されている。mallocは使えないことに注意。最もシンプルな方法としては、インスタンスを表す構造体の型をmyobj_tとすると、m_new_obj(myobj_t)でインスタンスオブジェクトが生成できる。
・インスタンスメソッドの実体は、mp_obj_t型を返す関数として定義する。
・マクロMP_DEFINE_CONST_FUN_OBJ_XXで関数をMicroPythonのオブジェクトとして定義する。XXの部分は関数の引数の個数により異なる。(0〜3:0個〜3個、VAR:可変長、VR_BETWEEN:最小個数と最大個数が決まっている、KW:キーワード=値の形式を用いる)
・グローバルオブジェクトのリストmp_rom_map_elem_t型配列へ
 { MP_ROM_QSTR(MP_QSTR_関数名), MP_ROM_PTR(&関数名オブジェクト名) }
を追加する

こんな感じです。インスタンスメソッドの追加はモジュールへの関数追加と全く同じですね。
以下のリンクも参照してください。

Adding a Module − MicroPython Development Documentation 1.0 documentation

今回はPinクラスを定義することが主眼ですが、MicroPythonのお作法では、Pin、I2C、SPIといったハードウェア寄りのクラスはmachineモジュールが持つようになっていますので、machineモジュールも定義しています。
追加したコードはこんな感じです。

added Pin class (machine.Pin), init(), value(), constants(IN, OUT, PU… ・ boochow/micropython-raspberrypi@e744494

Pinのインスタンスの実体は構造体(machine_pin_obj_t型として定義)ですが、インスタンスと物理的なGPIOとが1対1に対応しますので、無限にインスタンスを作ることはできません。
その代わり、スタティック変数として構造体のGPIOのピン個数(54個)分の配列を用意し、コンストラクタはPin番号に応じてこの配列のいずれかを返すようになっています。

他に初期化(init)と値の読み書き(value)の2つのインスタンスメソッドを定義しています。
これらのメソッドはGPIOレジスタにアクセスして処理を行います。
レジスタの操作方法については、以下の記事で紹介済みですので省略します。

Raspberry Pi Zero WでベアメタルLチカ: 楽しくやろう。
Raspberry Pi Zero + ベアメタルMicroPythonでのLチカ: 楽しくやろう。

上記で触れていない、入力ピンとして使用する場合のプルアップ・プルダウンについては以下のリンクが参考になりました。

bare metal - Modifying GPIO memory for one pin turns multiple on - Raspberry Pi Stack Exchange

現状では、Pi Zero WのLEDの点灯・消灯がGPIO47への出力(0で点灯)と入力(LEDを通じてVCCに接続されているので1になる)ができることが確認できています。

Raspberry PiのGPIOには、シンプルな入出力のほかに、SPIやI2Cとして使うためのAlternate Functionの指定や、割り込み、クロック出力などの機能があります。
いずれ、これらの機能のサポートをPinクラスに追加していきたいと思います。
ラベル:MicroPython
posted by boochow at 00:08| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする

2018年04月05日

Xilinx Artix-7 FPGA 評価ボード「Arty」を動かしてみた

arty01.jpg
XilinxのArtyというFPGAボードを買ってみました。
3月末にRSコンポーネンツで3割引きセールがあり、税抜き10525円と若干お得に買えました。

Arty [Reference.Digilentinc]

Artix-7 35T Arty FPGA 評価キット

このクラスのザイリンクス用評価ボードでは、他にBASYS3というのもあり、どちらにするか若干迷いました。
BASYS3はVGAポートと7セグメントLEDがあります。
ArtyはEthernetポートとDDR RAM(256MB)があり、Arduino用シールドも接続することができます。

以前(といっても、もう10年以上前)Spartan3スターターキットを使っていたことがあり、VGA信号を出すのが面白かったので、VGAポートがあるのはちょっと魅力です。
しかし、DDR RAMとEthernetも同じくらい魅力的ですし、VGAポートは簡単なDACを抵抗で組めば作れるので、Artを選びました。

他に、Alteraという選択肢もありますが、FPGAの部屋さんのお奨めは、趣味で使うならXilinxが良い、ということです。

Xilinxの開発ツールはVivado HLSというツールで、Artyにはバウチャー券が付属しており、無料のWebPackではなくより高機能な「Design Edition」を1年間使うことができます。
インストールには、サポートするデバイスを必要最低限(Artix-7のみ)にしても、20GBほどのスペースが必要です。(このためにSSDを大容量のものに入れ替えました)

vivado-install.png


インストールの終わりにライセンスマネージャーが起動され、ライセンスファイルを読み込めばインストール完了です。
http://xilinx.com/getlicenseへアクセスし、アカウントを作成して、バウチャー券のライセンスキーを入力すると、メールでライセンスファイルが送られてきます。

Vivadoは追って試してみることにして、まずは工場出荷時に書き込まれている回路で動作確認しました。
電源はMicroUSBで供給できるので、Arduino等と同じく、接続はお手軽です。
USB一本で、電力供給のほか、デザインの書き込みやUARTでの通信ができるようです。

出荷時の回路はUARTとGPIOのデモです。
ボード上には、4つのタクトスイッチ、4つのスライドスイッチ、4つのグリーンLED、4つのフルカラーLEDが実装されています。
デモでは、タクトスイッチに以下のような機能が割り当てられています。

・BTN0(右端):4つのスライドスイッチで指定した値をUARTへ表示。値はLEDのPWM制御に反映される。
・BTN1    :RGB LEDで光を左右にスクロール
・BTN2    :RGB LEDで色を変化
・BTN3(左端):メニューへ戻る

arty02.png




とりあえず動作確認は完了です。
次はどこから手をつけるかまだ考え中ですが、ライセンスが1年間なので、のんびりもしていられないですね。
posted by boochow at 11:46| Comment(0) | FPGA | このブログの読者になる | 更新情報をチェックする
人気記事