[KEKB Bunch Feedback Group]

株式会社デジテックス研究所社製バンチ振動モニタ18K10用EPICS Device Supportの製作(Japanese)


by とびやま まこと(Makoto Tobiyama)/KEKB ビームモニターグループ

警告
以下の記述に関しては、意図する、しないに関わらず多くの誤り、誤解が含まれていると思われますので、 決して信用してはいけません。これを信じて起きた損害に関しては、当方は一切責任を持ちません。


If you want to contact with the author, please E-mail to makoto.tobiyama@kek.jp.
目次

1.はじめに

18K10は、KEKB、KEKBダンピングリングでバンチ電流、バンチ振動をモニターするモジュールです。 外部から供給されるRF(509MHz)信号に同期して、バンチ電流あるいはバンチ位置信号を高速8bit ADC でサンプルし、FPGA内部ブロックRAMあるいは外部大容量メモリー(DDR2)に記録します。

2.VMEバスレジスタ

18K10ボードのI/Oマップは以下の通りです。
アドレスWrite/Readデータ
313029282726252423222120191817161514131211109876543210
0x*****(***00)00(R/W)BOARD RESET
0x*****(***00)04(R/W)TRIG_ENB
0x*****(***00)08(R/W)MEM_TRIG
0x*****(***00)0C(R/W)MEM_SIZE
0x*****(***00)10(R/W)IRQ_ENB
0x*****(***00)14(R/W)ADCLK_DLY
0x*****(***00)18(R/W)ADC_RST
0x*****(***00)1C(R/W)ADRDPT_RST
0x*****(***00)20(R/W)MEM_CL
0x*****(***00)24(R/W)FPGA_OUT
0x*****(***00)28
0x*****(***00)2C
0x*****(***00)30(R)BOARD_STS
0x*****(***00)34(R)AD_STS
0x*****(***00)38(R)REC_MODE
0x*****(***00)3C(R)HARMONIC
0x*****(***00)40(R)IRQ_NO
0x*****(***00)44(R)IRQ_ID
0x*****(***00)48(R)FPGA_IN
0x*****(***00)4C
0x*****(***00)50(R)DEBUG0
0x*****(***00)54(R)DEBUG1
0x*****(***00)58

0x*****(***00)FC
0x*****(***01)00(R)Data 0 Data 1
Data 2Data 3
0x*****(***01)04(R)Data 4 Data 5
Data 6Data 7
(R)Data n Data n+1
Data n+2Data n+3
0x*****(***01)FC(R)Data 252 Data 253
Data 254Data 255

差動入力時のADCのデータフォーマットは、
入力電圧ディジタル出力
76543210
100mV11111111
0V 10000000
-100mV00000000

です。
各レジスターの説明は以下の通りです。

3.EPICS環境

本デバイスサポートは、EPICS R314.12.1のVxWORKS(MV5500)用に開発したものです。 BLT(DMA転送)をサポートします。VxWorksのバージョンは6.8.3です。このバージョン からは、通常のabco4上で開発が可能です。

EPICSそのものに対する入門出家入道については専門家に帰依するなり、 コントロールグループのページを参照するなどの自活努力をお願いします。

4.コードの概要(全体)

全体のコードを以下のリンクに示します。
ソースファイル(devVme18k10KM.c)
また、dbdファイルの中身は
device(bo,VME_IO,devBo18k10KM,"V18K10KM")
device(bi,VME_IO,devBi18k10KM,"V18K10KM")
device(mbbiDirect,VME_IO,devMbbi18k10KM,"V18K10KM")
device(waveform,VME_IO,devWf18k10KM,"V18K10KM")
device(longout,VME_IO,devLo18k10KM,"V18K10KM")
device(longin,VME_IO,devLi18k10KM,"V18K10KM")
device(stringout,VME_IO,devSo18k10KM,"V18K10KM")
device(stringin,VME_IO,devSi18k10KM,"V18K10KM")
です。

DMA転送の詳細は、18k11の説明に 書きましたので、ここでは変更部分のみ示します。18K11の場合は、MBLTでしたが、18K10はBLTなので、 以下の様になります。

5.nfsによるデータ保存

waveform全体をchannel accessで持ってくること自体は、EPICS_CA_MAX_ARRAY_BYTESが 十分な大きさに定義してあればできます。但し、networkの混み方にもよりますが、 cagetのdefaultのtimeoutにかからないように、wait timeを適当に設定しないと 読めないことがあります。

実際の使用条件では、データを自動的にdiskにsaveして、あとからアクセスすることがほとんどと 思います。このため

を追加します。

5.1 ファイル保存選択

グローバル変数で
static int saveflag[10];
を定義し、boレコードを使ってこのフラグを制御します。具体的には、boのsignal 5を追加して
  case 5 : /* soft : record data y/n */
    saveflag[cardN] = 0x1 &(pbo->val);
    break;

としておきます。waveformレコード内では、saveflagをみて条件分岐させます。

5.2 システム時間を使ったファイル名自動生成

まず、現時間を格納する変数を定義します。
  struct timespec time_val;
外部からSOで与えたファイルheader (MLHとかMHVとか)に 現時間を日付_月_年_時間_分_秒の形にした物をくっつけ、 拡張子としてADCを付けた名前を作り、global変数のfile_nameに格納します。
  strcpy(file_name[cardN],NULL);
  strcat(file_name[cardN],head[cardN]);
  clock_gettime(CLOCK_REALTIME, &time_val);
  strftime(ttt,buflen,"%d_%b_%Y_%H_%M_%S",localtime(&time_val));
  strcat(file_name[cardN],ttt);
  strcpy(eee,".ADC");
  strcat(file_name[cardN],eee);
  if (debug_flag >5) 
    logMsg("file_name =%s\n",file_name[cardN],0,0,0,0,0);

なお、SIレコードでこのファイル名が読み出せるようにしておきます。

static long init_si_record(pstringin)
struct stringinRecord *pstringin;
{
  return 0;
}

static long read_si(pstringin)
struct stringinRecord      *pstringin;
{
    long status = 0;
    short cardN;
    char tempchar[255];

    cardN = pstringin->inp.value.vmeio.card;
    if (checkLink(cardN) == ERROR)
    {
      logMsg("Error- No 18k10KM for card %d\n",cardN,0,0,0,0,0);
      return(ERROR);
    }
    switch(pstringin->inp.value.vmeio.signal){
    case 0 :
      strcpy(pstringin->val,file_name[cardN]); 
      break;
    }

    return(status);
}

デバイスサポート内だけで、このSIレコードをプロセスさせるのは面倒(というか、 よく分からない)ので、waveformがprocessされたとき、FLNKでSIレコードを プロセスするようにデータベースでしておきます。もしも、sequencerなどで モニターしておけば、SIレコードが更新したタイミングを捕まえて actionすることができます。

5.3 データのNFSによる書き込み

書き込みは、モニターグループで管理しているNAS(Thecus N8900)に、/BORという ディレクトリを作り、NFS許可して行います。このNASには、10GbEアダプタをつけて あり、制御ネットに対してはSFP+ケーブルで10GbE接続されています。IOCは GbE接続ですが、制御側室にあるエッジスイッチから先は全て10GbEです。

手順は以下の様になります。

#define NUM_20M (5120*4096)
#define NUM_40M (5120*8192)
#define NUM_80M (5120*16384)

...

    if (memory_size == 1) 
      {

       m1 = 81920 * 2;
       m2 = NUM_40M; 
       
      }    else if (memory_size == 2)
      {
       m1 = 81920 * 4;
       m2 = NUM_80M;
     
      }
    else
      {

     m1 = 81920;

        m2 = NUM_20M;      }

......


    pwf->nord = m2;
    if (saveflag[cardN]) 
      {

  if (hostAdd( "wrs", "172.19.57.***" ) != OK) {
      logMsg("hostAdd Error!!\n",0,0,0,0,0,0);
          return(-1);        }
          
       taskDelay( sysClkRateGet() /10);
      
        if( nfsMount( "wrs", "/raid0/data/_NAS_NFS_Exports_/BOR","/bor/" ) != OK) {
          logMsg("nfsMount Error!!\n",0,0,0,0,0,0);
          return(-1);
        }
cd( "/bor/current/");
if( ( pwFile = fopen( file_name[cardN], "w" )) == NULL ) {
logMsg("File Open[Write mode] Error!!\n",0,0,0,0,0,0);
return(-1); } if( ( wsize = fwrite(&us_thing[0], 1, m2, pwFile )) != m2) {
logMsg("Unmatch File Write Length!!\n",0,0,0,0,0,0); } fclose(pwFile);
nfsUnmount("/bor/"); hostDelete( "wrs", "172.19.57.***"); }

6.EPICSデータベースサンプル

サンプルファイルは以下を参照してください。 mbbiDirectのsignal=1をI/O Intrに設定し、これのFLINKに waveformレコードを指定、そのFLINKにwaveform(LMEM)を 指定、その後EVENT(calcレコード)をprocessします。また、 subArrayのBUNCHをprocess、FNAME(保存ファイル名)を processします。実際にSuperKEKBで使用するときは、もう少し 変わるかも知れません(FANoutを使って整理するなど)。

7.スタートアップファイルサンプル

/cont/bootp/iocの所には
# Example vxWorks startup file
#Following must be added for many board support packages
</cont/bootp/ioc/kekb_mv5500.cmd
putenv "EPICS_CA_MAX_ARRAY_BYTES=167772160"
# put your startup script below
</users/tobiyama/epics_M6/iocBoot/iocfbppc/st.test2.cmd
kekBootLog
printTime(60)
のように、自分の所のブートファイルを読みに行くように設定します。 なお、EPICS_CA_MAX_ARRAY_BYTESはクライアント側も設定しておかないと 長いwaveformを読む事が出来ません。
1枚の18k10ボードを使用する時のスタートアップファイル(の関係部分)は次のようになります。
dbLoadRecords("db/FB_BCMKM.db","USER=FBB, CHAN=C0")

dev18k10KMConfig(1,0x08000000,0x5,0x90)
dbpf "FBB:MEM4:IRQENB","1" dbpf "FBB:MEM4:TRG_ENB","1" dbpf "FBB:MEM4:FILEHEAD","MLH"

8.データ転送、保存

実際のデータ転送速度を、VMEバスアナライザー(Logic Analyzer)を使って 測定してみました。結果は、以下のlinkをご参照ください。

資料

こう見てみると、VMEのデータ転送がやはり一番遅くボトルネックになって いることが分かります。NASに書き込むより遅いなんてショックです。 もちろん、昔のBORに比べると、遙かに早くはなっているのですが。

9.おわりに

バンチ電流、バンチ振動モニター18K10のバンチ振動モニターモードでの デバイスサポートについて紹介しました。。 nfsの部分は、東日技研の岡崎さんに教えてもらいました。 岡崎さんには、大変お世話になりました。感謝します。
Makoto Tobiyama
28/May/2014

Return to FB Home Page...