NuDCLその2 [Mac用USBデバイス工作]
昨日からMacOS XでFireWire(IEEE1394)のアイソクロナス転送を効率よく行うためのI/O Kitフレームワークの機能であるNuDCLのおさらいを始めた。古いDCLとの違いをまとめて、最終的に以前作ったIIDCカメラドライバをNuDCLを使ったものに置き換えたい。
NuDCLでも古いDCLのIOFireWireLibDCLCommandPoolRefと同じ働きをするIOFireWireLibNuDCLPoolRefというのがある。これを使ってDCLコマンド列を作る。
コマンドプール自体の作り方は
古いDCLでは
NuDCLは
NuDCLでは
最後の引数でデータを受け取るバッファを指定する。IOVirtualRangeというのはIOTypes.hで定義されたI/O Kitでの汎用の型
そのひとつ前のnumBuffers引数は、どうやらIOVirtualRangeを配列にできるらしい。配列にするとnumBuffers個のパケットをひとつのNuDCLで受け取れるのかもしれない。サンプルコードでは1が指定されているのでよくわからない。これは実験してみるしかない。
headerBytes引数はパケットのヘッダのバイト数を指定する。0、4、8が指定できるらしい。また、saveBag引数はCore Foundationの集合クラスで、Updateに使う。使い方はあとからでてくる。
これは例えば
2.2 コマンドプールを作る
コマンド列を作るための専用のクラスがコマンドプールである。NuDCLでも古いDCLのIOFireWireLibDCLCommandPoolRefと同じ働きをするIOFireWireLibNuDCLPoolRefというのがある。これを使ってDCLコマンド列を作る。
コマンドプール自体の作り方は
#ifdef kAVS_Use_NuDCL_UniversalReceiver nuDCLPool = (*nodeNubInterface)->CreateNuDCLPool( nodeNubInterface, 0, CFUUIDGetUUIDBytes(kIOFireWireNuDCLPoolInterfaceID)); #else dclCommandPool = (*nodeNubInterface)->CreateDCLCommandPool( nodeNubInterface, dclCommandPoolSize, CFUUIDGetUUIDBytes(kIOFireWireDCLCommandPoolInterfaceID)); #endifのようになっている。ここでnodeNubInterfaceはローカルのノード(Mac自身)をあらわすIOFireWireLibNubRefである。2番目の引数はDCLコマンド列の最終的なサイズをバイト単位で渡す。古いDCLでは十分な数字を渡さないと最終的にDCLコマンド列が作られなくなるが、NuDCLの場合は0を渡すことができるらしい。つまり前もってわからなくてもよい、ということ。これは楽でいい。
2.3 DCLコマンド本体
プールを使ってDCLコマンドをひとつひとつ作っていく。DCLコマンド自体は構造体でリンクトリストになっている。古いDCLでは
typedef struct DCLCommandStruct { struct DCLCommandStruct * pNextDCLCommand;// Next DCL command. UInt32 compilerData; // Data for use by DCL compiler. UInt32 opcode; // DCL opcode. UInt32 operands[1]; // DCL operands (size varies) } DCLCommand;のように単なる構造体になっている。
NuDCLは
typedef struct __NuDCL * NuDCLRef ;となっていて、Core Foundationと同じようなopaque構造体、つまり中身のわからない構造体になっている。この構造体を操作するにはcore Foundationの流儀と同じように専用の関数を使ってやることになる。
2.4 パケットひとつ分のデータを受け取るDCLコマンドを生成
DCLでデータを受け取るときは、パケットひとつひとつに対応するDCLコマンドを生成する必要があるのは同じ。古いDCLではDCLCommand* (*AllocateReceivePacketStartDCL)(IOFireWireLibDCLCommandPoolRef self, DCLCommand* inDCL, void* inBuffer, IOByteCount inSize);だった。引数の2番目にひとつ前のDCLコマンド、3番目に転送されたデータを保存するメモリアドレス、4番目にデータのサイズを渡すと、パケットひとつ分を受け取るDCLが生成される。
NuDCLでは
NuDCLReceivePacketRef (*AllocateReceivePacket)(IOFireWireLibNuDCLPoolRef self, CFMutableSetRef saveBag, UInt8 headerBytes, UInt32 numBuffers, IOVirtualRange* buffers);となっている。
最後の引数でデータを受け取るバッファを指定する。IOVirtualRangeというのはIOTypes.hで定義されたI/O Kitでの汎用の型
struct IOVirtualRange { IOVirtualAddress address; IOByteCount length; };になっている。
そのひとつ前のnumBuffers引数は、どうやらIOVirtualRangeを配列にできるらしい。配列にするとnumBuffers個のパケットをひとつのNuDCLで受け取れるのかもしれない。サンプルコードでは1が指定されているのでよくわからない。これは実験してみるしかない。
headerBytes引数はパケットのヘッダのバイト数を指定する。0、4、8が指定できるらしい。また、saveBag引数はCore Foundationの集合クラスで、Updateに使う。使い方はあとからでてくる。
これは例えば
thisDCL = (*nuDCLPool)->AllocateReceivePacket(nuDCLPool, pSegUpdateBags[seg], 4, 1, &range);のように使う。
2010-06-28 21:16
nice!(0)
コメント(0)
トラックバック(0)
コメント 0