Moiz's journal

プログラミングやFPGAなどの技術系の趣味に関するブログです

Raspberry Piのベアメタル環境からSDCARDにアクセスする(BUSモード編)

はじめに

Raspberry Piのベアメタル環境からGPIOを経由してSD CARDをアクセスする方法について、BUSモードでも成功したので紹介します

BUSモード

前回のエントリーではRaspberry PiでOSなどを介さず、EMMC 1も使わず、GPIO機能のみを使ってSD CARDにSPIモードでアクセスする方法を紹介しました。 しかし、SPIモードの使用には

  1. 一旦BUSモードで動作すると、SPIモードには再遷移できない
  2. Raspberry PiブートローダーはSD CARDにBUSモードでアクセスる
  3. したがって、デモでSPIモードを使用する前にユーザーがカードを一度抜き差しして、カードをリセットする必要がある

という問題がありました。 また、SD CARDの規格としても、SPIモードはあくまで簡易的にデータにアクセスするための方法です。したがってできることならBUSモードでSD CARDにアクセスしたいと思っていました。

例えば、SPIモードの特徴は以下のとおりです

  1. 使用するピンが少ない。電源とグラウンドを除くと、クロック1ビット、コマンド1ビットとデータ1ビットの、3本の信号線のみ2
  2. 制御が比較的簡単
  3. ただしデータが1ビットしかないので遅い

それに対してBUSモードは

  1. 最大4ビットのデータ線が使える
  2. SD CARDの最近の高速モードに対応している
  3. したがって速い
  4. ただし、制御はSPIモードに比べて若干面倒

となります3。 このように、BUSモードこそがSD CARD本来のモードと言えると思います。

今回は高速化を期待してBUSモードに対応させてみました。

リポジトリと使用方法

今回のデモの内容はGithubで公開してあります。

github.com

使用方法は

  1. 必要ないSD CARDを用意する4
  2. SD CARDにラズビアンOSなどをインストールしてRaspberry Piが起動するようにしておく
  3. SD CARDのboot領域のkernel.imgをリポジトリのkernel.imgで置き換える
  4. SD CARDをRaspberry Piに挿して起動する

なお、デモの結果を確認するにはSerialのTX/RXをRaspberry PiのGPIO#14/15(PIN8とPIN10)に接続し、PCなどのターミナルコンソールに信号の内容を表示させる必要があります。

デモの出力結果は以下のようになります。SD CARDのFAT32領域にアクセスして、ルートディレクトリのファイルを表示しています f:id:uzusayuu:20180730070201p:plain

前回との違い

SPIモードとBUSモードの違いは上記のようにいろいろありますが、今回影響を強く受けたのは以下のような点です

  1. コマンド(CMD)が双方向になった。SPIモードではCMDはホストからカードへの一方通行だったのですが、BUSモードではカードからホストにレスポンスを返すのにも使います
  2. データビットが1ビットから4ビットに増えた。BUSモードでは4本あるデータ線をすべて使うことができます
  3. コマンドやレスポンスのフォーマットがSPIモードと違う。

とくに、コマンドに対するレスポンスがデータと同時に帰ってくることがあるため、両者を同時に処理する必要がある点に注意が必要です。

なお、今回は読み込みまでしか実装していません。

実装の詳細についてはgithubで公開しているソースコードを参照ください5

次への課題

この実験は、もともとは、既存のライブラリで動作していた「Haribote OS」のSD CARD読み込み部分を、自分の実装で置き換えるというのが目的でした。これからそのあたりやっていこうと思っていたのですが、一時帰国で日本に帰った際にこんな本を見つけてしまいました。FatFSという組み込み向けFATライブラリーの解説本です。

shop.cqpub.co.jp

Haribote OSではFATの扱いはごく簡単なもので、残りの実装は読者への宿題になっています。こちらの本で解説されているFatFSを使えば読み書きやディレクトリのアクセスも含めたファイルシステムをサポートすることができそうです。ちょっと気になってきました。

まとめ

Raspberry Piのベアメタル環境でGPIOを経由してSD CARDをアクセスするデモについて紹介しました。 なお今回はリードのみの実装です。また、UHSなどの高速化モードはいっさいサポートしていません。


  1. Raspberry PiのSoC(BCM2835)のSD CARDインターフェース機能

  2. 規格としてはCS(チップセレクト)信号もあるが、Raspberry PiではSD CARDは一つしか繋がらないのでCSは必要ない

  3. 詳しいことはSD Associationが発行している簡易版規格書のパート1をご覧ください。

  4. デモでSD CARDの内容が破壊される可能性もありますので、必ず必要ないSD CARDを使用してください

  5. うまくまとまったらブログに書くことも考えています

Raspberry Piのベアメタル環境からSDCARDにアクセスする(SPIモード編)

はじめに

Raspberry Piのベアメタル環境からSD CARDをアクセスする方法について、限定的ながらある程度成功したので紹介します

周辺機器アクセスはベアメタルの鬼門

ベアメタルというのはOSなしの環境なので、当然ながらプログラミングにあたって各種OSの便利な機能を使うことができません。その中には当然、周辺機器のアクセスも含まれます。
そんな中ベアメタルで周辺機器にアクセスしようとする場合、

  1. ベアメタルで動作するライブラリを見つける
  2. 自分で何とかする
  3. 他の代替手段を探す

といった対策が必要になります。このうち1は一番簡単ではあるのですが、そもそも見つからない、見つかっても自分の目的と微妙に違う、ドキュメントが少ない、などの状況に出会うことがあり、常に万全の状態で使えるとは限りません。実際私が以前OSを移植した時は、Raspberry Piのフォーラムで見つけたSDCARDアクセスコードを許可を得て使わせてもらったのですが、その後バグの存在を指摘されたにもかかわらず動作の詳細が不明なため完全には修正することができませんでした。 また、3は逃げに近いのでなるべく避けたいところです。そうなった場合、「自分でなんとか」しようとするわけですが、次に出会う問題点がベアメタル特有のドキュメントの少なさです。場合によっては情報がまったく無く、詰んでしまう事もめずらしいことではありません。もちろんガチ勢の場合、既存のソフトのリバース・エンジニアリングや対象デバイスの解析などを駆使してどうとでもしてしまうわけですが、われわれ一般人にはかなりつらいところです。

Raspberry PiのSDCARDコントローラー(EMMC)はドキュメントが微妙

数ある周辺機器の中でもストレージは最も基本的なものです。これにアクセスできなければとたんにできる事の範囲が極端にせまくなってしまいます。
Raspberry Piの場合メインのストレージは言わずとしれたSDCARDで、Raspberry PiのCPU(BCM2835)にはEMMC(External Mass Media Controller)というIPが搭載されており、SDCARDとのアクセスをサポートしてくれます。そのEMMCの使い方は、と探してみるとBCM2835 ARM PeripheralsマニュアルにEMMCの項が見つかります(P.65 5 External Mass Media Controller)。
ここで、これは楽勝か?と思いつつ読み進めていくと、どうも勝手が違い読みにくいことに気が付きます。記述が断片的でどのように設定すればばSDCARDにアクセスできるのかわかりません。さらに読みすすめるとこのような文に出会います。

For detailed information about the EMMC internals please refer to the ArasanTM document SD3.0_Host_AHB_eMMC4.4_Usersguide_ver5.9_jan11_10.pdf but make sure to read the following chapter which lists the changes made to ArasanTM’s IP.

どうやらEMMCの使い方はArasanのドキュメントに書いてあり、BCM2835のマニュアルにはそこからの差分しか載っていないようです。記述が断片的なのはそういう理由があったわけです。 それでは、と、Arasanのドキュメントを探すと見つかりません。どこにも見つかりません。インターネット上をさんざん探しましたが、どうやら非公開のようです。やられた...。

まとめると

  • SD CARDへのアクセスが必要
  • BCM2835のEMMCの情報が必要
  • ArasanのIPの情報が必要
  • ArasanのIPのマニュアルは非公開
  • 詰んだ

困りました。

SDCARDのピンはGPIOにつながっている

このように途方にくれながらRaspberry Piのスキマティクスを見ているとSDCARDのピンはGPIOにつながっている事に気が付きました。 f:id:uzusayuu:20180520131226p:plain このあたり専用ピンにつながっているUSBとは事情が違うわけです。さて、ここでこんな考えが頭にうかびます。

「GPIOにつながっているんなら、GPIO経由でソフトでアクセスできるんじゃね?」

これは何も無茶な考えではなく、マイコンなどでは普通に行われる方法です。たとえばCQ出版の「フラッシュ・メモリ・カードの徹底研究」にはソフトウエアコントロールでMMCにアクセスする方法が、同社の「FPGAスタータ・キットで初体験!オリジナル・マイコン作り」にはNIOSからSD CARDにアクセスする方法が記載されています。 やるべきことは、

  1. EMMCを止める
  2. GPIO48から53を、ALT0(EMMC)からInputまたはOutputにつなぎ替える
  3. ソフトウェアからGPIOを制御しSDCARDをSPIモードにする
  4. 同様にソフトウェアでSDCARDの初期化を行う
  5. 同様にSDCARDからの読み出し、書き込みを行う

以上です。ソフトウェアは上記の2書籍に例があるので参考にしつつすすめる事ができます。また、SDCARD自体のコントロールについては、SDのスペック(SD Specifications Part 1 Physical Layer Simplified Specification)に十分な内容の情報があります。なんとかなりそうですね。

SDCARDにアクセスできた、が...

詳細は次回に譲るとして、試行錯誤のすえ、SDCARDの初期化と読み書きアクセスに成功しました。次の図は、SDCARDのFAT領域をベアメタル環境で読みだして、ファイルのリストを表示した結果です f:id:uzusayuu:20180520132857p:plain

今回のデモプログラムはgithubにて公開してあります。

github.com

ただ、ここで大問題があります。
どうやら、次のスペックの記述によると、SDモードからSPIモードへの変更は電源投入後の一回しかチャンスがないようです。SDのスペックの7 SPIの最初の項7.1 Introductionに次のような記述があります。

The interface is selected during the first reset command after power up (CMD0) and cannot be changed once the part is powered on.

Raspberry Piは本体のROMに記録されているブートロジックが最初のブートローダーをSDCARDから読み出すので、この時点でSDCARDはSDモードに設定されています。したがってSPIモードに変更し直すことはできないという事のようです。(痛恨)。 デモプログラムではユーザーにカードの抜き差しをしてもらうことでこの問題点を回避していますが、ちょっと実用的ではありません。やはりSDモードでのコントロールを考えないといけないようです。

あともうひとつ、ソフトウェアコントロールでシリアル通信なので読み・書き・コントロールすべて遅いです。デモではルートディレクトリのファイルを表示するのに1分くらいかかっています。*1

まとめ

以上、Raspberry Piのベアメタル環境からGPIO経由でSPIモードでSDCARDにアクセスすることにある程度成功したので報告しました。 実用性はあまりありませんが、SDCARDにコントロールIPをはさまず直接アクセスできるので、SDCARDの動作を理解するのには役に立つのではないかと思います。 次回以降、処理の詳細について説明したいと思います。

*1:これはさすがにちょっと遅すぎるので、どこか他の部分に問題があるのかもしれません。そのうちどこが本当にボトルネックになっているか調べてみたいと思います。

プロセッサの中のプロセッサとインストラクション・セットの多様性

プロセッサの中にも多数のプロセッサがいる

最近出版された「コンピュータ・アーキテクチャ 定量的アプローチ 第六版」に新設された第7章のドメイン・スペシフィック・アーキテクチャ(DSA)の章を読んでいたところ、面白い記述があった。まず前提としてライセンスの面倒さなどから、DSAには独自のRISCプロセッサを導入して、コンパイラやライブラリを移植することが多いという前置きのあとで、このように書かれている。

One AMD engineer estimated that there were 12 instruction sets in a modern microprocessor! (あるAMDのエンジニアの見積もりでは最近のマイクロプロセッサには12種類のインストラクションセットが含まれているという)

AMDのエンジニア、最近の、という言葉からおそらくRyzenやその関係のプロセッサではないかと思うが、実際にどのプロセッサなのかかは定かではない。 私自身も半導体の会社で働いているのでSOCに*1はメインのCPU以外にも多数のプロセッサが搭載されていることは事実として知ってはいたが、12種類のインストラクションというのは随分多いと感じる。なにしろインストラクション・セットが12種類ということは、搭載されているプロセッサは少なくとも12個以上で、そのうち命令が異なるものが12個ある、ということだ。 しかし同時に、いや大規模なSOCならそれくらいあってもおかしくないぞ、とも思う。

プロセッサ中のプロセッサの例

こういったSOCの中にメインのCPU以外に含まれるプロセッサというのは、内部の制御用だったりハードウェアの動作の一部または全部を引き受けたりするものなので、基本的にエンドユーザーやアプリケーション作成者からは見えないようになっている。したがって開発関係者以外には、仕様も場合によっては存在自体も隠されていることが多いのだが、ときどきその存在が表に現れる。

まず例としてAMD自身がEPYC中にX86とは別のプロセッサをセキュリティ用に搭載していることを発表している。

pc.watch.impress.co.jp

記事中「ARMのCortex-A5をセキュリティエンジンとして搭載しており、OSインディペンデントなセキュリティを提供する。」とある。つまり、EPYCにはOS上の操作しかしない一般ユーザーからは見えないプロセッサが最低でも一個搭載されていることになる。当然このプロセッサ用の開発環境、ライブラリ、OSはメインCPUとは別に作られ、チップの開発チームやパートナーのみに提供されているのだろう。

また、Tensilica*2のXtensa DSPは、Wikipediaの記述を信用するなら、PS4のプロセッサや、AMDのAPUなどに採用されているようだ。

Tensilica - Wikipedia

AMD TrueAudio - Wikipedia

これはWikipediaの記述だが、私自身もXtensaがオーディオ用として他のSOCに採用された例を見ているし、Tensilicaによるとこれまでに1400以上の採用実績があるということなので、多数のSOCで搭載されているのはおそらく間違いない。

ip.cadence.com

AMD以外に目を向けると、以前私も開発に関わっていた携帯用SOCのOMAPの画像処理プロセッサにはARMのCoretex-Mが制御用として搭載されていた。

http://www.ti.com/pdfs/wtbu/OMAP4470_07-05-v2.pdf

http://www.ti.com/lit/wp/spry242/spry242.pdf

OMAPシリーズにはこの他に画像処理アクセラレータのiMX、さらには当然ながらTIのDSPも搭載されており、GPUと合わせて今流行りのHeterogeneous Computingの先駆けを進んでいたと言っていいだろう。このあたりはTI自身が公開している上記の資料に詳しい。

ISAの多様性とRISV-V

ここで例にだしたのはセキュリティ、オーディオ、あとは画像処理という3種類のIPだが、現代のSOCにはこれ以外にも多種多様のIPコアが含まれている。 ちょっと考えただけでネットワーク、ディスプレイ、USB、電源管理、ストレージ、などなど。それぞれに専用のIPがありそれぞれ制御が必要な事を考えると、いくつかには専用プロセッサが搭載されていると推測するのは大きく間違ったことではないだろう。IPごとに必要な機能に過不足ないプロセッサを採用することを考えると、それぞれインストラクションが異なるということは十分にありそうな話だ。そうなれば最初の「最近のマイクロプロセッサには12種類のインストラクションセットが含まれている」という話もあながち大げさというわけではなさそうだ。さらに考えると、このプロセッサ群は当然コンパイラやライブラリーと一緒に提供され、多くの場合OSが動作しているはずだ。またデバッガなどの開発支援環境も当然それぞれ存在するのだろう。こういった想像は、これまで複数の会社でSOC開発に関わってきた私自身の過去の経験ともそんなに乖離していない。

また、SOCというと携帯や組み込み機器の中に入っているもの、というイメージがあるのかもしれないが、実は最近のPCのCPUはほとんどの場合SOCだ。 これはタブレット型や2in1タイプはもちろんのこと、ラップトップ、さらには多くのデスクトップまであてはまる。こういったPCに搭載されるCPUは、電源やUSB、メモリインターフェースといった昔からある機能はもちろんのこと、オーディオ、ビデオ、カメラ、などなど、PCに必要な機能の多くをオンチップで搭載している。例えば最近のノートPC用のチップを考えると、ダイ上の面積的に一番大きいのは大概GPUで、X86のコードを実行するいわゆるCPUと呼ばれる部分の面積はさらに残りの部分の半分ほどの事が多い(実際の面積比はSKUによって大きく異なります)。つまり、CPUの占める面積は意外なほど小さいのだ。

そして、残ったの面積は多数のIP*3が占めている。我々が普段使っているPCのCPUには、私達が存在も知らずアクセスすることもできないプロセッサが多数搭載されていて、その上で専用のコードやOSがユーザーの意志とはまったく関係なしに動きまわっている可能性が高いわけだ。

そう考えると、x86系とARM系の寡占化が極まったと考えられているCPUのインストラクションセットも、実は意外なほどの多様性を備えていることがわかるだろう。同様に、CPUの構造(マイクロアーキテクチャ)や、その上で動作するアセンブラ、OS、また開発に使用するコンパイラなども同様に多様なのだ。

では、これからもその多様性が広がっていくか?と考えると、少し疑問が残る。まず、明らかな問題として無駄が多い。たった一つのSOCを開発するのに12個も開発環境を用意し、それぞれノウハウもスキルベースも異なるコードを開発しメンテナンスするのはどう考えてもコスト高だ。さらに、一個一個のプロセッサに割ける人員も時間も予算も限られるので一つ一つが十分に洗練されていない、という可能性も出てくる。当然、ちょっと数を減らそうか、という話はでてくるはずだ。

ここで最初の「コンピュータアーキテクチャ」に話を戻すと、この本では「だからRISC-V*4」を使おう、という主張になっている。統一されたインストラクション、共通の開発環境を使えばこういったムダが一層されるわけだ。

さて、私自身はこれを読んだあとも「そううまくいくかね?」と思っていたのだが、先日こんなニュースが飛び込んできた。

www.itmedia.co.jp

このヘネシー氏は「コンピュータアーキテクチャ」の著者の一人。もう一人のデビッド・パターソン氏もGoogleに在籍していることを考えると、今後GoogleRISC-Vに力を入れてくることは予想に難くない。そうなると、意外とRISC-Vが広がってインストラクションセットの多様性を終焉させる、ということもありえないわけではないのかな、という気がしている。

さて、どうなりますかね?

*1:システムオンチップ, SoCとも

*2:現在はCadenceの一部

*3:Intellectual Property、半導体分野では機能ブロックやその設計資産を示す

*4:RISC-VはオープンでフリーなCPUインストラクションセット。最近盛り上がりをみせている

「実践コンピュータビジョン」の全演習問題をやってみた、というブログを書いた

夏頃にオライリージャパンの「実践コンピュータビジョン」という本を読み、全演習問題に挑戦しました。もともとこのブログにそのことを書こうと思っていたのですが、はてなブログでは大量のコードが出てくる記事を書くのがなんともおっくうで、延ばし延ばしになってきました。

先日思い立って、コードなどを書くのに楽なQiitaの方でそのことをブログに書きました。まとめ一つと、各10章に対応するエントリー、合計11本です。

 

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

ブログが分散するのは管理も大変だし、あまり好ましくないんですが、はてなでブログでコード挿入するのが面倒なのはなんともならず。いまさらはてなダイアリー表記に戻す気にもならず。

衣類乾燥機を修理してみたよ

衣類乾燥機が壊れた

先日衣類乾燥機が突然動作しなくなった。

パネルやモーターなどは普通に動いていて排気口からは風も出てくるが、温度が上がらず当然衣類もまったく乾かない。買ったのは四年前で当時入ったショップの延長保証も1年前に切れている。さて困った。買い換えか。

直し方をWEBで調べる

どうせ買い替えするのなら、最後遊びだと思って修理に挑戦してみよう。そう思ってWEBを検索すると多数衣類乾燥機の修理例がでてくる。さすがDIYの国アメリカ。後で書くが、乾燥機の構造自体も修理を前提として作っているような節がある。

どうやら、『一見普通に動作してそうなのに温度が上がらない』という場合の典型的な故障箇所は、ヒーターユニットかヒューズらしい。Youtubeに私が使っている製品とほぼ同じ機種について、詳細な点検方法と修理方法がアップされていた。

www.youtube.com

たぶんこれなら自分で直せそうだと判断し、早速分解にかかる。

分解!

工学系のステロタイプよろしく、私は分解が好きだ。大好きだ。

物をばらして中がどう動作するのか調べるのはわくわくする。そして良く壊す。今回はもともと壊れているので、さらに壊してもたいした損害じゃ無いから気が楽だ。そんなわけでどんどん分解していく。

手ぶれが酷くて申し訳ないが、これが元の姿。

f:id:uzusayuu:20171002122955j:plain

上部及び前面パネルとドアを外したのがこちら。

f:id:uzusayuu:20171002123013j:plain

これを見ればわかると思うが、かなーり大雑把な構造だ。日本のメーカーが日本向けに作ればサイズは2-3割小さくなるのではないかと思う。おそらくアメリカ向けの製品はサイズや機能よりも直しやすさ(部品の入手性含めて)が重視されているのだろう。

さてこのドラムを外すととうとうヒーターユニットとご対面だ

f:id:uzusayuu:20171002123054j:plain

雑!、というのが正直な感想だが、おかげで修理ができるので文句をいう筋合いもないだろう。コネクタを外してマルチメーターでヒーターの抵抗をしらべると無限大とでた。これでヒーターの故障に間違いないだろう。

修理

ヒーターユニット部分の蓋を外してみるとこんな感じのヒーターユニットが入ってた。

f:id:uzusayuu:20171002124744j:plain

子細に点検すると、あった。

f:id:uzusayuu:20171002123130j:plain

見事に切れてる。これじゃ温度が上がるわけが無い。早速交換部品をアマゾンで購入。$20を切る値段だった。安い。

左が故障したヒーターユニット、右が新品。

f:id:uzusayuu:20171002124404j:plain

新しいヒーターユニットの取り付け。

f:id:uzusayuu:20171002123034j:plain

一応導通と絶縁を確認して、後は、ドラムやパネルを一個一個元に戻していくだけ。最後に電源を戻し、試運転、無事動作しました。

まとめ

服が乾かない!の第一報から修理まで3日で済んだ。金銭面でずいぶん安く済んだのはもちろんのこと、修理を頼無にせよ新品を買うにせよおそらくは2週間くらいはかかっただろうと考えると、時間の節約という面でもずいぶんDIY修理のメリットはある。(日本みたいに次の日配達据え付けとかならいんだけどね...。)

今回衣類乾燥機を分解して思ったのは、アメリカ向けの家電は、機械自体も部品の入手性も、あと、情報の入手性も、修理がしやすいようにできている、ということ。その分最新の機能だとか、コンパクト性だとか、電力効率だとかは手薄になっているのかもしれない。おそらく日本の日本向けの製品とは思想が違うのだろう。なんにせよ、面白かった。(あと、ちゃんと直って良かった。)