NuDCLその4 [Mac用USBデバイス工作]
NuDCLと古いDCLの使い方の違いのおさらいを続けている。思想は同じだけど使い勝手はけっこう違う。NuDCLは古いDCLに較べてずいぶんシンプルに整理されている。とはいってもI/O Kitなので使いこなすのはちょっと難しそうではある。
古いDCLではタイムスタンプをとってくる専用のコマンドがあって
NuDCLではやはり専用のコマンドではなく
基本的には古いDCLもNuDCLも考え方は同じだけど、細部が微妙に違っている。
古いDLCではやはりコールバック関数指定専用のコマンドがある。
ただしこんどはSetDCLCallback関数にRefConを指定する引数がない。それはべつの関数
2.7 タイムスタンプ
FireWireのホストコントローラにはホスト側がパケットを受け取ったとき、そのパケットにタイムスタンプを打つ機能がある。バスサイクルが基準で、実時間になってないので使い勝手は悪いけど、リアルタイム性の必要なアプリ(例えばカメラの画像と他のハードウェアを同期させる)では便利な機能である。古いDCLではタイムスタンプをとってくる専用のコマンドがあって
DCLCommand* (*AllocatePtrTimeStampDCL)(IOFireWireLibDCLCommandPoolRef self, DCLCommand* inDCL, UInt32* inTimeStampPtr);で生成する。これが実行されるときにinTimeStampPtrがさしているメモリ領域にホストコントローラのタイムスタンプの値がコピーされる。ただし、このコマンドはupdateコマンドのあとでないと機能しない。
NuDCLではやはり専用のコマンドではなく
IOReturn (*SetDCLTimeStampPtr)(NuDCLRef dcl, UInt32* timeStampPtr);というプールの関数を使う。引数のdclは任意のコマンドでよく、dclが実行されるとtimeStampPtrの領域にタイムスタンプがコピーされる。
2.8 コールバック
DCLコマンドはスタティックなリンクトリストで、条件判定のようなコマンドはない。従ってループは無限ループしか作れない。条件判定してあるときにはループを脱出する、などと言ったコードはコールバックとしてCの関数を書いてそれを指定する。例えば、ループをしていてデータがいっぱいになったらいったんループを止め、データを退避して次のループを開始する、などという処理はデータがいっぱいになったかどうかをコールバック関数の中で判定し、ループの解除や再開になるようにDCLのリンクトリストを書き換える、というちょっと恐ろしいことをやる。基本的には古いDCLもNuDCLも考え方は同じだけど、細部が微妙に違っている。
古いDLCではやはりコールバック関数指定専用のコマンドがある。
DCLCommand* (*AllocateCallProcDCL)(IOFireWireLibDCLCommandPoolRef self, DCLCommand* inDCL, DCLCallCommandProc* inProc, DCLCallProcDataType inProcData);DCLコマンドのリンクトリストにこのコマンドが現れるとその時点でinProcで指定されたコールバック関数が呼ばれる。inProcDataはコールバック関数への引数として渡されるいわゆるRefConである。DCLCallCommandProcは
typedef void (DCLCallCommandProc)(DCLCommand * command);となっている。これを見るとRefConが渡されていない。実はRefConは直接渡されるのではなく、コールバックコマンドの
typedef struct DCLCallProcStruct { DCLCommand * pNextDCLCommand;// Next DCL command. UInt32 compilerData; // Data for use by DCL compiler. UInt32 opcode; // DCL opcode. DCLCallCommandProc * proc; // Procedure to call. DCLCallProcDataType procData; // Data for use by called procedure. } DCLCallProc;procDataポインタが設定されているので例えば
DCLCallProcStruct *pCallProc = (DCLCallProcStruct*) pDCLCommand; UniversalReceiver *pReceiver = (UniversalReceiver*) pCallProc->procData;のようにして取ってくる必要がある。 一方NuDCLではこれまでと同じように専用のコマンドというのはない。
typedef void (*NuDCLCallback)( void* refcon, NuDCLRef dcl); IOReturn (*SetDCLCallback)( NuDCLRef dcl, NuDCLCallback callback);という関数を使ってコールバック関数を指定する。こっちはちゃんと第1引数にRefConが入っている。
ただしこんどはSetDCLCallback関数にRefConを指定する引数がない。それはべつの関数
void (*SetDCLRefcon)(NuDCLRef dcl, void* refcon);を使って設定する。RefConはひとつのDCLコマンドごとに設定できる。
2010-07-01 22:13
nice!(0)
コメント(0)
トラックバック(0)
コメント 0