1.05k likes | 1.06k Views
< kazuro.furukawa @ kek.jp >. Introduction to Channel Access. Kazuro Furukawa <kazuro.furukawa@kek.jp> for EPICS Seminar at J-PARC March 14, 2012 Based on presentations by Kenneth Evans, Jr., 2004 Kazuro Furukawa, 2006 Kay Kasemir, 2007 Kazuro Furukawa, 2010
E N D
< kazuro.furukawa @ kek.jp > Introduction to Channel Access Kazuro Furukawa <kazuro.furukawa@kek.jp> for EPICS Seminar at J-PARC March 14, 2012 Based on presentations by Kenneth Evans, Jr., 2004 Kazuro Furukawa, 2006 Kay Kasemir, 2007 Kazuro Furukawa, 2010 <http://www-linac.kek.jp/cont/epics/>
概要 • Controls • Channel Access Concepts • Channel Access API • Simple CA Client • Simple CA Client with Callbacks • (EPICS Build System)
加速器の制御 • なぜ制御が必要か、制御で何をするのか • 粒子の軌道を変えるための電磁石の制御の例から考えてみよう
電磁石を使って粒子の軌道を制御しよう (1) • まずお試し用の電磁石で練習しようか • 電流変更するためのつまみと電流メータを使おう • 去年測った電流と磁場の関係のグラフを探さなきゃ… • 見つけたけど、いちいち読み取るのは面倒だなあ… • メータの針では精度がないからデジタル表示にしよう • PC で軌道計算をしてから設定しなくちゃ • あれ、電源がオフになった • なんだコイルの熱を冷やすのに水を流すのか… • 水の表示器を置いておこう • 間違って電流値を大き掛け過ぎたら、またオフになった • 電源を壊さないように過電流の制限に引っかかったんだ • さっきと同じ電流値にしても正しい磁場にならないぞ • 鉄芯のヒステリシスで電流と磁場の関係が変わっちゃった • 電流を上げたり下げたりして初期化しよう
電磁石を使って粒子の軌道を制御しよう (2) • 本物の粒子の軌道を曲げてみよう • あれ、本物の電磁石は 1km も離れているのか • しょうがない配線しよう • あれ、電磁石って何百台もあるの、ひえっー • とても全部配線できないよ • しょうがない、切り替え器を使って一個のつまみと一個のメータでたくさんの電磁石を扱えるようにしよう • あったまいいー • 入射器からリングに粒子を入射してと • あれ、うまく周回してくれないよ • ビームモニタの情報を PC に送って、軌道計算して、電磁石の磁場を調整しなくちゃ • ええっ、何百台もの電磁石の、制限値に注意して、磁場特性の変換をして、一度に、設定しなくてはいけないの • そんなことひとりでできないよ…
粒子を制御しよう • というわけで、 • 制御インターフェース群:加速器装置の情報解釈など • ネットワーク:情報伝送、タイミング伝送 • 計算機群:軌道計算、情報管理 (表示、操作、記録) など • を使うことになった • 制御システムを使用すれば • ビームモニタからの情報を参照して、 • シミュレーション計算結果と比較して、 • マイクロ波装置や偏向、収束、補正電磁石などを操作して、 • 粒子ビームを自在に操り、 • 粒子加速器の性能を最大限に発揮して • みんなに有効な実験結果を導くことが可能、かも...
KEKB Operation Improvement (base of SuperKEKB) Belle/KEK May.2000 Apr.2003 Dual Bunch e+ Feb.2005 Continuous Injections Dec.2008 Crab Cavities and Simultaneous Injection
大型物理実験装置 • 数十人から数千人規模の研究者が関わる物理実験装置 • 素粒子物理学実験、光学・電波天文台、プラズマ核融合、など • ほとんどが国際協力で予算獲得、建設、運用 • 例えば、素粒子のジュネーブ CERN/LHC、核融合のカダラッシュ ITER、天文のチリ ALMA などアジア、ヨーロッパ、アメリカの国際協力で実現しているものは多い • 関連した国際会議が開かれている、来年 10 月は米国 (サンフランシスコ) ITER/JAEA LHC/CERN
制御システムの目標 (の例) • 信頼性が高くかつ柔軟な制御処理機構を道具として提供する • 性能を高めるための (実時間) 自動処理 • モデリング・シミュレーション • 新しい問題に対する迅速な対処 • 情報の交換・管理 • データ解析 • 安全機構
EPICS • たくさんの制御システムが同じ問題を抱えていたのに、違うハードウェア/ソフトウェアを使い違った方法で解決しようとしていた • そこで EPICS が開発された • ほとんどの制御についての要求が満たされる • Closed Loop / Open Loop • Logical Value Conversion • Synchronous / Asynchronous • Programless / Performance • Display / Archive / Analysis
KEKB and Controls 制御用ソフトウェア EPICS • 以前はほとんどが内製ソフトウェアの組み合わせ • RPC, CORBA, … • 徐々に共通ソフトウェアに移行してきた • KEK では 1994 年から “EPICS” と呼ばれる国際共同開発のソフトウェアへ • BSD-like な Open-source、多数の研究所が採用 • SCADA や Labview などとほぼ同等またはそれ以上の機能 • 他に CORBA を基本としたものなどもある • 当初は中間層と全体制御の間で EPICS を利用していた • 現在は小型コントローラにも内蔵するようになってきている • 最近 ITER (プラズマ核融合) も採用を決める • 上位ソフトウェアはスクリプト言語で書かれるものも多い • 粒子加速器の物理の記述が行えて Mathematica 文法に近い “SADscript” というソフトウェアが多用される • 他に Python や Perl、Tcl なども • 下位ソフトウェアは C++ や C が多い
EPICS • EPICS を使用すると • これまで各研究所で作られていた制御のためのプログラムを個別に書いたり、保守したりする必要がなくなる • よりよく考慮された設計になっている可能性が高い • 当初は考えていなかった制御が必要になることは多い • 多様な制御方式に対応できる • 多様なアプリケーションプログラムを使用できる • 他のグループからの支援を得られる可能性がある • 国際的に貢献できる可能性がある • x 最新のソフトウェア技術の利用が制限される • オブジェクト指向プログラミング、CORBA、とか • 部分的に使用することは可能
チャネルアクセスの参考書 • 以降の Slide は Channel Access (CA) の概略説明 • より深く調べるときには • EPICS の web page を覗いてみる • http://www.aps.anl.gov/epics/index.php • Look under Documents • Also under Base, then a specific version of Base
EPICS システムの構成 MEDM MEDM Client Client Client MEDM Channel Access Server IOC IOC IOC Meter Power Supply Camera
3. TCP Connection Let’s talk ! • UDP Broadcast Sequence • Who has it ? 2. UDP Reply I have it ! IOC Check Check Check Check Search and Connect の手続き MEDM MEDM Client Client Client MEDM Server IOC IOC IOC Meter Power Supply Camera
Channel Access の動作 “connection request” or “search request” “get” or “caget” “put” or “caput” “set a monitor” Change its value to 30.5 Notify me when the value changes Who has a PV named “S1A:H1:CurrentAO”? What is its value? Channel Access Client CA Client CA Server OK, it is now 30.5 It is now 20.5 AMPS It is now 10.5 AMPS I do. 25.5 AMPS It is now 0.0023 AMPS Channel Access Server Process Variables: “put complete” S1A:H1:CurrentAO S1:P1:x S1:P1:y S1:G1:vacuum 30.5 is too high. It is now set to the maximum value of 27.5. “post an event” or “post a monitor” or You are not authorized to change this value or
Search 要求 • Client からの Search 要求は UDP の Packet から成る • Only goes to EPICS_CA_ADDR_LIST • Starts with a small interval (30 ms), that doubles each time • Until it gets larger than 5 s, then it stays at 5 s • Stops after 100 packets or when it gets a response • Never tries again until it sees a beacon anomaly or creates a new PV • Total time is about 8 minutes to do all 100 • 全ての Server は指定 PV が存在するかどうか調べる • 普通は最初 (または少数の) の要求 Packet で接続が確立できる • 存在しない PV を要求すると、多量の Traffic を生じる • Try to eliminate them
Beacon • Beacon は Server から送られる UDP broadcast packet • 正常時には, 個々の Server は一定時間間隔で UDP Beacon を broadcast する (like a heartbeat) • EPICS_CA_BEACON_PERIOD, 15 s by default • Server の起動時には, Server は連続した UDP beacon を broadcast する • Starts with a small interval (25 ms, 75 ms for VxWorks) • Interval doubles each time • Until it gets larger than 15 s, then it stays at 15 s • Takes about 10 beacons and 40 s to get to steady state • Client はその beacon を監視し続ける • Determine connection status, whether to reissue searches
Virtual Circuit の切断 • 3.13 and early 3.14 • Hang-up message or no response from server for 30 sec. • If not a hang-up, then client sends “Are you there” query • If no response for 5 sec, TCP connection is closed • MEDM screens go white • Clients reissue search requests • 3.14 5 and later • Hang-up message from server • TCP connection is closed • MEDM screens go white • Clients reissue search requests
Virtual Circuit の無応答 • 3.14.5 and later • No response from server for 30 sec. • Client then sends “Are you there” query • If no response for 5 sec, TCP connection is not closed • For several hours, at least • MEDM screens go white • Clients do not reissue search requests • Helps with network storms • Clients that do not call ca_poll frequently get a virtual circuit disconnect even though the server may be OK • Clients written for 3.13 but using 3.14 may have a problem • May be changed in future versions
重要な環境変数 (Environment Variable) • EPICS_CA_ADDR_LIST • Determines where to search • Is a list (separated by spaces) • “123.45.1.255 123.45.2.14 123.45.2.108” • Default is broadcast addresses of all interfaces on the host • Works when servers are on same subnet as Clients • Broadcast address • Goes to all servers on a subnet • Example: 123.45.1.255 • Use ifconfig –a on UNIX to find it (or ask an administrator) • EPICS_CA_AUTO_ADDR_LIST • YES: Include default addresses above in searches • NO: Do not search on default addresses • If you set EPICS_CA_ADDR_LIST, usually set this to NO
EPICS_CA_ADDR_LIST MEDM MEDM Client Client Client MEDM Specific 123.45.2.108 Broadcast 123.45.1.255 Subnet 1 Subnet 2 Not Included Server IOC IOC IOC Meter Power Supply Camera
CA Client EPICS_CA_ADDR_LIST EPICS_CA_AUTO_ADDR_LIST EPICS_CA_CONN_TMO EPICS_CA_BEACON_PERIOD EPICS_CA_REPEATER_PORT EPICS_CA_SERVER_PORT EPICS_CA_MAX_ARRAY_BYTES EPICS_TS_MIN_WEST さらに詳しくは Channel Access Reference Manual を参照 CA Server EPICS_CAS_SERVER_PORT EPICS_CAS_AUTO_BEACON_ADDR_LIST EPICS_CAS_BEACON_ADDR_LIST EPICS_CAS_BEACON_PERIOD EPICS_CAS_BEACON_PORT EPICS_CAS_INTF_ADDR_LIST EPICS_CAS_IGNORE_ADDR_LIST その他の環境変数
Release 3.13 の 3.14 の似ている部分 • Much effort has done into making clients written for 3.13 work with 3.14 with no changes to the coding • Even large programs like MEDM have had to make only a few minor changes • This means existing programs typically do not need to be rewritten • This is good! • In contrast, Channel Access Servers require many changes in converting to 3.14
Release 3.13 と 3.14 の違い • 3.14 is threaded • Your program does not have to be threaded • 3.14 has different names for some functions • ca_context_create for ca_task_initialize • ca_context_destroy for ca_task_exit • ca_create_channel for ca_search_and_connect • ca_create_subscription for ca_add_event • ca_clear_subscription for ca_clear_event • The new functions may have more capabilities, usually related to threading • We will use the new names • 3.14 has a different mechanism for lost connections • Virtual circuit unresponsive (Not available in 3.13) • Virtual circuit disconnected
CA (Channel Access) のAPI (Application Program Interface) • The main CA client interface is the "C" library that comes with EPICS base • Internally uses C++, but API is pure C. • Almost all other CA client interfaces use that C library • Exception: New pure Java JAC
基本的な Channel Access Client の手続き • Initialize Channel Access • ca_task_initialize or ca_context_create • Search • ca_search_and_connect or ca_create_channel • Do get or put • ca_get or ca_put • Monitor • ca_add_event or ca_create_subscription • Give Channel Access a chance to work • ca_poll, ca_pend_io, ca_pend_event • Clear a channel • ca_clear_channel • Close Channel Access • ca_task_exit or ca_context_destroy
cadef.h • All C or C++ programs must include cadef.h • #include <cadef.h> • You can look at this file to get more insight into Channel Access • This presentation will use C examples • We will try to emphasize concepts, not the language • Even if you do not use C, it is important to understand what is going on behind what you do use
ca_context_create enum ca_preemptive_callback_select { ca_disable_preemptive_callback, ca_enable_preemptive_callback }; int ca_context_create ( enum ca_preemptive_callback_select SELECT ); • Should be called once prior to any other calls • Sets up Channel Access • UseSELECT=ca_disable_preemptive_callback • Unless you intend to do threads • Can also use ca_task_initialize() for 3.13 compatibility
ca_context_destroy void ca_context_destroy (); • Should be called before exiting your program • Shuts down Channel Access • Can also use ca_task_exit() for 3.13 compatibility
ca_create_channel typedef void caCh (struct connection_handler_args ARGS); int ca_create_channel ( const char *PVNAME, caCh *CALLBACK, void *PUSER, capri PRIORITY, chid *PCHID ); • Sets up a channel and starts the search process • PVNAME is the name of the process variable • CALLBACK is the name of your connection callback (or NULL) • The callback will be called whenever the connection state changes, including when first connected • Information about the channel is contained in ARGS • Use NULL if you don’t need a callback
ca_create_channel, cont’d typedef void caCh (struct connection_handler_args ARGS); int ca_create_channel ( const char *PVNAME, caCh *CALLBACK, void *PUSER, capri PRIORITY, chid *PCHID ); • PUSER is a way to pass additional information • Whatever you have stored at this address • It is stored in the chid • In C++ it is often the this pointer for a class • Use NULL if you don’t need it • UsePRIORITY=CA_PRIORITY_DEFAULT
ca_create_channel, cont’d typedef void caCh (struct connection_handler_args ARGS); int ca_create_channel ( const char *PVNAME, caCh *CALLBACK, void *PUSER, capri PRIORITY, chid *PCHID ); • A chid is a pointer to (address of) an opaque struct used by Channel Access to store much of the channel information • chanId is the same as chid (typedef chid chanId;) • PCHID is the address of the chid pointer (Use &CHID) • You need to allocate space for the chid before making the call • Channel Access will allocate space for the struct and return the address
ca_create_channel, cont’d typedef void caCh (struct connection_handler_args ARGS); int ca_create_channel ( const char *PVNAME, caCh *CALLBACK, void *PUSER, capri PRIORITY, chid *PCHID ); • Use macros to access the information in the chid • ca_name(CHID) gives the process variable name • ca_state(CHID) gives the connection state • ca_puser(CHID) gives the PUSER you specified • Etc. • TheARGS structin the connection callback includes thechid • Can also use ca_search_and connect() for 3.13 compatibility
ca_clear_channel int ca_clear_channel (chid CHID); • Shuts down a channel and reclaims resources • Should be called before exiting the program • CHID is the same chid used in ca_create_channel
ca_array_get int ca_array_get ( chtype TYPE, unsigned long COUNT, chid CHID, void *PVALUE ); • Requests a scalar or array value from a process variable • Typically followed by ca_pend_io • TYPE is the external type of your variable • Use one of the DBR_xxx types in db_access.h • E.g. DBR_DOUBLE or DBR_STRING • COUNT is the number of array elements to read • CHID is the channel identifier from ca_create_channel • PVALUE is where you want the value(s) to go • There must be enough space to hold the values
ca_array_get_callback typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_array_get_callback ( chtype TYPE, unsigned longCOUNT, chid CHID, pCallBack USERFUNC, void *USERARG ); • Requests a scalar or array value from a process variable, using a callback • TYPE is the external type of your variable • Use one of the DBR_xxx types in db_access.h • E.g. DBR_DOUBLE or DBR_STRING • COUNT is the number of array elements to read
ca_array_get_callback, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_array_get_callback ( chtype TYPE, unsigned longCOUNT, chid CHID, pCallBack USERFUNC, void *USERARG ); • CHID is the channel identifier from ca_create_channel • USERFUNC is the name of your callback to be run when the operation completes • USERARG is a way to pass additional information to the callback • struct event_handler_argshas avoid *usrmember
ca_array_put int ca_array_put ( chtype TYPE, unsigned longCOUNT, chid CHID, const void *PVALUE); • Requests writing a scalar or array value to a process variable • Typically followed by ca_pend_io • TYPE is the external type of your supplied variable • Use one of the DBR_xxx types in db_access.h • E.g. DBR_DOUBLE or DBR_STRING • COUNT is the number of array elements to write • CHID is the channel identifier from ca_create_channel • PVALUE is where the value(s) to be written are found
ca_array_put_callback typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_array_put_callback ( chtype TYPE, unsigned longCOUNT, chid CHID, const void *PVALUE, pCallBack USERFUNC, void *USERARG ); • Requests writing a scalar or array value to a process variable, using a callback • TYPE is the external type of your variable • Use one of the DBR_xxx types in db_access.h • E.g. DBR_DOUBLE or DBR_STRING
ca_array_put_callback, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_array_put_callback ( chtype TYPE, unsigned longCOUNT, chid CHID, const void *PVALUE, pCallBack USERFUNC, void *USERARG ); • COUNT is the number of array elements to write • CHID is the channel identifier from ca_create_channel • PVALUE is where the value(s) to be written are found
ca_array_put_callback, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_array_put_callback ( chtype TYPE, unsigned longCOUNT, chid CHID, const void *PVALUE, pCallBack USERFUNC, void *USERARG ); • USERFUNC is the name of your callback to be run when the operation completes • USERARG is a way to pass additional information to the callback • struct event_handler_argshas avoid *usrmember
ca_create_subscription typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_create_subscription ( chtype TYPE, unsigned longCOUNT, chid CHID, unsigned longMASK, pCallBack USERFUNC, void *USERARG, evid *PEVID ); • Specify a callback function to be invoked whenever the process variable undergoes significant state changes • Value, Alarm status, Alarm severity • This is the way to monitor a process variable
ca_create_subscription, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_create_subscription ( chtype TYPE, unsigned longCOUNT, chid CHID, unsigned longMASK, pCallBack USERFUNC, void *USERARG, evid *PEVID ); • TYPE is the external type you want returned • Use one of the DBR_xxx types in db_access.h • E.g. DBR_DOUBLE or DBR_STRING • COUNT is the number of array elements to monitor
ca_create_subscription, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_create_subscription ( chtype TYPE, unsigned longCOUNT, chid CHID, unsigned longMASK, pCallBack USERFUNC, void *USERARG, evid *PEVID ); • CHID is the channel identifier from ca_create_channel • MASK has bits set for each of the event trigger types requested • DBE_VALUE Value changes • DBE_LOG Exceeds archival deadband • DBE_ALARM Alarm state changes
ca_create_subscription, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_create_subscription ( chtype TYPE, unsigned longCOUNT, chid CHID, unsigned longMASK, pCallBack USERFUNC, void *USERARG, evid *PEVID ); • USERFUNC is the name of your callback to be run when the state change occurs • USERARG is a way to pass additional information to the callback • struct event_handler_argshas avoid *usrmember
ca_create_subscription, cont’d typedef void ( *pCallBack ) (struct event_handler_args ARGS); int ca_create_subscription ( chtype TYPE, unsigned longCOUNT, chid CHID, unsigned longMASK, pCallBack USERFUNC, void *USERARG, evid *PEVID ); • PEVID is the address of an evid (event id) • You need to allocate space for the evid before making the call • Similar to a chid • Only used to clear the subscription (Can be NULL if not needed)