2017年12月01日

NUCLEO-F767ZIのMicroPython用Ethernetドライバ

ether01.png

昨日はサンプルアプリのWebサーバを動かしてみたNUCLEO-F767ZIですが、やはりMicroPythonからインターネット接続できるようにしたいところです。

しかし、以前も探してみたことがあったのですが、MicroPythonでNUCLEO-F767ZIのオンボードイーサネットを使うドライバは、現時点ではまだ無いようです。
だめもとで、先日のWIZnet5K+LwIPのドライバと、STM32CubeMXに付属のサンプルコードをを参考に、自分で作ってみることにしました。

中身がまだよく分かっていませんが、これらのコードを適当に切り貼りした結果、どうやらnetworkモジュールの下にEthernetドライバクラスを追加することはできました。
といっても、オブジェクトが生成できただけで、まだまともに動いてはいないのですが。
ラベル:MicroPython
posted by boochow at 00:57| Comment(0) | stm32 | このブログの読者になる | 更新情報をチェックする

2017年11月30日

NUCLEO-F767ZIでWebサーバ


NUCLEO-F767ZIのEthernet端子はMicroPythonからは使えないので、テストのために付属のアプリケーションを動かしてみました。

以前ちょっとだけ使ってみたSTM32CubeMXと一緒に配布されているものです。
C:\Users\ユーザ名\STM32Cube\Repository\STM32Cube_FW_F7_V1.8.0\Projects\STM32F767ZI-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS\SW4STM32

に入っています。(入っていない場合は、CubeMXのメニューのHelp→Install New Librariesから、最新の「Firmware Package for Family STM32F7」を選択してインストールします。)
これを、SW4STM32のImport...からGeneral→Existing Projects into Workspaceでワークスペースに追加してビルドします。

デフォルトではDHCPで動作しますので、動作しているIPアドレスのアタリをつける必要があります。

とりあえずEthernetが正常に動作していることは確認できました。
STM32F7-http-server.png


STM32CubeMXですが、このNUCLEO-F767ZIのように多機能なボードになってくると、初期設定を行うコードを自動生成してくれるのはそれなりに意味はあるかもしれません。
先日のRaspberry Piのベアメタルプログラミングでも、GPIOのモードを適切に設定するにはマニュアルを調べなければなりませんでしたが、そのへんがGUIで選択していくだけで済んでしまうのは、慣れると便利な気がします。
posted by boochow at 01:07| Comment(0) | stm32 | このブログの読者になる | 更新情報をチェックする

2017年11月27日

NUCLEO-F767ZIを購入

nucleo-f767zi-1.jpg

STM32のボードは以前購入したNUCLEO-F401REを使っていましたが、結構楽しめることが分かったので、上のランクのCortex-M7ベースのボードを買ってみました。
何種類かあるのですが、価格はどれも同じなので数字が一番大きいNUCLEO-F767ZIにしました。
CPUはF767ZI、クロックは216MHz、SRAMは512KB、フラッシュは2MBで、12bitのADCとDAC、4 I2C、4 UART、6 SPIとリソースも豊富です。

早速MicroPythonを入れてみました。
MicroPythonで動くベンチマークテスト的なものがフォーラムの以下のページにあったので

Benchmark comparison of MicroPython boards - MicroPython Forum

試してみたところ、こんな数値になりました。
Pystone(1.2) time for 500 passes = 152 ms
This machine benchmarks at 3289 pystones/second

上記のページにある他のボードは最速でも2212なので、5割増しのスピードです。
ちなみにESP32だと
Pystone(1.2) time for 500 passes = 850 ms
This machine benchmarks at 588 pystones/second
という結果でした。

Ethernetも搭載されているのですが、現時点ではMicroPythonでサポートされていないのが残念です。
nucleo-f767zi-2.jpg
posted by boochow at 22:49| Comment(0) | stm32 | このブログの読者になる | 更新情報をチェックする

2017年11月26日

Raspberry Pi Zero WでベアメタルUART

mini-uart.png

昨日のLチカに続いて、Raspberry Pi Zero WでUARTでのテキスト送受信を試してみました。
コードは以下で公開しています。

bare_matal_rpi_zero/mini-uart at master ・ boochow/bare_matal_rpi_zero

Raspberry Piシリーズでは、UARTはGPIO14/GPIO15を使うようになっており、その接続ピンは先日作った実験用ボードでUSB-UARTアダプタに接続できるようにしてあります。

最初は、昨日と同じく「BareMetalで遊ぶ Raspberry Pi」の通りに進めていたのですが、どうしてもUARTが反応してくれません。
これはどうもPi Zero WのI/OがPi model Aと違うのだろう、ということでいろいろネットの情報を探してみました。

その結果、どうやらPi Zero WではGPIO14/GPIO15にUARTを割り当ててはいるものの、正式なUARTを使用することはできず、mini-UARTという簡易型UARTを使用するか、またはBluetoothを使わない前提でUARTを使うか、という選択であるらしいことが分かりました。

以下のdwelch67さんのリポジトリにあるPi Zero用のUARTサンプルはPi Zero Wでも動作しました。

dwelch67/raspberrypi-zero: Raspberry Pi Zero baremetal examples

このサンプルは、Mini-UARTを使っています。
Mini-UARTは上記の本でも解説されていますが、正規のUARTよりも若干機能が制約されます。
BCM2835 ARM Peripheralsによると、Mini-UARTはUARTと違って

• Break detection
• Framing errors detection.
• Parity bit
• Receive Time-out interrupt
• DCD, DSR, DTR or RI signals

をサポートしないと書かれています(2.2節)。
なので、上記の本では発展性を考慮してmini-UARTではなく本来のUARTを使って解説されているのでした。

mini-UARTはどのRaspberry Piでも動作しますが、本来のUARTが動作しないのはPi Zero WとRaspberry Pi3のようです。Raspberry Pi3については、以下でちらりと触れられていました。

Raspberry Pi3 のシリアルコンソールで通信速度が合わない - Qiita
Raspberry Pi 3 になって、Bluetooth のサポートのために、GPIO の UART の割り当てが変更され、uart1 を使うようになった。
uart0 は Bluetooth が使うようになっている。


おそらく、Pi Zero Wについても同じ事情でUARTの割り当てが変更になったと思われます。

さらに調べていくと、以前も触れたPi用ベアメタルOSであるultiboのフォーラムで以下のような書き込みを見つけました。

GPS Receiver connected to UART on Raspbberry Pi Zero W - ultibo.org
When the WiFi/BT was added FPF swapped the Uarts.
TX0/RX0 on the Header is now the miniuart Page 8 manual.
The BT chip uses Uart 1 page 175.
Page 102 show the peripheral alternatives for the header 14/15.
As the WiFI/BT is not yet supported by Ultibo, you could alt5 the GPIO pins 14/15 to use the PL011 uart.


このPage XXというのは、前述のBCM2835 ARM Peripheralsのページ番号のようです。
GPIO14, GPIO15のモードをALT 5にすればmini UARTが使える、ということですが、確かに上に挙げたdwelch67さんのコードでも、そのようにしてmini UARTを使っていました。

PL011 uartというのはARMが実装しているUARTで、これはARMからマニュアルが配布されています
しかし今回はとりあえずmini-UARTの動作を確認してみることにしました。
うまく動かなくても、上記のdwelch67さんのコードと見比べれば、レジスタの操作が正しいかどうか確認できるからです。

思ったよりだいぶ手間取りましたが、以上の結果を踏まえて初期設定〜キャラクタの出力〜エコーバックを行うコードを何とか動作させることができました。
あまりオリジナルな部分はないのですが、前回のLチカ同様、インラインアセンブラを使っているので見かけ上はCのコードだけになっているのが取り柄です。


なお、mini-UARTについて調べている過程で行き当たった以下のページで紹介されているコードは、かなり短くてまさにmini-UARTは簡易版UART !、という感じですので一見の価値があります。

ラズパイ3でベアメタル - その3:シリアル通信(UART)でデータ送信(割り込みなし) - へにゃぺんて@日々勉強のまとめ

ただし、これだけ短いコードにするにはブートローダにmini-UARTの初期化をさせる必要があり、それにはSDカードに置く「config.txt」に「enable_uart=1」を記載する必要があるそうです。
config.txtなしの状態でも初期化されているのか気になって、config.txt抜きで動作させようと試みたのですが、少なくともGPIO14、15をALT5にする設定と、mini-UARTのボーレートの設定、データ長を8bitにする設定は行う必要がありました。
posted by boochow at 18:39| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする

2017年11月25日

Raspberry Pi Zero WでベアメタルLチカ

先日環境を整備したRaspberry Piでのベアメタルプログラミングですが、Raspberry Pi 2では動作したものの、Pi Zero Wは置き去りになっていました。
どちらかというとPi Zero Wのほうが小さくて実験に使いやすいので、こちらでもベアメタルプログラミングを試してみました。

JTAGはちゃんと動くようになるまで大変すぎたので、初心に戻ってシンプルなLチカから開始です。
教材には「BareMetalで遊ぶ Raspberry Pi - 達人出版会」を使いました。

環境構築で利用したインタフェース2017年2月号は、Raspberry Piに限らずARM全般を扱おうとしていますが、Raspberry Pi固有の事情には上記の本のほうが詳しいですし、紙数がある分、わかりやすくなっていると思います。

rpi-led.png


というわけで、まずはこの本のLチカを試してみました。オンボードのLEDを点滅させるもので、配線しなくていいのでお手軽です。
ただ、この本は初代Raspberry Piを前提としていますが、Raspberry Pi Zero Wでは使用するGPIOポートが違います。

ACT LED on RPi Zero W - Raspberry Pi Forums

このへんの情報は上記のRaspberry Piフォーラムに書かれていました。
整理すると、

 GPIO16を使用: model A/B
 GPIO47を使用: model A+/B+/2B/Zero/Zero W

 GPIO=Lで点灯: model A/B/Zero/Zero W
 GPIO=Hで点灯: model A+/B+/2B

となっているそうです。
この情報は回路図からは読み取れないので、device treeを見るとよい、とコメントされています。

ちなみに、上記のスレッドには、Raspberry Pi/Pi Zero用のベアメタルのコードを沢山リリースされているdwelch67さんが「ベアメタルってこうなんだよね。コードを書くよりも情報を探すほうが難しい。Linuxのソースを読んだり、フォーラムを読んだり。ドキュメントは間違っていると仮定しなけりゃならないし、チップやペリフェラルにはたいていバグがある。」なんていう感じのコメントをされています。


もう一つRaspberry PiのGPIOで押さえておかないといけないのは

・モード切替(GPFSEL0 〜 GPFSEL5)、ピンをHにする(GPSET0、GPSET1)、ピンをLにする(GPCLR0、GPCLR1)が別レジスタ
・モード切替は1つのGPIOにつき3ビット使用する

という点です。
特にモード切替レジスタは、1つのレジスタが32bitなので、10本のGPIOしか表現できません。
一方でGPIOは0〜53まで、54本ありますので、モード切替レジスタが6個もあります。
今回はGPIO47をいじるので、GPFSEL4のbit21〜23を設定しなければなりません。

なお、上記の本のサンプルでは、点滅にRaspberry Pi内蔵のタイマーを使っていますが、このコードはZero Wでもそのまま動作します。

ベアメタルなので、初期化コードはアセンブラ、メモリマップに従ってリンカスクリプトも書かなければならない、ということでどうやら動作するものができました。
ファイル一式は以下のリポジトリに置いてあります。
Interface2017年2月号の付録の開発環境で、ビルドできることを確認しました。

bare_matal_rpi_zero/led_blynk at master ・ boochow/bare_matal_rpi_zero

通常、初期化コードだけはアセンブラで書きますが、今回はCのインラインアセンブラを使いました。
このコード(void Init_Machine(void))はmain.cの中で他のコードよりも前に置かなければなりません。
Raspberry Piはブート時にコードを$8000から開始するようになっているので、$8000にこの実行コードを置かなければならないからです。
リンカスクリプトをうまく書けば特定の関数を先頭に持ってこれないか、といろいろ試してみたのですが、うまくいきませんでした。
オブジェクトファイルが分かれていれば順序を指定できるようですが、同じオブジェクトファイルに含まれる関数のメモリマップ上での配置は指定する方法が無いみたいです。
リンカはめったにいじらないので、私が不慣れなだけかもしれません。やり方をご存知の方はコメント下さい。

また、Init_Machine(void)はどこからも呼ばれていないが削除してはいけないので、リンカスクリプト内でKEEP指定をしています。
そして、ソースコード内では関数の頭にコンパイラが勝手にコードを付加しないようにnaked指定をしています。


makeするとkernel.imgが作成されますので、これをbootcode.binおよびstart.elfと共にSDカードへコピーするとLチカが動作します。
最新のbootcode.binとstart.elfはRaspberry PiのGitHubからダウンロードして下さい。

なお、Makefileでは、make deployでkernel.imgをSDカードにコピーするようになっています。
ただし、このコピー先は環境によって異なりますので、自分の環境に合わせて書き直す必要があります。

posted by boochow at 20:49| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
人気記事