MacでFTDI BitBang AVR-Writerを使う

久しぶりにMacでAVRの開発をしようとしたら環境構築で手間取ったので、今回はちゃんと記録しようと思いました。

ハードウェア

以下のページを参考にして秋月電子通商のUSBシリアル変換モジュール(AE-UM232R)をAVRライタとして使います。

photo

ソフトウェア

必要なドライバやツールはHomebrewのFormulaにしました。

上記2ファイルの/usr/local/Library/Formulaに配置し、以下の通りインストールすればOKです。

$ brew install avrdude --with-serjtag

$ brew list d2xx
/usr/local/Cellar/d2xx/1.0.4/include/ (2 files)
/usr/local/Cellar/d2xx/1.0.4/lib/libftd2xx.1.0.4.dylib
/usr/local/Cellar/d2xx/1.0.4/lib/libftd2xx.dylib

$ brew list avrdude
/usr/local/Cellar/avrdude/5.10/bin/avrdude
/usr/local/Cellar/avrdude/5.10/etc/avrdude.conf
/usr/local/Cellar/avrdude/5.10/share/man/man1/avrdude.1

動作確認

$ avrdude -c diecimila -p m88p -P ft0 -B 4800
avrdude: BitBang OK 
avrdude: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude: drain OK 

 ft245r:  bitclk 4800 -> ft baud 2400
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e930f

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

[メモ] Homebrewのfork

自分用のローカルパッチをgithub上に置いておきたい。

  • githubでmxcl/homebrewをforkする。
  • cd `brew --prefix`
  • git remote add myfork git@github.com:atty303/homebrew.git
  • 色々作業 (git add ...; git commit ...)
  • git push mywork
  • 本家の更新は普通に brew update で。

こんな感じでいいのかな。

KVO(Key-Value Observing, キー値監視) を行う … その1

どうもお久しぶりです。もともとマトモなアウトプットは無かったこのブログですが、そのマトモでないアウトプットも全部 Twitter に吐き出されているため、ホントに更新していませんでした。しかし、なんか急に書きたくなったので、脈絡もなく更新します。

7月あたりにふと作りたいiOSアプリを思い付いたので、Developer Program 契約3年目にして初のアプリを作り始めました。そして KVO を使おうとして「この API イケてねぇぞ! どうなってんだよ Apple さんよぉ……」と怒り狂い Web を散策した結果、良いエントリがあったので適当に翻訳しました。

Mike Ash 氏の Key-Value Observing Done Right というエントリで、2008年10月と少々古いですが、よくまとまっています。ではどうぞ。

キー値監視を行う

Cocoaのキー値監視機構は非常に強力で便利です。しかし残念なことに、そのAPIは本当にひどく、いくつかの点で本質的に壊れています。それがどのように壊れているのか、そしてより良くする方法を論じます。

何が壊れているのか

KVO API には大きく 3 つの問題があり、すべては複数レベルの階層構造を持つクラスへオブザーバーを登録することに関連しています。これはとても重要で、なぜなら NSObject (が実装している-bind:toObject:withKeyPath:options:) が常に監視対象になるからです。[?]*1

  1. -addObserver:forKeyPath:options:context:は起動するセレクタを変更することができません。


    NSNotificationCenter などの同様の API を見たとき、それは常に、指定されたイベントが発生したときに呼び出されるセレクタを渡して、オブザーバーを登録していることがわかります。これはあなた自身のメソッドにメッセージを送信するので、物事をスーパークラスから分離するのが非常に容易になります。KVO では、-observeValueForKeyPath:ofObject:change:context:をオーバーライドし、自分自身でメッセージを処理するかスーパークラスの実装を呼び出します。メッセージを処理するか上位のチェインに渡すかどうかの決定は、スーパークラスが同じオブジェクトとキーパスを登録しているかもしれないという事実によって複雑になります。

  2. コンテキストポインタは無意味です。


    これは、#1の結果です。起動するカスタムメソッドを指定することはできず、キーパスまたはオブジェクトからスーパークラスが通知に興味があるのか調べることもできないので、通知があなたのためのものなのかスーパークラスのためのものなのかを調べる手段が他に必要になります。コンテキストポインタがこれを行う方法です。スーパークラスからは使用することのできない一意ポインタを作成し、addObserver:...に渡さなければなりません。そして-observeValueForKeyPath:...の実装では、コンテキストポインタと先の一意ポインタを比較して確認しなければなりません。その結果、実際にコンテキストを保持するためのポインタをコンテキストポインタとして使用することはできません。

  3. -removeObserver:forKeyPath:は十分な引数を取っていません。


    このメソッドは、コンテキストポインタを取っていません。これは、スーパークラスと同じオブジェクト/キーパスの組み合わせで登録し、それが異なる寿命である場合に、あなたのオブザーバーのみを無効にする方法がないことを意味します。このメソッドを呼び出すと、あなたのものを無効にするか、スーパークラスのものを無効にするか、またはその両方を無効にします。

このような強力なツールが壊れているのはとても残念です。特に新しい API では伝統的な NSNotification とデリゲートに代わって、単に KVO をサポートするようになっている傾向が Apple にはあります。 完全な例は NSOperation で、NSOperation が完了したことの通知を得る唯一の方法は、KVO を使用してisFinishedプロパティを監視することです。

さて、私たちに出来ることはなんでしょうか?
私は役に立たない文句を言いたくないので、この問題を解決するためにクラスを書きました。私の公開 svn リポジトリから取得することができます:

svn co http://www.mikeash.com/svn/MAKVONotificationCenter/

また、上記のリンクをクリックすることで閲覧することができます。

それは、どのような仕組みでしょうか?それは、一意であることが保証できるポインタ、つまり self ポインタの利点を活用します。通知の対象となるオブジェクトを登録する代わりに、独自のヘルパーオブジェクトを各通知毎に作成して登録します。ヘルパーは通知を受信し、元のオブザーバーにそれを転送します。ヘルパーは各監視毎に固有のオブジェクトなので、単純なインスタンス変数として監視に関するメタデータを保持することができ、一意ポインタを必要とするコンテキストポインタに依存する必要がありません。ヘルパーは何もしませんが KVO 通知を待ち受け、オブジェクトの存続期間のあいだ監視は続きます。そして、そのスーパークラス、NSObject は何も監視しないことだけでなく、オブジェクトの存続期間だけ監視すると仮定することができます。[?]*2

MAKVONotificationCenterは、上記の3つのすべての欠陥をバイパスします:

  1. -addObserver:...メソッドで、監視対象のキーパスが更新されたときに起動されるセレクタを変更できます。スーパークラスは異なるセレクタを利用しているでしょうから、問題は解決されました。(Cocoaスーパークラス達が直接監視をするのに対して、 MAKVONotificationCenter はヘルパーを介して監視するので、確実に干渉しません) [?] *3

  2. オブザーバーのメソッドに渡されるuserInfoパラメータが提供されます。これは、監視についての必要な情報を含む任意のオブジェクトを指定できます。

  3. -removeObserver:...メソッドは、ターゲットとキーパスだけでなく、セレクターも取ります。これにより、サブクラスとスーパークラスの両方が同じオブジェクトの同じキーパスを登録している場合に、それぞれ独自のセレクタを指定することによって、他に影響を与えずに登録を解除することができます。

また、いくつかの興味深い機能があります。

+defaultCenterは、アクセス毎のロックを必要としないスレッドセーフなシングルトンを作成するために、 ロック不要の単純なアトミック呼び出しを使用しています。これは、事前の初期化、またはシングルトンへのアクセス毎にロックおよびアンロックを行うことなく、安全なシングルトンを実現する素敵なテクニックです。

少しよりよいAPIは、NSObject のカテゴリとして公開されています。これは、明示的にMAKVONotificationCenterのシングルトンをアクセスするよりも優れています。極端なケースでは、NSObjectのカテゴリ拡張だけを残して、MAKVONotificationCenterをヘッダから完全に取り除くことができました。

このコードは、基本的にはテストされていません。Tester.mの幾つかのテストコードが、私が行なった全てです。あなたは自分で試してみるまで、それを信用しないでください。実際のコードは約150行で多くのことは行なっていませんが、どのような場合でも「買い主の危険負担」です。

あなたのプロジェクトでこれを使用する場合は、適切なクレジットが成されている限りにおいて、それが可能です。また欠陥を発見した場合、パッチは大歓迎です。

そして、この MAKVONotificationCenter をベースにした GTMNSObject+KeyValueObserving.[hm] が Google Toolbox for Mac に含まれています。なので、僕は GTM のほうを使ってます。

で、これはこれで GC-enabled な環境で問題があるっぽい?(まぁiOSでは関係ありませんが)とか、せっかくだから Blocks/GCD 使いたいよね! とかまだトピックはあるので、気が向いたら「その2」を書きます。

*1:よくわからなかったのですが、要は全てのクラスはNSObjectを継承しているから大変だよ、って事でしょう。

*2:英語スキル低いので、よく読解できませんでした

*3:ここもよくわかりません

はじめての録画

基本的にfoltiaで満足してるから、tsniffは作ったものの使わずに1年ぐらい放置してたんですが、CCSと聞いて原始的にcronで録画してみました。その結果、パケットを取りこぼしまくっているみたいで5秒おきぐらいにブロックノイズでまくり、まったくのダメダメでした。tsniff使えね〜(笑)

ま、この1年のあいだに選択肢も色々と増え、モノによってはV4L-DVBのドライバとかもあるみたいなので、チューナー抜きは引退かな(まったく働いてないけど)。

オラタン移植

Xbox 360:電脳戦機バーチャロン オラトリオ・タングラム公式ウェブサイト

とうとうXbox360を買うときが来た、のかもしれない。ただ、5.2は好きじゃなくて、5.4は大好き、5.66は殆どやったことがない、という感じでも楽しめるのかな? あとで5.4→5.66の変更点を調べてみるかー。

Dxtoryで録画した動画にゲームパッドの操作を表示する

ようなソフトが無いものかと思ったけどまったく見付からないので、急遽 Visual Studio 2008 Expressをインストールして作った。ファイルをセーブする度に2秒ぐらい固まる、デバッグを終了するのに10秒ぐらい掛かるとストレスフルだった。


InputLogger

  • Dxtory の録画ホットキーと同じホットキーで記録開始。
  • DirectInput でポーリングして、読み取った入力情報をタイムスタンプとともにファイルに記録するだけ。

InputVisualizer

DirectShowSource("foo.avi")
ConvertToRGB32()
InputVisualizer("foo.avi.inputlog")

http://sites.google.com/site/atty303/downloads/InputLogger_20090211.zip

自分の作る動画専用の使い捨てコードなので超適当ですが、一応ソースとバイナリ。
InputLoggerは汎用化できるけど、Visualizerは難しい。描画をプラガブルにするにはどうすればいいんだろう。

Ubuntu 8.10 (x86_64)のMP4Box

Bug #273075 “MP4Box buffer overflow detected” : Bugs : gpac package : Ubuntu

これにクリーンヒットした。直るまで mpeg4ip-server パッケージの mp4creator で代用する。

mp4creator -extract=1 encoded_with_neroaacenc.aac tmp.aac
mp4creator -create=source.264 -rate=23.976025 dest.mp4
mp4creator -create=tmp.aac dest.mp4

とりあえず問題ないみたい。

17:00から移行作業を開始して、なんとか 1:30 の RIDE BACK に間に合った。foltiaの移行しかやってないので、残りはまた明日に。

ML115その後

1日電源抜いて放置していたら、POSTが走ってビープ音が鳴るようになった。「ピピピピ、ピー、ピー、ピー、ピー」って感じの音なんだけど、なんのエラーなのかわからない。マニュアルにはエラーコードしか書いてないし。
その後、色々触っていたら、またビープ音すら鳴らなくなった。
同じような症状で1週間放置していたら治ったという人も居るようなので、僕もしらばく放置してみよう。もし復活したら、VMWare ESXi Serverでもいれて遊ぶことにする。

ESXi Serverは、PCIバイスのPass-Throughっていうのかな、特定の仮想マシンに直接PCIバイスを割り当てることができれば最高なんだけど、たぶん出来ないよなぁ。その方面だとXenになるのかな。