« 特殊電子回路ではアルバイトを募集します | トップページ | PCI ExpressのPIOリードの謎 »

2013.04.09

MITOUJTAG Proの遠隔操作

MITOUJTAG Proの特徴は、JTAGスクリプトといって、C++言語を使ってバウンダリスキャンのやりかたを記述できるところにあります。

この機能を拡張して、ユーザが作ったプログラムにDLLを組み込むだけで、MITOUJTAGを介して端子の遠隔操作ができるようにしようと思っています。

この計画は2年ほど前に始めて作りかけの途中だったのですが、この2~3日で再び進めています。だいぶん安定して動くようになってきました。

まず最初はSpartan-6で簡単に試してみます。

最初にSpartan-6を認識したところの画面をご覧ください。

Mitoujtag_remote_sp6_2 

ここで右上にあるAdvanced JTAG Function Generatorの「待ちうけ」と書かれたボタンを押すと、外部のプログラムから接続を待ちうけるようになります。

作ったプログラムはこんな感じ。とても簡単です。

#include "sp6.h"

#define AJFG_CLI_API extern "C" __declspec(dllimport)
AJFG_CLI_API int AJFGInitialize(const char *pin_file);

int main(int argc,char *argv[])
{
	int errcode = AJFGInitialize("sp6.pin");  // ピン定義ファイルを指定
    if(errcode == ERR_CANNOTCONNECT)
    {
        printf("MITOUJTAGサーバに接続できませんでした\n");
        return -1;
	}
    if(errcode < 0)
    {
        printf("MITOUJTAGサーバに接続中にエラーが発生しました code=%d\n",errcode);
        return -1;
	}

	j_bypass();
	j_sample();j_extest(); // AJFGで端子を操作するにはこの行を有効にしてください
	for(int i=0;i<100;i++)
	{
		LED <= i;
	}

	return 0;
}

そして、メインのプログラムとは別にsp6.pinというファイルを作っておきます。LEDと、SWという名前の信号が、どのピンにつながっているかを指定するためのファイルです。

LED A7 B8 A8 B9 A9 C9 C11 F13 
SW  D6

次にビルドします。今はBorland C++でしかコンパイルできませんが、今日の夜にはVisual C++やMinGWにも対応しているでしょう。

bcc32 sp6.cpp AjfgClient.lib

出来上がったsp6.exeを実行すると、ボード上のLEDがチカチカ・・と光るのが見えます。

Sp6_remote

ユーザプログラムが終わったときの状態は、こんな感じです。

Mitoujtag_remote_sp6_end

この「待ちうけ」状態は、「停止」を押すまで繰り返し使えますので、MITOUJTAGには一切手を触れずにsp6.exeを何度も何度も起動できます。つまり、MITOUJTAGは常駐型のJTAGプログラムになって、プロセス間通信の要領でユーザプログラムからの指令を待つようにできるというわけです。

LEDチカチカだけではなく、結構複雑なこともできます。例えば、基板の実装検査なんかにバウンダリスキャンは最適です。

Mitoujtag_remote1

次のプログラムは、究極のRX62Nボード上のSDRAMの端子をJTAGバウンダリスキャンで操作して、SDRAMの動作テストを行うものです。SDRAMはJTAGに対応していませんが、RX62NがJTAGに対応しているので、バウンダリスキャンで操作して間接的に読み書きして検査するというものです。

// バウンダリスキャンでSDRAMの読み出し

#include "jtagscr.h" // JTAGスクリプト
#include "pindef.h"  // ピン定義(ユーザ定義)

#define AJFG_CLI_API extern "C" __declspec(dllimport)
AJFG_CLI_API int AJFGInitialize(const char *pin_file);

unsigned long sd_cmd(int ba,int addr,int ras,int cas,int wen,int cs)
{
	SD_A   = addr; SD_BA  = ba;
	SD_RAS = ras; SD_CAS = cas; SD_WEN = wen; SD_CS = cs;
	SD_CLK <= "0"; SD_CLK <= "1"; // クロックトグル
	return SD_D;
}

int main(int argc,char *argv[])
{
    if(AJFGInitialize("sample.pin") < 0) // ピン定義ファイルを指定
    {
        printf("MITOUJTAGサーバに接続できませんでした\n");
        Sleep(1000);
        return -1;
    }

	j_bypass();j_sample();j_extest();
	SD_D   = "Z"; SD_CKE <= "1"; // 初期設定
	sd_cmd(0,0,1,1,1,1); // インアクティブ
	sd_cmd(0,0x400,0,1,0,0); // プリチャージ
	for(int i=0;i<10;i++) {
		sd_cmd(0,    0,1,1,1,0); // NOP
	}
	sd_cmd(0,0x400,0,1,0,0); // プリチャージ
	for(int i=0;i<10;i++) {
		sd_cmd(0,    0,1,1,1,0); // NOP
	}
	// モードレジスタセット
	sd_cmd(0, 0x23,0,0,0,0); // CL=2,Burst=8
	for(int i=0;i<10;i++) {
		sd_cmd(0,    0,1,1,1,0); // NOP
	}
	sd_cmd(0,    0,0,1,1,0); // ROWアドレスセット
	sd_cmd(0,    0,1,1,1,0); // NOP
	SD_D <= 0x12345678; sd_cmd(0,0,1,0,0,0); // ライト
	SD_D <= 0x11111111; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x22222222; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x33333333; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x13579bdf; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0xdeadbeef; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x98765432; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x31323123; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x2345aaaa; sd_cmd(0,0x408,1,0,0,0); // ライト
	SD_D <= 0x30303030; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0xffffffff; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x00000000; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x5a5a5a5a; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0xa5a5a5a5; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x69966996; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= 0x96699669; sd_cmd(0,0,1,1,1,0); // NOP
	SD_D <= "Z";
	sd_cmd(0,    0,1,1,1,0); // NOP
	sd_cmd(0,    0,1,1,1,0); // NOP
	sd_cmd(0,    0,1,1,1,0); // NOP
	sd_cmd(0,    0,1,1,1,0); // NOP

	sd_cmd(0,    0,0,1,1,0); // ROWアドレスセット
	sd_cmd(0,    0,1,1,1,0); // NOP
	sd_cmd(0,    0,1,0,1,0); // リード
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,0x408,1,0,1,0)); // リード・プリチャージ
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("%08x ",sd_cmd(0,    0,1,1,1,0)); // NOP
	printf("\n");
	SD_CKE <= "0";

	for(int i=0;i<1000;i++)
	{
		P84_BUZZ <= i & 1;
	}

	return 0;
}

これで、MITOUJTAGは、VisualStudioだろうが、C#だろうが、複雑なネットワークが絡んでくるシステムだろうが、ファンクションテスタだろうが何からでもつなぐことができるようになるわけです。この追加機能は今夜あたりにはリリースしたいと思います。

|

« 特殊電子回路ではアルバイトを募集します | トップページ | PCI ExpressのPIOリードの謎 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« 特殊電子回路ではアルバイトを募集します | トップページ | PCI ExpressのPIOリードの謎 »