2017年12月09日

Raspberry Pi ZeroとPico Hat Hackerが届きました

rpi-zero.jpg

英国にPimoroniという電子工作関連のオンラインショップがありますが、先日セールをやっていたのでRaspberry Pi Zero(と、カメラモジュールとか細々としたもの)を買いました。
すぐ使用する予定は無いのですが、なぜか日本では品薄でなかなか購入できないので、この機会にまとめ買いです。
以前Pi Zero Wもこのショップで購入しています。
購入した品物は大体2週間以内には届きますので、感覚的にはAliexpressよりも対応が早いです。

上の写真の中央がPi Zero、左がPi Zero Wです。
並べてみると、サイズは同じですがZero Wはラズベリーのロゴがない代わりにWiFi/BLEのチップが追加されています。

右はオマケでついてきたPico Hat Hackerです。GPIOに他のHatをつけるとGPIOにアクセスできなくなってしまいますが、このボードを挟めば大丈夫!という代物です。
ただ、ネットを見ていると「Pi Zeroの40本のピンヘッダをハンダづけするのが辛い!」という声もあるようなので、その倍の本数をハンダ付けしないといけない本品はちょっとマニアックかもしれませんね。
posted by boochow at 16:01| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする

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 | このブログの読者になる | 更新情報をチェックする

2017年11月19日

Raspberry Pi Zeroにカラーのピンヘッダを装着

rpi-color-gpio.jpg

これまでRaspberry Piを電子工作的には使ってこなかったこともあり、RPi Zero WのGPIOにはピンヘッダをつけていなかったのですが、ベアメタルの実験用にピンヘッダをつけました。

ピンの機能が色分けされた製品があったので、それを使ってみました。
英国で電子工作関連のグッズをいろいろ売っているPimoroniの製品です。

Colour-coded GPIO Header for Pi Zero - Pimoroni

国内では千石電商で買えます。200円でした。

COM1111 Colour-coded GPIO Header for Pi Zero

この色分けの意味ですが、5Vが赤、3.3Vが黄色、GNDが黒です。
rpi-gpio.png


ここまではいいのですが、水色のピンがあって、これは「何も繋ぐな」(Do Not Connect)となっています。
わざわざピンを引き出しておいて、繋ぐなとはどういうことでしょう。
回路図を見ると、この2本のピンの用途が書いてありました。
rpi-gpio-idsc-idsd.png

このピン(ID_SD、ID_SC)は、Raspberry Piに接続するボード(HAT)上のEEPROMを接続するための端子だそうです。
信号的にはI2Cですが、ブート時にここからEEPROMを読み取って、それにあわせたGPIO設定をするためのものなので、それ以外の目的に使ってはいけない、ということです。

この信号の使い方については、Raspberry Piのブログに記載があり、仕様もGitHubで公開されています。

Introducing Raspberry Pi HATs - Raspberry Pi

raspberrypi/hats

OpenClipartにRaspberry Piのピン配列があったので貼っておきます。

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

Raspberry Pi2でベアメタルプログラミング環境を作成

rpi-baremetal1.jpg

先日ちょっと調べたRaspberry Piのベアメタルプログラミングですが、やはり調べたら試してみたくなるもので、Interface誌2017年2月号の記事の通りにやってみました。

ちょっと試すだけならQIピンでの接続でもいいのですが、UARTとJTAGをつなぐとなると結構な本数になりますので、接続用の基板を作成することにしました。
上の写真のように、Raspberry PiのGPIOヘッダと、JTAG用およびUART用のコネクタを接続した基板です。

ターゲットマシンはRaspberry Pi2ですが、将来的にPi Zeroでの利用も考えて、aitendoのPi Zero用のユニバーサル基板を使いました。
rpi-baremetal3.jpg

GPIOをそのまま接続した40pinボックスヘッダ、JTAG用の20pinボックスヘッダ、UART用の6ピンヘッダがついています。
GPIOのピン配列はこちらが詳しいです。

40pinボックスヘッダは、デバッグしながら他のI/Oも使いたい場合のために付けてあり、ここからフラットケーブルでブレッドボードなどに配線する想定です。
JTAGは手持ちの製品がSEGGER J-Link(のコピー品?)なので、ボックスヘッダもこの製品のピン配列に合わせて配線していますが、基本的にどこの製品でも20pinなら同じピン配列だと思います。
UARTは、以前から使っているスイッチサイエンスの製品です。6ピンになっていますが、配線はGNDとRX、TXだけです。
rpi-baremetal2.jpg

参考までに結線も載せておきます。

表面
rpi_jtag_uart_surface.png
裏面
rpi_jtag_uart.png


これをRaspberry Pi2につないで、Interface誌2017年2月号のDVDに入っている開発環境のVMをインストールして、Eclipse + OpenOCDでJTAG経由でのデバッグを試しました。
今回は記事の通りにすれば良かったので、かなり楽にできましたが、設定項目は複雑な上に「RPi2の場合は1回目はOpenOCDがうまく動かないので2回起動する」といった謎のバッドノウハウもあり、この記事なしに最初から自分でやろうとしたらかなり時間がかかったのではないかと思います。

なお、付録のDVDではOpenOCDで使用するJ-Link用の設定ファイルは
 /usr/local/share/openocd/scripts/interface/jlink.cfg

です。
インタフェースのシリアル番号を記入するようになっていますので、
# Example: Select J-Link with serial 123456789
#
jlink serial 000000123456

のように頭の0を省略せずに指定します。
また、openocdの起動は
$ sudo openocd -f /home/user/arm/cfg/jlink.cfg -f /home/user/arm/cfg/raspi2.cfg
のようにスーパーユーザの権限で行う必要がありました。

なお、初代RPiとRPi Zero Wは同じCPUを使っていますので、初代RPi用のベアメタルのオブジェクトならRPi Zeroでも動作するのではないかと思って試してみましたが、うまくいきませんでした。
posted by boochow at 00:27| Comment(0) | Raspberry Pi | このブログの読者になる | 更新情報をチェックする
人気記事