The following state program illustrates entry and exit actions.
assign v to "grw:xxxExample"; monitor v;
printf("Will do this on entry");
printf("Another thing to do on entry");
printf("now changing to high\n");
when (delay(.1)) { } state low
printf("Something to do on exit");
The following segment of a state program illustrates dynamic assignment of database variables to database channels. We have left out error checking for simplicity.
option -c; /* don't wait for db connections */
assign setpoint to {}; /* don't need all five strings */
sprintf (str, "MySys:%s", "name");
The following state program contains most of the concepts presented in the previous sections. It consists of four state sets: (1) level_det , (2) generate_voltage , (3) test_status , and (4) periodic_read . The state set level_det is similar to the example in See A Complete State Program. It generates a triangle waveform in one state set and detects the level in another. Other state sets detect and print alarm status and demonstrate asynchronous pvGet and pvPut operation. The program demonstrates several other concepts, including access to run-time parameters with macro substitution and macValueGet , use of arrays, escaped C code, and VxWorks input-output.
/* File example.st: State program example. */
program example ("unit=ajk, stack=11000")
/*=================== declarations =========================*/
assign wf1 to "{unit}:wf1.FVAL";
/*=================== State Sets ===========================*/
/* State set level_det detects level > 5v & < 3v */
/* Use parameter to define logging file */
if (pmac == 0 || pmac[0] == 0)
printf("No macro defined for \"output\"\n");
fd = open(pmac, (O_CREAT | O_WRONLY), 0664);
printf("Can't open %s\n", pmac);
fdprintf(fd, "Starting state program\n");
when (pvConnectCount() == pvChannelCount() ) {
fdprintf(fd, "All channels connectedly");
when (pvConnectCount() < pvChannelCount() ) {
fdprintf(fd, "Connection lost\n");
/* Check for channel status; print exceptions */
printf("start test_status\n");
fdprintf(fd, "start test_status\n");
when ((ch_status = pvStatus(ao1)) != prev_status) {
/* Periodically write/read a waveform channel. This uses
pvGetComplete() to allow asynchronous pvGet(). */
fdprintf(fd, "periodic read: ");
/* Exit procedure - close the log file */
/*==================== End of state sets =====================*/
/* This C function prints out the status, severity,
and value for a channel. Note: fd is passed as a
parameter to allow reentrant code to be generated */
print_status(int fd, float value, int status, int severity)
case NO_ALARM: pstr = "no alarm"; break;
case HIHI_ALARM: pstr = "high-high alarm"; break;
case HIGH_ALARM: pstr = "high alarm"; break;
case LOLO_ALARM: pstr = "low-low alarm"; break;
case LOW_ALARM: pstr = "low alarm"; break;
case STATE_ALARM: pstr = "state alarm"; break;
case COS_ALARM: pstr = "cos alarm"; break;
case READ_ALARM: pstr = "read alarm"; break;
case WRITE_ALARM: pstr = "write alarm"; break;
default: pstr = "other alarm"; break;
fprintf (fd, "Alarm condition: \"%s\"", pstr);
else if (severity == MAJOR_ALARM)
fdprintf (fd, ", severity: \"%s\", value=%g\n", pstr, value);