TP-Linkのスマートプラグを利用するにはKASA Smartというアプリをスマホに入れないと微塵も動きません。このアプリの利用規約には同意不可能な条項があって、
法的資格
(中略)お客様は利用にあたりお客様に適用するすべての法律を遵守しなければなりません。準拠法が利用を禁ずる場合はお客様は本サービスを利用することはできません。
ユーザーのコンテンツ
(中略)
2. 世界のあらゆる場所で享受できるユーザーコンテンツに対する全ての人格権を放棄し、そのような権利の主張ができないことを確認する。
と書いてあります。TP-Linkは、ユーザーがフォーラムに投稿した質問、レビュー、回答などを勝手に使うけど、文句言わないでね?と言いたいみたいです。
その主張については同意しますけど、、、
日本では著作者人格権は譲渡できません(著作権法59条)、放棄規定はありませんが、包括的に放棄はできないと考えられており、日本においてTP-Linkの利用規約にYesと答えることはできません。
規約内で矛盾がある場合に、利用者が同意してしまうと、この契約はどうなるんでしょう、無効になるの…?
TP-Linkは中国の会社ですから、この利用規約は中国でもほぼ同じなのではないかと思うんですが、中国って著作者人格権の放棄はできるんですかね?
規約のことは忘れて、スマートプラグを使ってみました。
スマホから電源ON/OFFの指示を送ると、スマートプラグから「カッ!!」というかなり大きめのリレー音がしてうるさいです。今日も元気なことがわかって安心……?
使って初めて知ったのですが、スマホからスマートプラグへの電源ON/OFFの指示は必ずTP-Linkのサーバーに飛んで行くんですね。インターネット接続のできない場所ではスマホのアプリが起動しないため、電源ON/OFF指示ができません。
インターネット接続がなくても、スマートプラグ本体の電源ボタンを押せば電源ON/OFFできますが、そこまで行けるならTinker Boardを直接リセットした方が遥かに早いです。
昔から、ネットワーク対応のACタップは売られていましたが(Pingを打つと電源が落ちる、WebインタフェースでON/OFFできるなど)、いずれも1万円〜数万円の製品です。
従来製品と比較して、サーバーの維持費も追加で必要なはずなのに、大抵のスマートプラグは2,000円〜5,000円で販売されています。機能の割に破格の値段だと思います。
単純に考えると、外出中(=インターネット側から)に、宅内の電源をON/OFFするため、何らかのサーバーを経由しているのでしょう。
嫌らしく考えると、スマートプラグはサーバーを経由させることで、ユーザーの生活情報を強制的に奪えますから、将来に情報が何かに使えることを見込んで、破格の値付けでばら撒いているのでしょう。
Tinker Board上でlinux-nextを実行するとreboot時にハングしてしまい、その後ウンともスンとも言わなくなるので、外部からボードの電源ON/OFFする方法を探していました。考え付いた方法は3つです。
1番目は下手なハンダ付けをして、失敗するとボードが壊れることと、制御用にもう1つボードが要るのは何だかダサいのでやりたくありません。
2番目の線で探していたのですが、USBの給電をON/OFFできる製品って、意外とないですね……。
仕方なく3番目の線で、TP-LinkのスマートプラグHS105を購入しました(メーカーの製品サイト)。Amazonで2,600円です。Wi-Fiが内蔵されている割に、ずいぶん値段が安いですね。
メモ: 技術系の話はFacebookから転記しておくことにした。少し加筆した。
目次: ROCK64/ROCKPro64
年末に喰らったA型インフルエンザのダメージも回復したので、RK3328のI2S1のMCLK(マスタークロック)の設定がおかしくなる問題の追跡を再開しました。
思っていた以上に難しくて理解できず、かれこれ1週間以上費やしてしまいましたが、やっと見えてきました。
ざっくり言えばRockchipのSoCが持つクロック分周器の構成がかなり変わっていることが関係している、と言えるんじゃないでしょうか。良し悪しはさておいて、問題の原因になっています。
再現方法はとても簡単です。48kHz → 44kHzの順で再生すると正常に再生できますが、32kHz → 44kHzの順で再生するとエラーになって再生できません。これだけです。
早速、問題の原因を説明したいところですが、Rockchipのクロックがどのように繋がっているか説明しないと、全く何も意味が分からないと思いますので、軽く説明します。
RK3328やRockchipの 他のSoCは、1〜128分周まで可能なInteger Dividerと、有理数で分周(例えば7/500など、分子、分母は16ビット精度の整数で指定可能)が可能なFractional Dividerの2つを持っています。
RK3328のTRM(Technical Reference Manual)では、前者にi2s1_pll_div、後者にi2s1_frac_divという名前を付けており、Linuxのクロックドライバでは前者にclk_i2s1_div、後者にclk_i2s1_fracという名前を付けています。
媒体 | Integer Divider | Fractional Divider |
---|---|---|
TRM(Technical Reference Manual) | i2s1_pll_div | i2s1_frac_div |
Linux Clockドライバ | clk_i2s1_div | clk_i2s1_frac |
今後はLinuxの名前で表記しますが、接頭辞のclk_ は省きます。
I2S系のクロックはInteger DividerとFractional Dividerの両方を利用可能です。他のハードウェアブロックはInteger Dividerしか使えませんが、UARTとI2SとS/PDIFは両方使えるようです。
PLLと分周器とI2S1の接続は下記のようになっています。
CPLL --> | selector |-----> i2s1_div --+--> | selector |--> I2S1 MCLK GPLL --> | | ,---------------' | | `--> i2s1_frac ----> | |
図からもわかる通り、必要に応じてi2s1_fracは使ったり、使わなかったりします。
例えば48kHz, 32kHzで再生する場合は、GPLL -> i2s1_div -> I2S1の経路が使われます。i2s1_fracは使いません。44kHzで再生する場合は、GPLL -> i2s1_div -> i2s1_frac -> I2S1の経路が使われます。
サンプリング周波数Fsと、正しく再生できているときの各分周器の出力周波数、分周比は下記のとおりです。
Fs | i2s1_div出力 | i2s1_div分周比 | i2s1_frac出力 | i2s1_frac分周比 |
---|---|---|---|---|
32kHz | 8.192MHz | 1/60 | 未使用 | 未使用 |
44.1kHz | 491.52MHz | 1/1 | 11.2896MHz | 147/6400 |
48kHz | 12.288MHz | 1/40 | 未使用 | 未使用 |
ちなみにi2s1_divの入力はGPLLが選択されることが多く、周波数は491.52MHzで固定のようです。CPLL/GPLLの周波数は可変のはずですが、切り替わったところを見たことがありません。まあ、GPLLは今回の話に関係ないから、どうでも良いですけど……。
Linuxのクロックドライバは、セレクタで選択可能なクロック系統(この場合だとi2s1_divとi2s1_frac)全てに対して、同じ目標周波数で設定して、目標に一番近い周波数を出力できるクロック系統を選択する仕組みになっています。
例えば先ほど44.1kHzの再生のときはi2s1_fracが選ばれると言いましたが、実はこのときクロックドライバの裏側では、
この2つの選択肢(※)が提示されており、i2s1_fracの方が目標値に近い(誤差0)ため、i2s1_fracが選択されています。
(※)正確に言うと12MHz clkinもあるので3つの選択肢から選びますが、ここでは説明を省いています。12MHz clkinが選ばれることはほぼありません。
先ほど示した表のとおり、32kHzの再生後はi2s1_divの出力が8.192MHzになります。この状態で44.1kHzを再生しようとすると、クロックドライバはi2s1_fracの出力を11.2896MHzにしようと試みます、しかし…。
今のクロックドライバはi2s1_fracの親にあたるクロック、つまりi2s1_divの周波数が目標の出力周波数11.2896MHzより低いと、設定を諦めてしまう実装になっています。
コードで言うとこの部分です。
//drivers/clk/clk-fractional-divider.c
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long m, n;
u64 ret;
if (!rate || rate >= *parent_rate) //★★この部分★★
return *parent_rate;
if (fd->approximation)
fd->approximation(hw, rate, parent_rate, &m, &n);
else
clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
//...
32kHz → 44.1kHzの再生時はrate = 11.2896MHz, *parent_rate = 8.192MHzとなり、★の部分のif文が発動します。これは「i2s1_fracは8.192MHzしか設定できません」という結果を返すことと等しいです。
この結果を受けたクロックドライバの選択肢は下記のようになります。
いずれも目標の11.2896MHzと合いませんが、目標に近いのはi2s1_divと言えます。このためクロックドライバはi2s1_divが最適と判断し、I2S1のマスタークロックが11.214954MHzというおかしな値に設定されてしまいます。
このマスタークロック周波数は、サンプリング周波数44.1kHzの整数倍ではないため、サウンドドライバがエラーと判断してPCM再生を止めてしまいます。
48kHz → 44.1kHzの再生時はrate = 11.2896MHz, *parent_rate = 12.288MHzとなるため、★のif文を突破してfd->approximationの呼び出しに到達します。RockchipのFractional dividerの場合、この関数ポインタはrockchip_fractional_approximation() 関数を指しています。
この関数は変わった処理で、ある条件を満たすと、親のクロックを使うのを諦めて、親の親のクロックを使う処理になっています。
static void rockchip_fractional_approximation(struct clk_hw *hw,
unsigned long rate, unsigned long *parent_rate,
unsigned long *m, unsigned long *n)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long p_rate, p_parent_rate;
struct clk_hw *p_parent;
unsigned long scale;
p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
if ((rate * 20 > p_rate) && (p_rate % rate != 0)) { //★★目標値が親クロックの20倍より大きく、割り切れないとき★★
p_parent = clk_hw_get_parent(clk_hw_get_parent(hw)); //★★親の親(CPLLかGPLL)を使う★★
p_parent_rate = clk_hw_get_rate(p_parent);
*parent_rate = p_parent_rate;
}
通常ならば、存在するかどうかわからない「親の親のクロック」の存在を仮定しており、Rockchipのクロックトポロジー(PLL -> i2s1_div -> i2s1_frac)と、ハードウェア制約に強く依存した特殊な処理になっていることが伺えます。
しかし、この特殊処理のおかげでi2s1_divの周波数がi2s1_fracにとって扱いづらい変な値に設定されていたとしても、親の親(CPLLかGPLL)の周波数に戻すことができます。
48kHz → 44.1kHzの再生時にi2s1_fracだけでなく、i2s1_divの周波数まで変わってしまっているのは、なんだか不思議だなあと思った方も居るかもしれません。その理由は、この関数が親クロックの周波数目標値を書き換えてしまうから、だったんです。
ここまで読んでいただいている方はほぼゼロだと思いますが……、分周器i2s1_divとi2s1_fracの設定が可能かどうか?どちらを選ぶべきか?を判定する部分は、こんな感じの呼び出し経路になっています。
rockchip_i2s_set_sysclk
clk_set_rate
clk_core_set_rate_nolock
clk_core_req_round_rate_nolock
clk_core_get_boundaries
clk_core_round_rate_nolock // I2S1クロックの設定
clk_core_determine_round_nolock
clk_mux_determine_rate
clk_mux_determine_rate_flags // I2S1手前のセレクタの設定
__clk_determine_rate
clk_core_round_rate_nolock // i2s1_divの設定
clk_core_determine_round_nolock
clk_composite_determine_rate // i2s1_divのセレクタの設定
clk_divider_round_rate // Integer dividerの設定
__clk_determine_rate
clk_core_round_rate_nolock // i2s1_fracの設定
clk_core_determine_round_nolock
clk_composite_round_rate // i2s1_fracのセレクタの設定
clk_fd_round_rate // Fractional dividerの設定
rockchip_fractional_approximation // RockchipのFractional divider固有の設定
何度も同じ関数名が出てきて奇妙に見えると思いますが、目標となるクロック周波数の設定を1ブロックだけで解決できないとき、親クロックに対して再帰呼び出しを行い、親の設定を変更しようとする仕組みになっています。
良くできている素晴らしい仕組みだとは思うのですが…、関数ポインタを使って高度に抽象化されているため、コードを見てもどの関数が呼ばれるのか、もう全く全然わかりません。動作もかなり追いづらいし、デバッグが辛いです……。
Yoctoを使ったプロジェクトをビルドする際に、Gitプロトコルを使わないとアクセスできないリポジトリがあります。
Gitプロトコル(git:// から始まるURLのリポジトリ)は無害なんですけど、大抵の社内プロキシを越えられなくて苦労するので、越え方をメモしておきます。
まずGitのプロキシ設定を行います。この例ではgit-proxyというコマンドを使ってくれと指示しています。
git config --global --add core.gitProxy git-proxy
そんなコマンドはないので、自分で作ります。パスの通った場所、例えば ~/bin/git-proxyのようなファイルを作成して、下記のシェルスクリプトを書いておきます。
#!/bin/sh
exec socat STDIO PROXY:192.168.x.x:$1:$2,proxyport=8080
もちろん別途socatコマンドのインストールが必要です。Debianならapt-get install socatでインストールできます。
最初はnetcatでやってみたんですがダメでした。何でだろ?
目次: ROCK64/ROCKPro64
RK3288のGPLL系のクロック周波数が、49151999のようなおかしな値になってしまう問題も、追ってみたら意外と簡単だったのでパッチを作りました。取り込まれることを祈っておきましょう。
たぶん誰も興味が無いと思いますが、下記はRK3328 GPLL系のクロック周波数がおかしくなる問題の詳細です。
まずROCK64には24MHzの水晶が載っていて、RK3328のXIN24Mに入力されています。これがFREFになります。
PLL周波数は仕様書(RK3328 TRM)によると、
FOUTVCO = FREF / REFDIV * (FBDIV + FRAC / 224)
と書かれています。
しかしこれはおそらく誤記で正しくは、
FOUTVCO = FREF / REFDIV * (FBDIV + FRAC / 2^24)
だと思われます。
クロックドライバの実装も後者でしたし、hdkさんに教えてもらった他のRockchipの仕様書でも2^24になっていましたから、RK3328の仕様書にある224は2^24の誤記とみて問題ないでしょう。
最終的なPLL周波数は、
FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
となります。
REFDIV, FBDIV, POSTDIV1, POSTDIV2, FRACに設定される値は、クロックドライバで下記のように定義されています。
//drivers/clk/rockchip/clk-rk3328.c
static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217),
/* vco = 1016064000 */
RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088),
/* vco = 983040000 */
RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088),
/* vco = 983040000 */
RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088),
/* vco = 860156000 */
RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894),
/* vco = 903168000 */
RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329),
/* vco = 819200000 */
{ /* sentinel */ },
};
このコードの何がおかしいのかお見せするため、試しに先頭の行の値を使ってPLL周波数を計算してみます。PLL周波数の目標値であるrateは1016064000です。その他の設定値は、
です。この設定値に基づいて各設定値を計算してみると、
となってしまい、1足りない変な値になります。1足りない原因は2項目の計算結果が63999になってしまうことですから、直すにはfracの値を1増せば良いです。fracを134218にすると、
となって、めでたしめでたしです。
以上の解析結果に基づいてfracの値を1増やすパッチをLinux MLに送りました。英語がイマイチで、うまく説明できず、原始人のような「これ値違う、俺直す」になってしまっていますが……。
RockchipのアーキメンテナのHeikoさんは、コミットメッセージがあまりにもひどいと直してくれる(昔も修正されたことがある)みたいなので、そこに甘えておきます。原始人英語がそのまま取り込まれても別に構いませんし。
目次: ROCK64/ROCKPro64
RK3328のACODECパッチをALSA MLに送ったところ、すんなり取り込まれました。やった。作者が自分ではないドライバを投稿したのは初めてかもしれません。それでも取り込まれるんですね。
あと48kHz → 44.1kHz系に切り替えたときに音が出なくなってしまう病気の応急処置パッチも取り込まれました。素早く切り替えるとやっぱり音が鳴らなくなるんですが、これ以上追う手段が無いので(2018年12月19日の日記参照)諦めています。できればRockchipの中の人に直してほしいね…。
メモ: 技術系の話はFacebookから転記しておくことにした。
目次: ROCK64/ROCKPro64
RK3328のI2S1で44.1kHz系を再生するとEINVALエラーになってしまう問題は、I2Sのマスタークロック周波数が11289600ではなく11289599などという変な値が渡されて、マスタークロックとビットクロックが整数比ではなくなることが原因でした。
エラーを無視して処理を流してみると、分周比がおかしくなります。本来11289600 / 2822400 = 4にならなければいけないのですが、11289599 / 2822400 = 3になって、周波数が高めに設定されてしまい、異常に音が高くなります。
Rockchip Linuxはどうやって解決しているのか見るとDIV_ROUND_CLOSESTというマクロで割り算の結果を4側に丸めていました。本当の原因は変な端数の値を返すクロックドライバだと思うので、この対応はちょっとイケてないですね……。
ACODECにも2つほど問題があって、完全には解決できていません。
問題1つ目は、44.1kHz系を再生すると、全く音が出なくなる症状です。これはコアのリセットで直るようです。
リセットを掛けないと、切り替え以降、何をしても全く音が出ません。しかしRockchip Linuxのコードは全くリセットを掛けておらず、なぜこれで動くのか理解できません……。
気になる点としては、リセットすることでdai_set_fmtで設定されたI2Sのマスタースレーブ設定が吹き飛んでしまうことです。しかしACODECはなぜかマスタースレーブ設定が間違っていても動いてしまいます。ハードが設定値を無視しているか、Rockchip Linuxのドライバが間違っているかどちらかでしょう。真相はわかりません。
問題2つ目は、48kHz系 → 44.1kHz系への切り替え時、たまに音が異常に小さくなる症状です。これは直せそうにないです。
これくらいまではわかりましたが、鳴るときor鳴らないときの法則が全くわからないので、これ以上追うのは厳しいです。
体感では、クロック系の切り替えが早すぎると(1秒くらい?)症状が出やすいです。何でだろう??
while :; do aplay -D hw:0,0 48k.wav ; aplay -D hw:0,0 44k.wav ; done
こんなスクリプトをグルグル回すと、44kHz系は全く音が出ません。待ち時間が足りないのかと思いPRECHARGEの後に500msのウェイトを入れましたが、結果は変わらず音が出ません。。。
Raspberry Pi対抗ボードの多くはRaspberry Pi 3のEthernetが遅いこと(USB接続らしい)を引き合いに出し、ネットワークが速いことを宣伝文句にしています。
宣伝文句自体は疑っていませんが、どの程度の差があるかは知らないので、測定してみました。ちょうどTinker Boardも購入しましたし、Rockchip同士の比較もしてみたいと思います。
測定は簡単です。受信側のPCで下記を実行します。
$ iperf3 -s -p 11111
送信側の各種ボードで下記を実行します。
$ iperf3 -c (PCのIPアドレス) -p 11111
受信側のPCのCPUはRyzen 7 2700で、マザーボードはASUS B450-F GAMINGです。OSはDebian GNU/Linux amd64のTesting版です。測定時点でのカーネルは4.18.0-2-amd64というバージョンになっていました。
結果だけ先に言うとTinker Board(RK3288)の方が速いです。ROCK64(RK3328)の方が後発のSoCなのですが、Ethernetは遅いみたいですね。
ちなみにRaspberry Pi 3は94Mbpsでした。そもそもGigabit Etherじゃないので、比べ物になりません。
念のため各ボードのEthernetケーブルを入れ替えてみましたが、結果は変わりませんでした。
参考までにファイルサーバとして使っているPentium Jのマシンから、同様の計測を行ったところ942Mbits/sec でした。
結果はこんな感じでした。
katsuhiro@linaro-alip:~$ iperf3 -c 192.168.1.2 -p 11111 Connecting to host 192.168.1.2, port 11111 [ 4] local 192.168.1.16 port 58608 connected to 192.168.1.2 port 11111 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 4] 0.00-1.00 sec 113 MBytes 950 Mbits/sec 0 358 KBytes [ 4] 1.00-2.00 sec 112 MBytes 942 Mbits/sec 0 358 KBytes [ 4] 2.00-3.00 sec 112 MBytes 941 Mbits/sec 0 358 KBytes [ 4] 3.00-4.00 sec 112 MBytes 941 Mbits/sec 0 358 KBytes [ 4] 4.00-5.00 sec 112 MBytes 941 Mbits/sec 0 358 KBytes [ 4] 5.00-6.00 sec 112 MBytes 943 Mbits/sec 0 406 KBytes [ 4] 6.00-7.00 sec 112 MBytes 941 Mbits/sec 0 406 KBytes [ 4] 7.00-8.00 sec 112 MBytes 941 Mbits/sec 0 406 KBytes [ 4] 8.00-9.00 sec 112 MBytes 941 Mbits/sec 0 406 KBytes [ 4] 9.00-10.00 sec 112 MBytes 941 Mbits/sec 0 406 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-10.00 sec 1.10 GBytes 942 Mbits/sec 0 sender [ 4] 0.00-10.00 sec 1.10 GBytes 942 Mbits/sec receiver iperf Done.
katsuhiro@rock64:~$ iperf3 -c 192.168.1.2 -p 11111 Connecting to host 192.168.1.2, port 11111 [ 4] local 192.168.1.102 port 54768 connected to 192.168.1.2 port 11111 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 4] 0.00-1.00 sec 97.6 MBytes 819 Mbits/sec 0 356 KBytes [ 4] 1.00-2.00 sec 96.4 MBytes 808 Mbits/sec 0 395 KBytes [ 4] 2.00-3.00 sec 95.8 MBytes 804 Mbits/sec 0 395 KBytes [ 4] 3.00-4.00 sec 95.7 MBytes 803 Mbits/sec 0 395 KBytes [ 4] 4.00-5.00 sec 95.8 MBytes 803 Mbits/sec 0 395 KBytes [ 4] 5.00-6.00 sec 95.8 MBytes 804 Mbits/sec 0 395 KBytes [ 4] 6.00-7.00 sec 95.8 MBytes 804 Mbits/sec 0 395 KBytes [ 4] 7.00-8.00 sec 95.7 MBytes 803 Mbits/sec 0 395 KBytes [ 4] 8.00-9.00 sec 95.8 MBytes 804 Mbits/sec 0 395 KBytes [ 4] 9.00-10.00 sec 95.8 MBytes 803 Mbits/sec 0 395 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-10.00 sec 960 MBytes 805 Mbits/sec 0 sender [ 4] 0.00-10.00 sec 958 MBytes 804 Mbits/sec receiver iperf Done.
katsuhiro@raspberrypi:~ $ iperf3 -c 192.168.1.2 -p 11111 Connecting to host 192.168.1.2, port 11111 [ 4] local 192.168.1.105 port 46476 connected to 192.168.1.2 port 11111 [ ID] Interval Transfer Bandwidth Retr Cwnd [ 4] 0.00-1.00 sec 11.3 MBytes 94.6 Mbits/sec 0 29.7 KBytes [ 4] 1.00-2.00 sec 11.2 MBytes 94.1 Mbits/sec 0 29.7 KBytes [ 4] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec 0 29.7 KBytes [ 4] 3.00-4.00 sec 11.2 MBytes 94.2 Mbits/sec 0 29.7 KBytes [ 4] 4.00-5.00 sec 11.2 MBytes 94.1 Mbits/sec 0 29.7 KBytes [ 4] 5.00-6.00 sec 11.2 MBytes 94.2 Mbits/sec 0 29.7 KBytes [ 4] 6.00-7.00 sec 11.2 MBytes 94.2 Mbits/sec 0 29.7 KBytes [ 4] 7.00-8.00 sec 11.2 MBytes 94.1 Mbits/sec 0 29.7 KBytes [ 4] 8.00-9.00 sec 11.2 MBytes 94.2 Mbits/sec 0 29.7 KBytes [ 4] 9.00-10.00 sec 11.2 MBytes 94.1 Mbits/sec 0 29.7 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-10.00 sec 112 MBytes 94.2 Mbits/sec 0 sender [ 4] 0.00-10.00 sec 112 MBytes 94.2 Mbits/sec receiver iperf Done.
目次: ROCK64/ROCKPro64
Tinker Boardでサウンド周りを有効にしてlinux-nextを動かしてみたものの、指摘された不具合(2018年12月5日の日記参照)が出ません。
メールではDMAドライバのどこかでクラッシュした、と言われました。サウンド周りのハードウェアはI2Sとコーデックが居ますが、DMAを使うのはI2Sだけです。コーデックmax98090はSoC外部に居ますから、SoC内部のDMAを使う術がありません。
I2Sが原因ならば、SoC内部のハードウェア起因ですから、Tinker BoardだろうがChromebook C201だろうが、ボードに関わらず現象が再現しても良さそうなのに。
Chromebookで使われているグルードライバrockchip-snd-max98090の影響も疑って、Chromebook C201のデバイスツリー(rk3288-veyron-speedy.dts)からデバイスノードの設定をパクってきて、max98090をspdif-transimtterに差し替えて(Tinker Boardにmax98090は搭載されていない)、無理やり動かしてみましたが、特に何事も無く動いてしまいました。
どうやってもChromebook C201じゃないと再現しないのかな?良くわからないバグだ……。
ROCK64のときはアナログオーディオ出力でもHDMI出力でも、SoC内蔵のI2Sハードが動作しましたが、Tinker Boardはちょっと事情が違います。
Tinker Boardにもアナログオーディオ端子は付いていますが、接続先はRK3288ではなくオンボードのUSB Audio(Realtek ALC4040)です。アナログオーディオのためにわざわざ専用USBデバイスを載せるとは、豪華なボードだなあ〜。
というわけで、Tinker BoardでSoC内蔵のI2Sが動くかどうか試すには、アナログオーディオ端子ではダメで、HDMI出力じゃないと本当に動作しているかどうかわからないです。我が家にはデジタルテレビならありますが、ボードからケーブルが届かないですね。
できればHDMIが映せて、音も出せて、ボードの隣に置いても邪魔にならないくらい小さいモニタがあるとベストですが、我が家にそんなもんは無い……。
メモ: 技術系の話はFacebookから転記しておくことにした。少し加筆した。
< | 2019 | > | ||||
<< | < | 01 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | 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 | 29 | 30 | 31 | - | - |
合計:
本日: