link もっと前
   2019年 1月 11日 -
      2019年 1月 2日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

スマートプラグの利用規約

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 するため、何らかのサーバーを経由しているのでしょう。

嫌らしく考えると、スマートプラグはサーバーを経由させることで、ユーザーの生活情報を強制的に奪えますから、将来に情報が何かに使えることを見込んで、破格の値付けでばら撒いているのでしょう。

[編集者: すずき]
[更新: 2019年 1月 12日 23:39]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

スマートプラグ

Tinker Board 上で linux-next を実行すると reboot 時にハングしてしまい、その後ウンともスンとも言わなくなるので、外部からボードの電源 ON/OFF する方法を探していました。考え付いた方法は 3つです。

リセット信号を外部から送る
Tinker Board はリセットスイッチが搭載されているので、リセットスイッチを物理的に外して、別のボードの GPIO などを繋げばリセットできます。
USB の電源を ON/OFF する
USB micro B プラグでの給電のため、USB の電源を ON/OFF することができれば、コールドリセットできます。
AC ON/OFF する
当たり前ですが AC アダプタ(AC 100V → USB)の電源を ON/OFF すれば、コールドリセットできます。

1番目は下手なハンダ付けをして、失敗するとボードが壊れることと、制御用にもう 1つボードが要るのは何だかダサいのでやりたくありません。

2番目の線で探していたのですが、USB の給電を ON/OFF できる製品って、意外とないですね……。

仕方なく 3番目の線で、TP-Link のスマートプラグ HS105 を購入しました(メーカーの製品サイト)。Amazon で 2,600円です。Wi-Fi が内蔵されている割に、ずいぶん値段が安いですね。

メモ: 技術系の話は Facebook から転記しておくことにした。少し加筆した。

[編集者: すずき]
[更新: 2019年 1月 12日 23:22]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

ROCK64 で 32kHz → 44.1kHz の順に再生するとエラーになる

年末に喰らった A 型インフルエンザのダメージも回復したので、RK3328 の I2S1 の MCLK(マスタークロック)の設定がおかしくなる問題の追跡を再開しました。

思っていた以上に難しくて理解できず、かれこれ 1週間以上費やしてしまいましたが、やっと見えてきました。

ざっくり言えば Rockchip の SoC が持つクロック分周器の構成がかなり変わっていることが関係している、と言えるんじゃないでしょうか。良し悪しはさておいて、問題の原因になっています。

現象と再現方法

再現方法はとても簡単です。48kHz → 44kHz の順で再生すると正常に再生できますが、32kHz → 44kHz の順で再生するとエラーになって再生できません。これだけです。

Rockchip のクロックと分周器

早速、問題の原因を説明したいところですが、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_ は省きます。

Rockchip の I2S クロック

I2S 系のクロックは Integer Divider と Fractional Divider の両方を利用可能です。他のハードウェアブロックは Integer Divider しか使えませんが、UART と I2S と S/PDIF は両方使えるようです。

PLL と分周器と I2S1 の接続は下記のようになっています。

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 が選ばれると言いましたが、実はこのときクロックドライバの裏側では、

  • i2s1_div: CPLL 1.2GHz / 107 = 11.214954MHz
  • i2s1_frac: i2s1_div 491.52MHz * 147/6400 = 11.2896MHz

この 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 より低いと、設定を諦めてしまう実装になっています。

コードで言うとこの部分です。

Fractional Divider のドライバ(一部)

//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 しか設定できません」という結果を返すことと等しいです。

この結果を受けたクロックドライバの選択肢は下記のようになります。

  • i2s1_div: CPLL 1.2GHz / 107 = 11.214954MHz
  • i2s1_frac: i2s1_div 8.192MHz

いずれも目標の 11.2896MHz と合いませんが、目標に近いのは i2s1_div と言えます。このためクロックドライバは i2s1_div が最適と判断し、I2S1 のマスタークロックが 11.214954MHz というおかしな値に設定されてしまいます。

このマスタークロック周波数は、サンプリング周波数 44.1kHz の整数倍ではないため、サウンドドライバがエラーと判断して PCM 再生を止めてしまいます。

48kHz → 44.1kHz の再生で問題が起こらない理由

48kHz → 44.1kHz の再生時は rate = 11.2896MHz, *parent_rate = 12.288MHz となるため、★の if 文を突破して fd->approximation の呼び出しに到達します。Rockchip の Fractional divider の場合、この関数ポインタは rockchip_fractional_approximation() 関数を指しています。

この関数は変わった処理で、ある条件を満たすと、親のクロックを使うのを諦めて、親の親のクロックを使う処理になっています。

Rockchip の Fractional Divider ドライバ(一部)

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ブロックだけで解決できないとき、親クロックに対して再帰呼び出しを行い、親の設定を変更しようとする仕組みになっています。

良くできている素晴らしい仕組みだとは思うのですが…、関数ポインタを使って高度に抽象化されているため、コードを見てもどの関数が呼ばれるのか、もう全く全然わかりません。動作もかなり追いづらいし、デバッグが辛いです……。

[編集者: すずき]
[更新: 2019年 1月 5日 23:30]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

git プロトコルの社内プロキシ越え

Yocto を使ったプロジェクトをビルドする際に、Git プロトコルを使わないとアクセスできないリポジトリがあります。

Git プロトコル(git:// から始まる URL のリポジトリ)は無害なんですけど、大抵の社内プロキシを越えられなくて苦労するので、越え方をメモしておきます。

まず Git のプロキシ設定を行います。この例では git-proxy というコマンドを使ってくれと指示しています。

Git 側の設定

git config --global --add core.gitProxy git-proxy

そんなコマンドはないので、自分で作ります。パスの通った場所、例えば ~/bin/git-proxy のようなファイルを作成して、下記のシェルスクリプトを書いておきます。

自作 Git プロキシコマンド

#!/bin/sh

exec socat STDIO PROXY:192.168.x.x:$1:$2,proxyport=8080

もちろん別途 socat コマンドのインストールが必要です。Debian なら apt-get install socat でインストールできます。

最初は netcat でやってみたんですがダメでした。何でだろ?

[編集者: すずき]
[更新: 2019年 1月 6日 20:12]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2019年 1月 11日 -
      2019年 1月 2日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 1/20 00:16

カレンダー

<2019>
<<<01>>>
--12345
6789101112
13141516171819
20212223242526
2728293031--

最近のコメント 20件

  • link 18年12月11日
    すずき 「確認いただいてありがとうございます。直っ...」
    (更新:12/27 00:22)
  • link 18年12月11日
    T4 「再現しませんね\n\n確かに、過去にそう...」
    (更新:12/25 12:45)
  • link 18年12月11日
    すずき 「失礼しました。Rock64 の方は、\n...」
    (更新:12/22 02:10)
  • link 18年12月11日
    T4 「私は、Tinker Board を持って...」
    (更新:12/21 10:14)
  • link 18年12月11日
    すずき 「> 但し、これもう一年以上前の話で...」
    (更新:12/19 11:54)
  • link 18年12月11日
    T4 「> Rockchip の U-bo...」
    (更新:12/18 13:31)
  • link 18年11月28日
    すずき 「Linux に contribute す...」
    (更新:12/10 12:33)
  • link 18年11月28日
    T4 「やっぱり貴方でしたか、ご苦労さまでした。...」
    (更新:12/05 09:20)
  • link 18年11月28日
    すずき 「RK3228 じゃなくて RK3288 ...」
    (更新:12/05 02:19)
  • link 18年11月28日
    すずき 「ありがとうございます。Linux のコミ...」
    (更新:12/05 02:04)
  • link 18年12月01日
    すずき 「私も最初、HDD, SSD は使いまわそ...」
    (更新:12/04 12:49)
  • link 18年11月28日
    T4 「まずは、おめでとうございます。\n\nい...」
    (更新:12/04 10:00)
  • link 18年12月01日
    hdk 「ウチもASUSのマザーボード(Micro...」
    (更新:12/03 22:15)
  • link 18年11月14日
    すずき 「そうなんです。Debian 便利です。\...」
    (更新:11/27 22:22)
  • link 18年11月14日
    よしだあ 「libopencv-dev とな&hel...」
    (更新:11/27 00:46)
  • link 18年11月15日
    すずき 「なるほど、Windows 10 と古い ...」
    (更新:11/17 22:47)
  • link 18年11月15日
    hdk 「あっ、拒否されるというのは昔のWindo...」
    (更新:11/17 21:07)
  • link 18年11月15日
    すずき 「hdk さん\n\n色は自動で付けている...」
    (更新:11/17 13:15)
  • link 18年11月11日
    すずき 「T4 さん\n\nクロック周りなんですね...」
    (更新:11/17 13:06)
  • link 18年11月11日
    T4 「● I2S1が 全く動かない\nなぜか ...」
    (更新:11/17 09:44)

最近の記事 3件

link もっとみる
  • link 19年01月18日
    すずき 「[Cocos2d-x 再び] 以前 Cocos2d-x をビルドし...」
    (更新:01/20 00:16)
  • link 19年01月14日
    すずき 「[家の PC 性能表、更新] 昔(2017年 5月 2日の日記参照...」
    (更新:01/14 02:08)
  • link 19年01月13日
    すずき 「[ROCK64 と Tinker Board の U-Boot] ...」
    (更新:01/13 21:44)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報