SSブログ

NuDCLその2 [Mac用USBデバイス工作]

昨日からMacOS XでFireWire(IEEE1394)のアイソクロナス転送を効率よく行うためのI/O Kitフレームワークの機能であるNuDCLのおさらいを始めた。古いDCLとの違いをまとめて、最終的に以前作ったIIDCカメラドライバをNuDCLを使ったものに置き換えたい。

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);
のように使う。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立06/28献立06/29 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。