Cosmo-ZをMATLABで操作する方法

MATLABにはWindowsのDLLを実行する機能があり、Cosmo-Zをリモート操作するAPIはDLLで提供されているので、これらを組み合わせることでMATLABからCosmo-Zを操作することができるようになります。

 

基本のサンプルプログラム

以下のファイルを作成し、libcsz.dllと、cosmoz.hとともにMATLABのサンプルプログラムと同じディレクトリにコピーして実行してください。

% MATLABのDLL読み込み機能をオープンする
loadlibrary('libcsz.dll','cosmoz.h');

% Cosmo-ZにTCP/IPで接続するため、csz_openを呼び出す。
% 第3引数のINTERFACE_TCPIPがうまく行かない場合は、2を指定する
% 第4引数はホスト名
result = calllib('libcsz', 'csz_open', INTERFACE_TCPIP, 'cszmini');
if ~result
    disp('エラー:Cosmo-Zへの接続に失敗しました。');
    unloadlibrary('libcsz');
    return;
end

% FPGAバージョン情報を調べる
version = calllib('libcsz', 'csz_fpga_version');
fprintf("FPGA Version=%08x\n",version);

% Cosmo-Zの温度を読み取る
tempe = calllib('libcsz', 'csz_xadc_tempe');
fprintf("Currnet temperature=%f\n",tempe);

% TCP/IPの接続を閉じる
result = calllib('libcsz', 'csz_close');

% MATLABのDLL読み込み機能を閉じる
unloadlibrary('libcsz');

 

実行結果の例

以下のようにFPGAのバージョンと温度が表示されます。

FPGA Version=26040803
Currnet temperature=63.366510

解説

loadlibraryでDLLをオープンし、calllibで各種のDLL関数を呼び出しています。

calllibで呼び出される関数の引数の型や戻り値の型はcosmoz.hを読み込むことでMATLABによって解釈されます。

 

戻り値が構造体である関数を呼び出す場合

csz_capture_executeのように構造体を返す関数の場合、MATLABでは構造体を受け取ることができないため、libstructを使って受け取ります。

CAPTURE_INFOという構造体はC言語のヘッダファイルで

typedef struct CAPTURE_INFO {
CAPTURE_RESULT result; //!< キャプチャ実行結果
    uint32_t chmask;       //!< キャプチャしたチャネル
    int chcount;           //!< キャプチャしたチャネル数
    int length;            //!< キャプチャ長
    ・・・
    ・・・
uint32_t start_addr;   //!< イベントキャプチャのデータが入っている先頭アドレス
} CAPTURE_INFO;

のように定義されています。

csz_capture_executeのプロトタイプはヘッダファイルで

CSZAPI CAPTURE_INFO CSZCALL
csz_capture_execute(uint32_t chmask,int length,CAPTURE_TRIGGER type,int maxseq);

のように宣言されています。

MATLABで構造体を作るにはstruct()かint32(0)を使い、変数を作ったあと、libstructで型付けし、calllibの最終引数にして指定して実行します。

info = struct();
libstruct('CAPTURE_INFO', info);
result = calllib('libcsz', 'csz_capture_execute', 0xff, DATASIZE
    ,CAPTRIG_AUTO ,1, info);

 

データキャプチャのサンプルプログラム

下記のページにあるC言語で書かれたリモート操作のサンプルプログラムをMATLABで書き換えたものを示します。

https://cosmoz.jp/tutorial/cremote.html

function main(hostname)
    % 引数のチェック(C言語の argc < 2 の代わり)
    if nargin < 1
        disp('引数に hostname を指定してください。例: main(''192.168.1.10'')');
        return;
    end
    % INTERFACE_TCPIP  = 2; %MATLABがh内のenumを解釈できない場合
    % FALSE            = 0; %MATLABがh内のenumを解釈できない場合
    % CAPTRIG_AUTO     = 0; %MATLABがh内のenumを解釈できない場合
    % CAPRESULT_SUCCESS = 0; %MATLABがh内のenumを解釈できない場合
    % DATASIZE         = 10; %MATLABがh内のenumを解釈できない場合

    % 1. ライブラリのロード
    if ~libisloaded('cosmoz')
        loadlibrary('cosmoz.dll', 'cosmoz.h');
    end

    % 2. ドライバーのオープン
    if calllib('cosmoz', 'csz_open', INTERFACE_TCPIP, hostname) == FALSE
        disp('Cosmoz driver open failed.');
        return;
    end

    % 3. ADC周波数の設定とウェイト
    calllib('cosmoz', 'csz_adc_freq', 80);
    pause(0.1); % 100000マイクロ秒 = 0.1秒(usleepの代わり)

    % 4. キャプチャ実行受け皿の作成と実行
    % info = csz_capture_execute(...) の戻り値(構造体の実体)を受ける処理
    % ※ 構造体 CAPTURE_INFO の定義に合わせたダミー構造体を作成して libstruct に渡します
    % ※ ここでは、仮にメンバ変数に「result」という整数型があると仮定しています
    blankInfo.result = int32(0); 
    infoStruct = libstruct('CAPTURE_INFO', blankInfo);

    % 5. 構造体を実体で返す関数のため、第3引数に受け皿(infoStruct)を渡す
    calllib('cosmoz', 'csz_capture_execute', int32(255), int32(DATASIZE), CAPTRIG_AUTO, 1, infoStruct);

    % 6. キャプチャ結果の確認
    if infoStruct.result ~= CAPRESULT_SUCCESS
        disp('キャプチャエラー');
        calllib('cosmoz', 'csz_close');
        return;
    end

    % 7. データコピー用の配列(バッファ)を用意
    % C++の new uint16_t[DATASIZE] の代わり。MATLABでは uint16型 で初期化します。
    data1 = zeros(1, DATASIZE, 'uint16');
    data2 = zeros(1, DATASIZE, 'uint16');
    data3 = zeros(1, DATASIZE, 'uint16');
    data4 = zeros(1, DATASIZE, 'uint16');

    % 8. データのコピー
    % [戻り値, 変更された引数1, 変更された引数2...] という形式で、書き換えられた配列を受け取ります
    [~, ~, data1] = calllib('cosmoz', 'csz_capture_datacopy', infoStruct, 1, data1);
    [~, ~, data2] = calllib('cosmoz', 'csz_capture_datacopy', infoStruct, 2, data2);
    [~, ~, data3] = calllib('cosmoz', 'csz_capture_datacopy', infoStruct, 3, data3);
    [~, ~, data4] = calllib('cosmoz', 'csz_capture_datacopy', infoStruct, 4, data4);

    % 9. コンソール表示
    fprintf('time[ns]\tCH1\tCH2\tCH3\tCH4\n');
    for i = 1:DATASIZE
        % MATLABの配列は1オリジン(1番目からスタート)
        % ループ変数 `i` を計算用に0始まりにするため `(i-1)` としています
        time_ns = (i - 1) * 12.5;
        fprintf('%0.1f\t%d\t%d\t%d\t%d\n', time_ns, data1(i), data2(i), data3(i), data4(i));
    end

    % 10. 終了処理(MATLABはdelete[]の呼び出しは不要。自動でメモリ解放されます)
    calllib('cosmoz', 'csz_close');
    
    % 必要に応じてライブラリもアンロード
    % unloadlibrary('cosmoz');
end

 

ダウンロード

cosmoz.hとlibcsz.dllは下記のURLから入手してください。

https://cosmoz.jp/files/libcsz.zip