目次: GCC
目次: Linux
Crosstool-NGはRISC-Vに対応していないのかと思っていたら、Experimentalオプション(CT_EXPERIMENTAL)をYに設定したらRISC-Vが選べるみたいです。
GCCのビルドはARM向けに昔チャレンジしましたが、結構面倒くさいので、コンパイラを含むツールチェーンを簡単にビルドできるCrosstool-NGの存在は非常にありがたいです。あとはLLVMにも対応してくれたら最高なんですけどね。
ExperimentalというだけあってRISC-V 32bit用のコンパイラはビルドエラーになってしまって作成できません。RISC-V 64bit用のコンパイラは作成できます。
作成したコンパイラで適当なコードをビルドして逆アセンブルを見ると、命令長が32bitのものと、16bitのものが混在していました。そういえばARMもARM命令とThumb命令の2種類の命令長があります。最近はRISCでも命令長可変の仕様が流行りなんでしょうか?
メモ: 技術系の話はFacebookから転記しておくことにした。少し加筆。
目次: ROCK64/ROCKPro64
ROCKPro64のシリアル文字化けの原因は、RK3399の端子ドライブ能力不足が原因である可能性は高そうですが、最大値の12mAに設定しても立ち上がりが遅い(立ち下がり50ns以下に対し、立ち上がり300ns以上かかる)点が気になります。
SoC以外に原因があるとすれば、ボードの回路くらいですが、回路となると門外漢も良いところで、確かめ方がわかりません。
ROCKPro64のSchematicsを素直に信じると、SoCの出力ピンが直接コネクタに接続されていて、抵抗も何もないように読めます。RK3399はSoC裏面がハンダ付けされている(BGA)ため、コネクタ〜SoC端子間に、本当に抵抗や断線がないかどうかは確かめようがありません。
文字化けの頻度はかなり減ったので、今のままでもそれなりに使えますが、なぜ立ち上がりだけが異常に遅いのか、釈然としません。うーん……。
ROCK64というかRockchip RK3328のHDMIドライバはdrivers/gpu/drm/rockchip/dw_hdmi-rockchip.cです。このドライバは多くの処理をdrivers/gpu/drm/bridge/synopsys/dw-hdmi.cつまりSynopsys DesignWareのHDMI IP用のドライバに頼っています。
SynopsysのHDMIドライバは映像出力と、音声出力の機能を持っています。映像側の作りは知りませんが、音声側はASoCフレームワークに合わせて作られています。そのお陰でROCK64にHDMI音声出力対応を追加するときは、デバイスツリーに記述を足すだけで良く、非常に楽でした。
Synopsysのドライバはlinux-nextにUpstreamされていますが、コミットログを見る限りSynopsysのメールアドレスの人はあまり出現しません。
社外の人や、会社と関係のない所属の人がわざわざドライバに修正をコミットしてくれるなんて、凄いことだと思います。人気のあるIPのドライバをOSSにすると、色々な人が直してくれて、正のスパイラルが構築される、良い例と言えるでしょう。
この辺の根回しの良さは、さすがIP屋さんのSynopsysって感じがしました。
メモ: 技術系の話はFacebookから転記しておくことにした。追記した。
目次: ROCK64/ROCKPro64
以前(2018年12月)にROCKPro64を購入したのですが、シリアルが文字化けして使い物にならず、ずっとお蔵入りになっていました。
最初はケーブルの接続や、接地がおかしいのかと思いましたが、GND側はきっちり0Vでした。どうも単純な原因ではなさそうだったので、オシロスコープで信号を見ることにしました。テストパターンとして0と1が交互に出現し、一番転送が難しいパターンと思われる0x55 'U' の文字を出力しています。
正常に出力できているROCK64と比較すると、ROCK64は出力が0 → 1 → 0と変化する際に0V → 3V → 0Vのように電圧が振れますが、ROCKPro64は、0V → 2.48V → 0Vのように立ち上がり側が遅く、中途半端な電圧になっています。
下記の画像の青色の線がROCK64のシリアル出力で、オレンジ色の線がROCKPro64のシリアル出力です。どちらも1秒ごとに 'U' を出力して、最初の立ち下がり(Start Bit、必ず0)にトリガを掛けています。
ROCK64は綺麗な波形ですが、ROCKPro64は0V → 3Vへの立ち上がりが間に合っていないことが分かるかと思います。
文字化けの原因ですけども、シリアルの転送速度(1.5Mbps、1ビット666ns)に対し、0 → 1の立ち上がりが遅すぎる(650nsくらい)からでしょう。出力側は1を送出しているつもりでも、信号が立ち上がるのが遅いため、受信側は0だと解釈してしまう場合があります。
転送速度を落とせば改善するかもしれません。しかしRockchipのU-Bootはなぜか1.5Mbps固定で転送してくる困った奴で、下手にシリアルの転送速度を変えるとU-Bootが操作できなくなり、非常に使いづらいのです。イマイチですね……。
ROCKPro64にはRockchipのRK3399と言うSoCが搭載されていて、RK3399は一部のピンのDrive Strength、つまりピンに流せる電流量を調整できます。決して特殊な機能ではなく、大抵のSoCが持つ普通の機能です。
ROCKPro64がコネクタに引き出しているシリアルはUART2です。UART2はGPIO4_C4(TX)とGPIO4_C3(RX)というピンに割り当てられています。幸運なことにRK3399ではこれらのピンのDrive Strengthが変更できるので、設定値を振って(※)オシロで波形を見てみました。
下記の画像が測定結果です。1枚目はデフォルトかつ最小の3mA、2枚目は最大の12mA設定です。出力している文字は前回同様0x55 'U' で、トリガも前回同様Start Bitの立ち下がりに仕掛けています。オシロのRising, Falling Time解析をONにしたので、立ち上がり、立ち下がりに掛かった時間も一緒に表示されています。
Drive Strength = 3mAのときのシリアル出力波形
Drive Strength = 12mAのときのシリアル出力波形
字が若干見づらいので、一応書いておくと、立ち上がりの時間は650ns → 300nsくらいに改善しました。良い感じですね。
ちなみにスクリーンショットの色が変で、文字が読みづらいのは仕様です。Tektronixさん、スクリーンショット背景の白黒反転処理、バグってますよ……??
それはさておきDrive Strengthの変更で、ROCKPro64のシリアル文字化けはかなり改善されました。しかし完全ではなく大量に出力した際に若干文字化けします。
さらなる改善のためには、シリアルの転送速度を落とすくらいしか思いつきません。が、U-Bootの書き換えをするのが面倒くさいので、また今度にします……。
(※)レジスタ名はGRF_GPIO4C_Eで、アドレスは0xff77e138です。書き込む値は0x03c00xx0をお勧めします。xxの部分はドライブ能力を最小にするなら00で、最大にするなら3cです。
メモ: 技術系の話はFacebookから転記しておくことにした。追記、文章の組み換えをした。
目次: Linux
Linuxのクロックフレームワークで実装できるクロック分周器のドライバは2種類あります。
1つはinteger dividerで、入力されたクロック周波数の1/3や1/4など整数比の周波数で出力するハードウェアです。もう1つはfractional dividerで、周波数をx/yにするハードウェアです。
後者のfractional dividerドライバは、標準動作とカスタム動作のドライバが書けます。標準動作の場合、分子と分母に設定できる値に、何ら制約がないものとして動作します。カスタム動作のドライバは、特殊な制約のあるハードウェア向けです。
今のところカスタム動作のfractional dividerドライバを実装しているのはRockchipだけです。Rockchipの場合、分母が分子の20倍以上でなければ出力周波数が不安定になる制約があるようです。
Rockchipが変な仕様であることは間違いないと思いますが、Linuxに対応しているだけ、まだマシとも取れますね。世の中には「どうしてこうなった??」としか思えない、変な仕様のハードウェアがたくさん存在しますし……。
メモ: 技術系の話はFacebookから転記しておくことにした。
< | 2019 | > | ||||
<< | < | 02 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | - | - |
合計:
本日: