EPICS

Writing Channel Access Clients
Kazuro Furukawa, KEK(Marty Kraimer, APS, USPAS1999)(Bob Dalesio, LANL, USPAS2003)

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

1

References
u

EPICS

EPICS R3.12 / R3.14 Channel Access Reference Manual
詳細なドキュメント

ucadef.h caerr.h - CA の基本インターフェースの記述

udb_access.h
データの定義、分かりにくいがロバストなソフトウェアを書くためには重要

u

LANL にあるチュートリアルも分かりやすい
EPICS Web ページからたどることができる

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

2

CA between IOC and OPI

EPICS

WORKSTATION
user program
Channel Access
Repeater

Channel AccessserverChannel AccessclientChannel Accessclientdatabase access library
DATABASE

C program
SNL sequence

database libraryrecord support
device support
device drivers
IOCinstrumentation
andcontrol hardware
Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

3

Overview of Talk
uEPICS

クライアントソフトウェアの例題の紹介
CA API/Macro の簡単な使用例
CA Callback の使用例
（db_access.h の詳細は省く）
SEVCHK
SEVCHK(<function call>,”message”)
リターンコードを検査する Macro
もしエラーがあればメッセージを表示して終了する
以下の使用例で使う、‫ݠ‬験には便利
実用ソフトウェアでは使用するべきではない

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

4Very Simple Example

EPICS/*caSimpleExample.c*/#include <stddef.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "cadef.h"main(int argc,char **argv){doubledata;
chid mychid;if(argc != 2) {fprintf(stderr,"usage: caExample pvname\n");exit(1);}

SEVCHK(ca_task_initialize(),"ca_task_initialize");
SEVCHK(ca_search(argv[1],&mychid),"ca_search failure");SEVCHK(ca_pend_io(5.0),"ca_pend_io failure");SEVCHK(ca_get(DBR_DOUBLE,mychid,(void *)&data),"ca_get failure");SEVCHK(ca_pend_io(5.0),"ca_pend_io failure");printf("%s %f\n",argv[1],data);
return(0);}Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

5caExample

EPICS/*from stdin read list of PVs to monitor*/#include <stddef.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <cadef.h>#define MAX_PV 1000
#define MAX_PV_NAME_LEN 40
typedef struct{
charvalue[20];chidmychid;evidmyevid;} MYNODE;

Channel Access に関する宣‫ؘ‬等
u Stdin から Process Variable (Record) 名のリストを読み込み、処理を行う例題
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

6

CA macros

EPICS

static void printChidInfo(chid chid, char *message){
printf("\n%s\n",message);printf("pv: %s type(%d) nelements(%d) host(%s)",ca_name(chid),ca_field_type(chid),
ca_element_count(chid),ca_host_name(chid));
printf(" read(%d) write(%d) state(%d)\n",ca_read_access(chid),ca_write_access(chid),
ca_state(chid));}uchid (Channel ID) を指定すると次の情報が取得できる
ca_name - nameu ca_field_type - type as defined in db_access.h
u ca_element_count - array size (1 for scalars)
u ca_host_name - INET name of hostu ca_read_access - Is read access allowed
u ca_write_access - Is write access allowed
u ca_state - connected, not connected, etc.
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

7

exception/connection
callbacks

EPICS

static void exceptionCallback(struct exception_handler_args args){
chid chid = args.chid;
MYNODE*pnode = (MYNODE *)ca_puser(chid);
long type = args.type;/*type of value returned*/long count = args.count;long stat = args.stat;
printChidInfo(chid,"exceptionCallback");
printf("type(%d) count(%d) stat(%d)\n",type,count,stat);}static void connectionCallback(struct connection_handler_args args){
chid chid = args.chid;
MYNODE*pnode = (MYNODE *)ca_puser(chid);
printChidInfo(chid,"connectionCallback");}u

exceptionCallback
以下の callback 以外のイベントがӭった場合に呼ばれる
u Ioc で発生した Error などuuconnectionCallbackuconnect/disconnect が発生する毎に呼ばれる

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

8

accessRightsCallback

EPICS

static void accessRightsCallback(struct access_rights_handler_args args){chidchid = args.chid;
MYNODE*pnode = (MYNODE *)ca_puser(chid);
printChidInfo(chid,"accessRightsCallback");}

Connect 時
u access rights が変更になった時
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

9eventCallback

EPICS

static void eventCallback(struct event_handler_args eha){chidchid = eha.chid;
MYNODE*pnode = (MYNODE *)ca_puser(chid);
longtype = eha.type;
longcount = eha.count;if(eha.status!=ECA_NORMAL) {printChidInfo(chid,"eventCallback");} else {char *pdata = (char *)eha.dbr;
printf("Event Callback: %s = %s\n",ca_name(eha.chid),pdata);}}u

Monitor のイベントが発生した時

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

10

main - startEPICS

main(){
int
npv = 0;MYNODE*pnode;MYNODE*pmynode[MAX_PV];char*pname[MAX_PV];
int
i, status;
char
tempStr[MAX_PV_NAME_LEN];
char*pstr;
while(1) {if(npv >= MAX_PV ) break;pstr = fgets(tempStr,MAX_PV_NAME_LEN,stdin);if(!pstr) break;if(strlen(pstr) <=1) continue;
pstr[strlen(pstr)-1] = '\0'; /*strip off newline*/
pname[npv] = calloc(1,strlen(pstr) + 1);
strcpy(pname[npv],pstr);
pmynode[npv] = (MYNODE *)calloc(1,sizeof(MYNODE));
npv++;}u

Stdin から Process Variable (Record) 名のリストを読み込む
caExample < fileWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

11

Actual CA calls}

EPICSSEVCHK(ca_task_initialize(),"ca_task_initialize");
SEVCHK(ca_add_exception_event(exceptionCallback,NULL),"ca_add_exception_event");for(i=0; i<npv; i++) {SEVCHK(ca_search_and_connect(pname[i],&pmynode[i]->mychid,connectionCallback,&pmynode[i]),"ca_search_and_connect");
SEVCHK(ca_replace_access_rights_event(pmynode[i]->mychid,accessRightsCallback),"ca_replace_access_rights_event");
SEVCHK(ca_add_event(DBR_STRING,
pmynode[i]->mychid,eventCallback,pmynode[i],&pmynode[i]->myevid),"ca_add_event");}/* 正常動作時にはこれ以下には到達しない */SEVCHK(ca_pend_event(0.0),"ca_pend_event");
ca_task_exit();

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

12

Start and Endu

EPICS

ca_task_initialize

ca_repeater との接続などの処理(connection management)uca_add_exception_event

CA に異常がӭこった場合の処理を行うために Callbackを指定しておく
u{その他の Code}uca_task_exit

CA に関連して確保した資源をЖ放する
Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

13

SearchuEPICS

ca_search_and_connect(name,pchid,connectionCallback,userarg)
ca_replace_access_rights_event(chid,accessRightsCallback)

要求は Buffer がいっぱいになるか ca_pend or ca_flush が実行されるまで Buffer される
u UDP ブロードキャストで Process Variable を探索要求を出す
uuu（ EPICS_CA_AUTO_ADDR_LIST が YES または未ध定の場合）

サブネット上の IOC はその Process Variable を収容していれば、要求に答える

Process Variable を収容している IOC に対して TCP 接続を確立
する
u connectionCallback は接続状態が変化すると呼ばれる
u accessRightsCallback は Access Right が変更されると呼ばれる
u chid に対して対応する userarg を使うことができる
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

14

I/OuEPICS

Puts - 多数のバリエーションがあるu

ca_array_put(type,count,chid,pvalues)...
ca_flush_io()Calls are buffered until: buffer full, ca_flush, or ca_pend.
uca_put_callback(type,count,chid,pvalue,putCallback,userarg)

putCallback called after all records processed because of put
complete processing.
u

Gets - 同様に多数のバリエーションがある
ca_array_get(type,count,chid,pvalues)...
ca_pend_io(timeout)
u ca_array_get_callback(type,count,chid,getCallback,userarg)...
ca_pend_event(timeout)
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

15

I/O continued
uEPICS

Monitors - 多数のバリエーションがあるuca_add_masked_array_event(type,count,chid,eventCallback,userarg,pevid,mask)

Call this once for each channel to be monitored.
Mask allows value changes, alarm changes, archival changes
u …
uca_pend_event(timeout)

Waits at least timeout seconds

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

16

Waiting
uEPICS

ca_flush_io()

通常 ca_pend から呼ばれる
udp/tcp の Buffer を送り出すuca_pend_io(timeout)

ca_flush_io を呼ぶ。未処理の ca_gets や ca_search が終了するか、timeout になるまで待つ
uca_pend_event(timeout)

イベントが発生するか timeout になるまで待つu timeout
0 は無限に待つという意味
u .0001 などの短い時間を指定すれば、polling を行うことに使えるuWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

17

CA with X

EPICS

Channel Access uses select() to wait.
u File Descriptor Manager can be used.
u Channel access provides ca_add_fd_registrationu X provides similar facilityuWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

18

db_access.h

EPICS

Describes the data CA can transfer
u Hard to understand and useu Provides access tou

data types:
string, char, short, long, float, doubleu status, severity, time stamp
u arraysu enums (in ioc both menus and DBF_ENUM fields)
u complete set of enum choices
u control, display, alarm limitsu Alarm AcknowledgmentuWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

19ezCa - Easy Channel
Accessu

EPICSGoals
Easy to use.
u Provide non-callback synchronous model.
uu

Data Typesuu

Basic Callsuuuu

ezcaByte, ezcaString, ezcaShort, ezcaLong, ezcaFloat,ezcaDouble
int ezcaGet(pvname, type, nelem, buff)
int ezcaPut(pvname, type, nelem, buff)
int ezcaGetWithStatus(pvname,type,nelem,buff,time,stat,sevr)

Synchronous Groupsuuu

int ezcaStartGroup(void)any combination of get and put
int ezcaEndGroup(void)

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

20

ezCa continuedu

Error Handlinguuuuuuuuu

int ezcaGetControlLimits(pvname,type,low,high)int ezcaGetGraphicLimits(pvname,type,low,high)int ezcaGetNelem(pvname,nelem)
int ezcaGetPrecision(pvname,precision)
int ezcaGetStatus(pvname,time,stat,sevr)
int ezcaGetUnits(pvname,units)

Monitor Functions
uuuu

ezcaPerror(message)
ezcaGetErrorString(message,errorstring)
ezcaFreeErrorString(errorstring)

Other Groupable Functions
uu

EPICS

int ezcaSetMonitor(pvname,type)int ezcaClearMonitor(pvname,type)int ezcaNewMonitor(pvname,type)

OthersWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

21

Starting Your PracticeEPICS

mkdir test1
u cd test1
u setenv HOST_ARCH`$EPICS_BASE/../startup/HostArch`uu

HOST_ARCH=`$EPICS_BASE/../startup/HostArch`

export HOST_ARCHu (USER=`whoami` ; export USER)
u makeBaseApp.pl –t simple test1
u cd test1App/src
u create source codeu gmake caExample
u edit Makefile.Hostu caExample ffred
u gmake (make)uSouce file が一つ (xxxx.c) であれば、cd O.linux (or O.solaris, etc)
u make xxxx
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

22

Practice Explanation 1uuuu

EPICS

HOST_ARCH=`$EPICS_BASE/../startup/HostArch`
export HOST_ARCH
assigning a platform name for EPICS software(backquotes around “$EPICS … HostArch” mean

“execute it and use the result”)
USER=`whoami` ; export USER
assigning a user name for EPICS software
mkdir test1 ; cd test1
making directory for our test
and going into it
makeBaseApp.pl –t example test1
creating environment (directory and config files)
for a new EPICS application
see the manual “EPICS IOC Applications Building
and Source Release Control”

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

23

Practice Explanation 2EPICS

cd test1App/src
u 適当な単純な sample code を作る
u gmake (make)
makeBaseApp.pl が用意した Makefile に従って EPICS
環境を準備する
u cd O.linux ; gmake xxxx
もしも Makefile.Host を適当に変更してあればこの Stepは必要ない
u xxxxプログラムを実行してみる
uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

24

Data Type Conversions in
Channel Access

EPICS

DBR
_STRING, _DOUBLE, _FLOAT, _LONG, _CHAR, _ENUM
Data type conversions are performed in the server
Endian and floating point conversions are done in the client
Polite clients requests data in native type and perform necessaryconversion on the client side

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

25

Accessing Composite Data
Structures

EPICS

Many fields are fetched from the data store in one access:struct dbr_ctrl_float
data;
struct dbr_ctrl_float*pdata = &data;
ca_get(DBR_CTRL_FLOAT,mychid,(void *)pdata);
printf(“%d %d\n”,pdata->status, pdata->severity);
printf(“%d %d\n”,pdata->stamp.secPastEpoch, pdata->stamp.nsec);
printf(“%f %f\n”,pdata->high_display_limit,pdata->low_display_limit);
printf(“%f %f\n”,pdata->high_warning_limit,pdata->low_warning_limit);
printf(“%f %f\n”,pdata->high_alarm_limit,pdata->low_alarm_limit);
printf(“%f %f\n”,pdata->high_control_limit,pdata->low_control_limit);
printf(“%f %s\n”,pdata->value, pdata->units);*Refer to db_access.h for structures...

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

26

Error Checking

EPICS

u

Error codes and error related macros are in caerr.hu

SEVCHK will exit on errors it deems irrecoverableu

ECA_NORMAL means the exchange was initiated successfullyuSEVCHK exit behavior can be replaced with your own exception handler
ca_add_exception_event(…..)
example:status = ca_array_put(data_type,channel_id,pvalue);
SEVCHK(status,”additional info in error message”);

uWriting Channel Access Clients–EPICS Training – K.F – Jul.2003.

27

Caching vs. Queuing
uuu

EPICS

An event handler can either take its actions in the event handler queuing
all data is handleddegradation mode is longer delays
Place data into an intermediate buffer and have an alternate thread
handle the datacachingdata can be overwritten
degradation mode is intermediate data is discarded
note that buffer in IOC will overwrite the last monitor on the queue
when a buffer overflows in the IOC

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

28

Channel Access Notesuca_repeater needs to be run once on each workstation

uin the database,u a deadband of 0 posts a monitor on any changeu a deadband of -1 posts monitors on every scanu

R3.15 may limit monitor eventsuread cadef.h, caerr.h and db_access.h before writing a channel
access clientu

it is most efficient to use native data types and handle data
conversions in the client program

Writing Channel Access Clients–EPICS Training – K.F – Jul.2003.

EPICS29