Software
この章では制御用のLinuxソフトウェアについて述べます。
開発環境
- CentOS7
- gcc version 4.8.5
HR-TDC用のソースコードのみROOTファイルを作るためにCERN ROOTに依存します。 ROOTがインストールできない環境ではHR-TDCをmake対象から外してください。
ディレクトリ構造
CoreLibはこのソフトウェアり利用される共通のライブラリを提供します。CommonはSDSやFMPの制御など、各ファームウェアで共通の要素を制御するためのプログラムを提供します。そのほか各ファームウェア専用のソースコードはFW名がついたディレクトリ内に存在します。
hul_software.git
├── Makefile
├── CoreLib
├── Common
└── FW directories
ソースファイル
ソースファイルには他のDAQシステムへ移植する際にそのままコピーするべきなライブラリ的なファイルと、同じように動作さえすればどのように書いてもいい物、デバッグ用で移植の必要がない物が存在します。重要な物だけ説明します。
全ての実行体は引数無しで起動するとusageが表示されるようになっています。
CoreLib
- rbcp.hh
- RBCPパケットの構造体です。そのまま移植してください。
- Uncopyable.hh
- 自身のクラスのコピーコンストラクタと代入演算子を禁止するメソッドです。かなり古い実装方法で今はc++の標準機能で同様の事が出来るためそのうちなくします。
- BitDump
- 整数値を渡してbit列を標準出力するためのクラスです。元々はUnpackerの中で使われていたものを移植しました。UDPRBCPの中で使っています。デバッグに便利です。
- Utility
- コンソール上でプログレスバーを表示したり文字を点滅させたりします。移植の必要はないのですがFlashMemoryProgrammerの中で利用しています。
- UDPRBCP
- SiTCPのUDP通信を行うためのクラスで、重要なソースコードです。コンストラクタはIP address、upd portを必要とし、最後の引数は表示モードです。
UDPRBCP.hh
内にRbcpDebugMode
という列挙体で定義されています。
- NoDisp: 通信時に何も表示しません。
- Interactive: 何をしている程度の情報を出力します。
- Debug: 全ての情報を標準出力します。
通常使う際はNoDispでいいでしょう。UDPRBCPはSiTCPの生のUDP通信レベルの機能を制御しています。最低限これがあればHULの制御が可能です。
- FPGAModule
- UDPRBCPを隠蔽してBusControllerレベルの通信機能を提供するクラスです。UDPRBCPを包含するためコンストラクタはUDPRBCPを引数に取ります。BCTを通じて多バイトの読み書きをサポートすることが主な機能です。
int32_t WriteModule(const uint32_t local_address,
const uint32_t write_data,
const int32_t n_cycle = 1);
レジスタを書き込むメソッドです。第1引数はRBCP addressです。4章のレジスタマップ、および後述するRegisterMap.hh
を参照してください。第2引数が書き込むレジスタです。第3引数は書き込みバイト数です。戻り値はUDCPRBCP::DoRBCP
の結果です。この関数は32-bitと64-bitレジスタ用にオーバーロードされています。n_cycle
が取れる範囲はそれぞれ1-4と1-8です。
uint32_t ReadModule(const uint32_t local_address,
const int32_t n_cycle = 1);
レジスタを読み出すためのメソッドです。第1引数はRBCP address。第2引数は多バイト読み出しの回数を設定します。読み出した結果は関数の戻り値に現れます。n_cycle
の値に限らずuint32_t
の型で与えられます。この関数も32-bitと64-bit用にオーバーロードされています。
int32_t WriteModule_nByte(const uint32_t local_address,
const uint32_t* write_data,
const int32_t n_byte);
同一のアドレスに複数バイト書き込むための関数です。この関数では書き込みのたびにアドレスの最下位をインクリメントしません。想定する書き込み先はFIFOです。
int32_t ReadModule_nByte(const uint32_t local_address,
const int32_t n_byte);
同一のアドレスから複数バイト読み出すための関数です。この関数では読み出しのたびにアドレスの最下位をインクリメントしません。想定する読み出し元はFIFOです。読み出したデータはrd_data_
というクラス変数に格納されます。GetDataIterator
でイテレータを取得してアクセスしてください。
- SiTCPController
- SiTCPの予約領域に直接アクセスするための関数です。EraseEEPROMはEEPROMを全消去するための関数です。EEPROMの領域に読み書きする関数は危険なため作っていません。SiTCP Utilityを使うことをお勧めします。
void ResetSiTCP(const std::string ip)
SiTCPをソフトリセットします。
void WriteSiTCP(const std::string ip,
const uint32_t addr_ofs,
const uint32_t reg)
SiTCP予約領域アドレスに1-byteのレジスタを書き込むための関数です。SiTCPの予約領域は0xffffff00から始まっており、そこからのオフセットをaddr_ofs
で指定します。この関数ではEEPROM領域にはアクセスできません。
void ReadSiTCP(const std::string ip,
const uint32_t addr_ofs)
SiTCP予約領域から1byteのレジスタを読み出すための関数です。addr_ofs
の意味はWrite_SiTCPと同様です。
void EraseEEPROM(const std::string ip)
EEPROMを全消去するための特殊な関数です。IPアドレスやMACやライセンス情報など全部消えるため、SiTCPのライセンスファイルは再書き込みする必要があります。この関数はBBTのSiTCPコミュニティに報告が挙がっている“一度TCPコネクションを張るとしばらく再接続することができなくなる“問題の解決に使います。詳しくは該当スレッドを見てください。
Common
FlashMemoryProgrammerとSelf Diagnosis Systemの制御用のプログラムがまとめられています。これらはHULのFWの共通部分のため、レジスタはRegisterMapCommon.hh
としてまとめられています。HUL制御の例題集のような側面があるので、各main関数の動きを説明します。
- assert_bctreset
BCT::Reset
にアクセスしFW内でリセット信号をアサートさせます。- erase_eeprom
- SiTCPControllerのEraseEEPROMを呼び出しす実行体です。
- reconfig_fpga
- 能動的にFPGAをSPIフラッシュメモリからリコンフィグする実行体です。FPGAは電源投入時にSPIフラッシュメモリからコンフィグされますが、それを任意のタイミングで行うためのプログラムです。FPGA放射線ダメージを受けた、新しいMCSをFMPを使ってSPIフラッシュメモリへダウンロードした、などのタイミングで使います。
- read_xadc
- SDS内のXADCインターフェースにアクセスして、FPGAの温度、VCCINT電圧、VCCAUX電圧を取得します。
- read_sem
- SDS内のSEMインターフェースにアクセスして、訂正可能なSEUを修正した回数、SEMの動作状態 (watchdog)、修正不可能な放射線損傷を検知したかどうか (uncorrectable)を読み出します。SEUを訂正した回数はBCTリセット以上のリセット信号か
SemRstCorCount
にアクセスで0に戻ります。Uncorrectableに1が立っている場合FPGAの再コンフィグが必要です。 - reset_sem
- SEMのソフトリセットをアサートします。
- inject_sem_error
- SEMを使って人工的にSEUを発生させます。デバッグ用です。DRPを使ってSEMにアクセスしているので、理解すれば他の動作もさせる事が出来ます。詳しくはXilinxのPG036を参照してください。
- flash_memory_programmer
- MCSファイルをSiTCPを通じてSPIフラッシュメモリへ書き込むためのプログラムです。MCSファイルをバイナリに変換(MCSは実はテキストファイルです)、SPIメモリの型番のチェック、メモリイレース、プログラム、リードバックとベリファイを順番に実行します。
- mcs_converter
- MCSファイルをあらかじめバイナリに変換しておくためのプログラムです。
- check_spi_device
- HUL上にのっているSPIフラッシュメモリの型番を調べます。何が乗っているか分からないときに使ってください。
- verify_mcs
- SPIフラッシュメモリからリードバックして指定のMCSファイルとの整合性をチェックします。
各FW用のプログラム
殆どのFWではdebug
とdaq
の実行体だけが実装されています。daq
はデータ取得するための実行体です。DAQコードのサンプルとして使ってください。RegisterMap.hh
にはFW特有のレジスタのアドレスが書かれています。ここではFW特有のプログラムについて説明します。
- DaqFuncs.cc
- DAQを行うための関数をまとめたソースコードです。ベタ移植する必要は無いですが、ConnectSocket、Event_Cycle、receive関数はそのまま移植したほうがいいでしょう。また、MH-TDCのSetTdcWindowもそのまま移植してください。基本的には計測ブロックの設定を行い、DCTでgateを開いて、EventCycleを呼び続ける、RUNが終わったらDCTでgateを閉じる、という流れになります。
- Gateを閉じた後タイムアウトするまでEventCycleを呼びつづける事でHUL内部のバッファを空にしているので、
while(-1 != EvenCycle)
の処理は必ず行ってください。これをやらないと次のRUNの先頭に前のRUNで読まれなかったイベントが返ってくる可能性があります。 - daq
- HULからデータ読み出しを実行します。 次の様にIP address、RUN番号、および取得するイベント数を引数に与えてください。
./bin/daq [ip address] [RUN no] [# of events]
. データファイルはdata/run1.dat
のようにコマンドが実行されたディレクトリのサブディレクトリdata
内に生成されます。そのため、この実行体は各ファームウェアディレクトリの下で実行されることが想定されています。data
ディレクトリが存在しない場合make実行時に生成されます。 - データ収集中、読み出したデータが何イベントかに1回コンソール上に表示されます。
HR-TDC
- initialize
- DDR receiverの初期化、および校正クロックを使ってestimator用のLUTの校正を行います。電源投入後に1度実行するする必要があります。
- decoder
- デバッグ用にデコーダが用意されています。次のようにRUN番号を与えて実行してください
./bin/decoder [RUN no]
. このプログラムはdata
ディレクトリ内のデータファイルを読み、rootfile
ディレクトリにデコード結果のroot fileを生成します。daqと同様に各ファームウェアディレクトリの下で実行されることが想定されています。
TTreeの構造
Branch name | Description | |||
---|---|---|---|---|
through | 各メザニンHR-TDCのTDC::Throughの設定を示します。 インデックス0と1はスロットUとスロットDに対応します。 | |||
stop_out | 各メザニンHR-TDCのTDC::StopDoutの設定を示します。 インデックス0と1はスロットUとスロットDに対応します。 | |||
over_flow | Sub-headersのOverFlow bitを示します。インデックス0と1はスロットUとスロットDに対応します。 | |||
Decoded common stop TDC data. | ||||
stop_fine_count | Common stop dataのFine count (TDC dataの下位13 bit)です。TDC::StopDoutが1である場合利用可能なデータです。 | |||
stop_estimator | Common stop dataのestimator値です。TDC::StopDoutが1である場合利用可能なデータです。 | |||
stop_coarse_count | Common stop dataのcouarse count (TDCデータの上位11 bit)。TDC::StopDoutが1である場合利用可能なデータです。 | |||
common_stop | Common stopのTDC値。TDC::StopDoutが1である場合利用可能なデータです。 | |||
Decoded data for leading edge measurement. | ||||
num_hit | リーディングエッジデータのヒット数です。 | |||
num_hit_ch | 各チャンネルにおけるリーディングエッジデータのヒット数です。 | |||
channel | チャンネル番号です。この配列のインデックス番号はデコードされた順番を示します。 | |||
fine_count | リーディングエッジデータのfine count値です。TDC::Throughが1の時有効なデータです。この配列のインデックス番号はデコードされた順番を示します。 | |||
estimator | リーディングエッジデータのestimator値です。TDC::Throughが0の時有効なデータです。この配列のインデックス番号はデコードされた順番を示します。 | |||
coarse_count | リーディングエッジデータのcoarse count値です。この配列のインデックス番号はデコードされた順番を示します。 | |||
tdc_leading | リーディングエッジデータのTDC値です。この配列のインデックス番号はデコードされた順番を示します。 | |||
Decoded data for trailing edge measurement. | ||||
tdc_trailing | トレーリングエッジデータのTDC値です。この配列のインデックス番号はデコードされた順番を示します。 | |||
ブランチ名がtから始まる物はトレーリングエッジデータのデコード結果を示します。 |