# Presentation: 199617

## SNC/SEQ Developments

- Michael Laznovsky
- SLAC

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## overview

- sequencer internals via PVs
- seqPvShow()
- SNL local-variable access API
- edm-based state-level debugger
- future/ongoing

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## seq internal-state PVs

- seq program internal state available via PVs ...work at SLAC by Kuhkee Kim (now at KBSI)
- available since 9/2003 in version 2.0.6
- code in src/dev/devSequencer.c
- updates asynchronously at 10Hz via internal scan thread; use “I/O Intr” record scan
- doesn’t distinguish between multiple invocations of the same program (only first is accessible)

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## via “stringin” record

- record(stringin,"$(user):nSS")
- {
-         field(DTYP,"Sequencer Internals")
-         field(INP,"@**sncExample:nStateSets**")
-         field(SCAN,“I/O Intr")
- }
- record(stringin,"$(user):nASSIGN")
- {
-         field(DTYP,"Sequencer Internals")
-         field(INP,"@**sncExample:nAssign**")
-         field(SCAN,“I/O Intr")
- }
- etc.

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## seq internals

- stringin record INP field format:
- string is of form <seqName>.**<xxx>**, where **<xxx>** may exhibit further structure, e.g. <seqName>.**nStatesets**, <seqName>.<ssName>.**nStates**
-                    <seqName>:<ssName>
-                    <seqName>:<ssName>.**threadId**
-                    <seqName>:<ssName>.**threadIdHex**
-                    <seqName>:<ssName>.**timeElapsed**
-                    <seqName>:<ssName>.**nStates**
-                    <seqName>:<ssName>.**prevState**
-                    <seqName>:<ssName>.**nextState**
-                    <seqName>:<ssName>.**currentState**
-                    <seqName>.**nStateSets**
-                    <seqName>.**nAssgin**
-                    <seqName>.**nConnect**
-                    <seqName>.**nChans**
-                    <seqName>.**nQueues**
-                    <seqName>.**pQueues**
-                    <seqName>.**nlogFile**
-                    <seqName>.**threadPriority**
-                    <seqName>.**varSize**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## example

**record(stringin, "$(IOC):SDB$(N):SEQ") {**
**  ****field(DTYP,"Sequencer Internals")**
**  ****field(INP,"@zz99Control:ss1.currentState")**
**  ****field(SCAN,"I/O Intr")**
**}**
**% camonitor ZZ99:SDB1:SEQ**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:04.679082779 ss1_init**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:16.749157851 ss1_update**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:17.779172017 ss1_delay123**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:18.809246599 ss1_update**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:19.839219015 ss1_delay123**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:20.869182430 ss1_update**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:21.689297930 ss1_delay123**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:22.929213761 ss1_update**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:23.769233178 ss1_delay123**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:24.799274010 ss1_update**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:25.839421092 ss1_delay123**
** ****ZZ99:SDB1:SEQ                  06/01/06 09:31:26.879261175 ss1_update**
**...**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## seqPvShow()

- dump list of macro-expanded PVs to stdout/file
- show single thread’s PVs (via thread id), or all threads if id==0
- basically a per-thread “dbl”
- setting env var turns on automatic dump at each seq thread startup
- 	**epics> *****seqShow***
**	****Program Name     Thread ID  Thread Name      SS Name**
**	****freqControl      4e0200     freqCtlLX        freq_ctrl**
**                    ****4f6c28     freqCtlLX_1      sens_ctrl**
**	****epics> *****seqPvShow 4e0200 ***
**	****program freqControl 4e0200**
**	****LB40:X:FREQ:SCAN_CUT**
**	****LB40:X:FREQ:SCAN_FIT**
**	****LB40:X:PHASE:SCAN_CUT**
**	****LB40:X:PHASE:SCAN_FIT**
**	****LB40:XY:TUNE:KNOB_DELTA**
**	****LB40:XY:TUNE:KNOB_STATUS**
**	****...**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## snl local-variable access

- additional snc code output
- iocsh command-line functions
- access API

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## additional snc output

- for example, for this source code:
-                  **float  amp;**
**        ****double beta;**
**        ****short  num;**
**        ****int    mask;**
**        ****double ww;**
**        ****double theta;**
- snc adds a new table to the generated *.c file (re-entrant example):
-               **/* Local Variables (some may also be connected to PVs above)**
**         *****   ... does not include escaped declarations**
**         *****/**
**        ****static struct seqVar seqVar[NUM_VARS] = {**
**          ****/* name type_i type_s class dim1 dim2 initial address */**
**          ****{ "amp",        5, "float",    0,   1,   1, NULL, (void *)OFFSET(struct UserVar, amp) },**
**          ****{ "beta",       6, "double",   0,   1,   1, NULL, (void *)OFFSET(struct UserVar, beta) },**
**          ****{ "num",        2, "short",    0,   1,   1, NULL, (void *)OFFSET(struct UserVar, num) },**
**          ****{ "mask",       3, "int",      0,   1,   1, NULL, (void *)OFFSET(struct UserVar, mask) },**
**          ****{ "ww",         6, "double",   0,   1,   1, NULL, (void *)OFFSET(struct UserVar, ww) },**
**          ****{ "theta",      6, "double",   0,   1,   1, NULL, (void *)OFFSET(struct UserVar, theta) }**
**        ****};**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## seqVarShow (tid,varName)

- display local var info
-  ... ("tid"             == 0) -> show all local-var info for *all* threads
-  ... ("varName"  == 0) -> show all local-var info for *single* thread
-  ... ("varName"  !=  0) -> show single var value only
**long epicsShareAPI ****seqVarShow**** (**
**        ****epicsThreadId       tid,        /* thread id */**
**        ****char               *varName)    /* var name */**
**epics> *****seqVarShow***
**Program: zz99Control**
**  ****Name                  Type            [n][n]   Address Value**
**  ****------------------------------------------------------------**
**  ****amp                   float                    247128  "0"**
**  ****beta                  double                   247130  "0”**
**  ****dd                    int             [10][25] 255270  "0"**
**  ****num                   short                    247138  "0"**
**  ****mask                  int                      24713c  "0"**
**  ****w                     double                   247140  "0"**
**  ****theta                 double                   247148  "0"**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## local-variable access API

**get pointer to start of local-variable table, and var count**
-    **long epicsShareAPI ****seqVarGetPtrAndCount**** (**
**        ****epicsThreadId       tid,        /* thread id */**
**        ****SVAR              **ppSV,       /* [returned] ptr to struct array */**
**        ****int                *pNV)        /* [returned] ptr to count */**
**get single local-variable value**
-    **long epicsShareAPI ****seqVarGet**** (**
**        ****epicsThreadId       tid,        /* thread id */**
**        ****char               *varName,    /* var name */**
**        ****char               *pStr)       /* [returned] char buf for value */**
**set single local-variable value**
-    **long epicsShareAPI ****seqVarPut**** (**
**        ****epicsThreadId       tid,        /* thread id */**
**        ****char               *varName,    /* var name */**
**        ****char               *pStr)       /* value */**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## local-variable access API

- iterator versions (“SVAR” is defined in seqCom.h):
**long epicsShareAPI ****seqVarGetInit**** (epicsThreadId tid)    **
**long epicsShareAPI ****seqVarGetNext**** (epicsThreadId tid,**
**                                     ****SVAR        **ppSV)**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## local-variable get/put example

- 	**epics> *****seqShow***
**	****Program Name     Thread ID  Thread Name      SS Name**
**	****zz99Control      267ef0     zz99seq          ss1**
**	****                 ****191a88     zz99seq_1        ss2**
**	****epics> *****seqVarGet 267ef0,"beta"***
**	****"0"**
**	****epics> *****seqVarPut 267ef0,"beta","100"***
**	****epics> *****seqVarGet 267ef0,"beta"***
**	****"100"**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## state-level debugger

- edm gui backed by small(~ish) db built around **gensub** records
- view/debug multiple threads (currently up to 5)
- view/modify local variables
- force state transitions
- halt / single-step / breakpoints (now: states; later: expressions?)
- trace execution to screen/stdout/file
-      log state names
-      log when() clauses
-      log local-variable values

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## seqDbg* api(proposed)

**seqDbgRun (run | stop)**
**seqDbgStep (count)**
**seqDbgForce (state) **
**seqDbgBpSet (state | expr)**
**seqDbgBpEnable (...)**
**seqDbgBpClear (...)**
**seqDbgBpWait (...)**
**............**

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## future/on-going

- graphical state program output (graphviz/...)
- master/slave api for redundant IOCs
- suggestions?

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

- M. Laznovsky / SLAC

- EPICS / 16-June-2006

## fincomments/suggestions tolazmo @ slac.stanford.edu

- M. Laznovsky / SLAC

- EPICS / 16-June-2006