AlcapDAQ  1
Macros | Functions | Variables
mfe_mucap.c File Reference
#include <stdio.h>
#include "midas.h"
#include "msystem.h"
#include "mcstd.h"

Go to the source code of this file.

Macros

#define USE_EVENT_CHANNEL   1
 
#define SERVER_CACHE_SIZE   0 /* event cache before buffer */
 
#define ODB_UPDATE_TIME   1000 /* 1 seconds for ODB update */
 
#define DEFAULT_FE_TIMEOUT   60000 /* 60 seconds for watchdog timeout */
 
#define EQUIPMENT_COMMON_STR   "\Event ID = WORD : 0\n\Trigger mask = WORD : 0\n\Buffer = STRING : [32] SYSTEM\n\Type = INT : 0\n\Source = INT : 0\n\Format = STRING : [8] FIXED\n\Enabled = BOOL : 0\n\Read on = INT : 0\n\Period = INT : 0\n\Event limit = DOUBLE : 0\n\Num subevents = DWORD : 0\n\Log history = INT : 0\n\Frontend host = STRING : [32] \n\Frontend name = STRING : [32] \n\Frontend file name = STRING : [256] \n\"
 
#define EQUIPMENT_STATISTICS_STR   "\Events sent = DOUBLE : 0\n\Events per sec. = DOUBLE : 0\n\kBytes per sec. = DOUBLE : 0\n\"
 

Functions

INT frontend_init (void)
 
INT frontend_early_init (void)
 
INT frontend_exit (void)
 
INT frontend_loop (void)
 
INT begin_of_run (INT run_number, char *error)
 
INT pre_begin_of_run (INT run_number, char *error)
 
INT end_of_run (INT run_number, char *error)
 
INT pause_run (INT run_number, char *error)
 
INT resume_run (INT run_number, char *error)
 
INT poll_event (INT source, INT count, BOOL test)
 
INT interrupt_configure (INT cmd, INT source, PTYPE adr)
 
int send_event (INT index)
 
void send_all_periodic_events (INT transition)
 
void interrupt_routine (void)
 
void interrupt_enable (BOOL flag)
 
void display (BOOL bInit)
 
INT tr_prestart (INT rn, char *error)
 
INT tr_start (INT rn, char *error)
 
INT tr_prestop (INT rn, char *error)
 
INT tr_prepause (INT rn, char *error)
 
INT tr_resume (INT rn, char *error)
 
INT manual_trigger (INT index, void *prpc_param[])
 
INT register_equipment (void)
 
void update_odb (EVENT_HEADER *pevent, HNDLE hKey, INT format)
 
int message_print (const char *msg)
 
BOOL logger_root ()
 
INT scheduler (void)
 
INT cnaf_callback (INT index, void *prpc_param[])
 
int main (int argc, char *argv[])
 

Variables

char * frontend_name
 
char * frontend_file_name
 
BOOL frontend_call_loop
 
INT max_event_size
 
INT max_event_size_frag
 
INT event_buffer_size
 
INT display_period
 
INT run_state
 
INT run_number
 
DWORD actual_time
 
DWORD actual_millitime
 
char host_name [HOST_NAME_LENGTH]
 
char exp_name [NAME_LENGTH]
 
INT max_bytes_per_sec
 
INT optimize = 0
 
INT fe_stop = 0
 
BOOL debug
 
DWORD auto_restart = 0
 
HNDLE hDB
 
EQUIPMENT equipment []
 
EQUIPMENT * interrupt_eq = NULL
 
EVENT_HEADER * interrupt_odb_buffer
 
BOOL interrupt_odb_buffer_valid
 
BOOL interrupt_enabled
 

Macro Definition Documentation

#define DEFAULT_FE_TIMEOUT   60000 /* 60 seconds for watchdog timeout */

Definition at line 320 of file mfe_mucap.c.

Referenced by main().

#define EQUIPMENT_COMMON_STR   "\Event ID = WORD : 0\n\Trigger mask = WORD : 0\n\Buffer = STRING : [32] SYSTEM\n\Type = INT : 0\n\Source = INT : 0\n\Format = STRING : [8] FIXED\n\Enabled = BOOL : 0\n\Read on = INT : 0\n\Period = INT : 0\n\Event limit = DOUBLE : 0\n\Num subevents = DWORD : 0\n\Log history = INT : 0\n\Frontend host = STRING : [32] \n\Frontend name = STRING : [32] \n\Frontend file name = STRING : [256] \n\"

Definition at line 368 of file mfe_mucap.c.

Referenced by register_equipment().

#define EQUIPMENT_STATISTICS_STR   "\Events sent = DOUBLE : 0\n\Events per sec. = DOUBLE : 0\n\kBytes per sec. = DOUBLE : 0\n\"

Definition at line 386 of file mfe_mucap.c.

Referenced by register_equipment().

#define ODB_UPDATE_TIME   1000 /* 1 seconds for ODB update */

Definition at line 318 of file mfe_mucap.c.

Referenced by interrupt_routine(), and scheduler().

#define SERVER_CACHE_SIZE   0 /* event cache before buffer */

Definition at line 316 of file mfe_mucap.c.

Referenced by register_equipment(), and scheduler().

#define USE_EVENT_CHANNEL   1

Definition at line 312 of file mfe_mucap.c.

Function Documentation

INT begin_of_run ( INT  run_number,
char *  error 
)

Definition at line 295 of file crate.cpp.

296 {
297  diag_print(1, "*** Begin of run %d ***\n", run_number);
298 
299  for(int i = 0; i < num_trigger_modules; i++) {
300  if((*trigger_modules[i]).bor != NULL) {
301  int status = (*trigger_modules[i]).bor();
302  if(status != SUCCESS) {
303  return status;
304  }
305  }
306  }
307 
308  for(int i = 0; i < num_periodic_modules; i++) {
309  if((*periodic_modules[i]).bor != NULL) {
310  int status = (*periodic_modules[i]).bor();
311  if(status != SUCCESS) {
312  return status;
313  }
314  }
315  }
316 
317  cycle_active = 0;
318  event_avail = false;
319 
320  between_runs = false;
321 
322  return SUCCESS;
323 }
INT cnaf_callback ( INT  index,
void *  prpc_param[] 
)

Definition at line 1934 of file mfe_mucap.c.

References c, cam16i_q(), cam16i_rq(), cam16o_q(), cam24i_q(), cam24i_rq(), cam24o_q(), cam_crate_clear(), cam_crate_zinit(), cam_inhibit_clear(), cam_inhibit_set(), count, debug, i, printf(), and size.

Referenced by main().

1935 {
1936 DWORD cmd, b, c, n, a, f, *pdword, *size, *x, *q, dtemp;
1937 WORD *pword, *pdata, temp;
1938 INT i, count;
1939 
1940  /* Decode parameters */
1941  cmd = CDWORD(0);
1942  b = CDWORD(1);
1943  c = CDWORD(2);
1944  n = CDWORD(3);
1945  a = CDWORD(4);
1946  f = CDWORD(5);
1947  pdword = CPDWORD(6);
1948  pword = CPWORD(6);
1949  pdata = CPWORD(6);
1950  size = CPDWORD(7);
1951  x = CPDWORD(8);
1952  q = CPDWORD(9);
1953 
1954  /* determine repeat count */
1955  if (index == RPC_CNAF16)
1956  count = *size / sizeof(WORD); /* 16 bit */
1957  else
1958  count = *size / sizeof(DWORD); /* 24 bit */
1959 
1960  switch (cmd)
1961  {
1962  /*---- special commands ----*/
1963 
1964  case CNAF_INHIBIT_SET:
1965  cam_inhibit_set(c);
1966  break;
1967  case CNAF_INHIBIT_CLEAR:
1968  cam_inhibit_clear(c);
1969  break;
1970  case CNAF_CRATE_CLEAR:
1971  cam_crate_clear(c);
1972  break;
1973  case CNAF_CRATE_ZINIT:
1974  cam_crate_zinit(c);
1975  break;
1976 
1977  case CNAF_TEST:
1978  break;
1979 
1980  case CNAF:
1981  if (index == RPC_CNAF16)
1982  {
1983  for (i=0 ; i<count ; i++)
1984  if (f<16)
1985  cam16i_q(c, n, a, f, pword++, (int *) x, (int *) q);
1986  else if (f<24)
1987  cam16o_q(c, n, a, f, pword[i], (int *) x, (int *) q);
1988  else
1989  cam16i_q(c, n, a, f, &temp, (int *) x, (int *) q);
1990  }
1991  else
1992  {
1993  for (i=0 ; i<count ; i++)
1994  if (f<16)
1995  cam24i_q(c, n, a, f, pdword++, (int *) x, (int *) q);
1996  else if (f<24)
1997  cam24o_q(c, n, a, f, pdword[i], (int *) x, (int *) q);
1998  else
1999  cam24i_q(c, n, a, f, &dtemp, (int *) x, (int *) q);
2000  }
2001 
2002  break;
2003 
2004  case CNAF_nQ:
2005  if (index == RPC_CNAF16)
2006  {
2007  if (f<16)
2008  cam16i_rq(c, n, a, f, (WORD **) &pdword, count);
2009  }
2010  else
2011  {
2012  if (f<16)
2013  cam24i_rq(c, n, a, f, &pdword, count);
2014  }
2015 
2016  /* return reduced return size */
2017  *size = (int) pdword - (int) pdata;
2018  break;
2019 
2020  default:
2021  printf("cnaf: Unknown command 0x%X\n",(unsigned int)cmd);
2022  }
2023 
2024  if (debug)
2025  {
2026  if (index == RPC_CNAF16)
2027  printf("cmd=%d r=%d c=%d n=%d a=%d f=%d d=%X x=%d q=%d\n",
2028  (int)cmd, (int)count, (int)c, (int)n, (int)a, (int)f, (int)pword[0], (int)*x, (int)*q);
2029  else if (index == RPC_CNAF24)
2030  printf("cmd=%d r=%d c=%d n=%d a=%d f=%d d=%X x=%d q=%d\n",
2031  (int)cmd, (int)count, (int)c, (int)n, (int)a, (int)f, (int)pdword[0], (int)*x, (int)*q);
2032  }
2033 
2034  return RPC_SUCCESS;
2035 }
void display ( BOOL  bInit)

Definition at line 1347 of file mfe_mucap.c.

References equipment, frontend_name, host_name, i, run_number, run_state, status, and time.

Referenced by main(), manual_trigger(), and scheduler().

1348 {
1349 INT i, status;
1350 time_t full_time;
1351 char str[30];
1352 
1353  if (bInit)
1354  {
1355  ss_clear_screen();
1356 
1357  if (host_name[0])
1358  strcpy(str, host_name);
1359  else
1360  strcpy(str, "<local>");
1361 
1362  ss_printf(0, 0, "%s connected to %s. Press \"!\" to exit", frontend_name, str);
1363  ss_printf(0, 1, "================================================================================");
1364  ss_printf(0, 2, "Run status: %s", run_state == STATE_STOPPED ? "Stopped" :
1365  run_state == STATE_RUNNING ? "Running" :
1366  "Paused");
1367  ss_printf(25,2, "Run number %d ", run_number);
1368  ss_printf(0, 3, "================================================================================");
1369  ss_printf(0, 4, "Equipment Status Events Events/sec Rate[kB/s] ODB->FE FE->ODB");
1370  ss_printf(0, 5, "--------------------------------------------------------------------------------");
1371  for (i=0 ; equipment[i].name[0] ; i++)
1372  ss_printf(0, i+6, "%s", equipment[i].name);
1373  }
1374 
1375  /* display time */
1376  time(&full_time);
1377  strcpy(str, ctime(&full_time)+11);
1378  str[8] = 0;
1379  ss_printf(72, 0, "%s", str);
1380 
1381  for (i=0 ; equipment[i].name[0] ; i++)
1382  {
1383  status = equipment[i].status;
1384 
1385  if ((status == 0 || status == FE_SUCCESS) &&
1386  equipment[i].info.enabled)
1387  ss_printf(14, i+6, "OK ");
1388  else if (!equipment[i].info.enabled)
1389  ss_printf(14, i+6, "Disabled ");
1390  else if (status == FE_ERR_ODB)
1391  ss_printf(14, i+6, "ODB Error");
1392  else if (status == FE_ERR_HW)
1393  ss_printf(14, i+6, "HW Error ");
1394  else if (status == FE_ERR_DISABLED)
1395  ss_printf(14, i+6, "Disabled ");
1396  else
1397  ss_printf(14, i+6, "Unknown ");
1398 
1399  if (equipment[i].stats.events_sent > 1E9)
1400  ss_printf(25, i+6, "%1.3lfG ", equipment[i].stats.events_sent/1E9);
1401  else if (equipment[i].stats.events_sent > 1E6)
1402  ss_printf(25, i+6, "%1.3lfM ", equipment[i].stats.events_sent/1E6);
1403  else
1404  ss_printf(25, i+6, "%1.0lf ", equipment[i].stats.events_sent);
1405  ss_printf(36, i+6, "%1.1lf ", equipment[i].stats.events_per_sec);
1406  ss_printf(47, i+6, "%1.1lf ", equipment[i].stats.kbytes_per_sec);
1407  ss_printf(58, i+6, "%ld ", equipment[i].odb_in);
1408  ss_printf(69, i+6, "%ld ", equipment[i].odb_out);
1409  }
1410 
1411  /* go to next line */
1412  ss_printf(0, i+6, "");
1413 }
INT end_of_run ( INT  run_number,
char *  error 
)

Definition at line 330 of file crate.cpp.

331 {
332  diag_print(1, "*** End of run %d ***\n", run_number);
333 
334  between_runs = true;
335 
336  for(int i = 0; i < num_trigger_modules; i++) {
337  if((*trigger_modules[i]).eor != NULL) {
338  int status = (*trigger_modules[i]).eor();
339  if(status != SUCCESS) {
340  return status;
341  }
342  }
343  }
344 
345  for(int i = 0; i < num_periodic_modules; i++) {
346  if((*periodic_modules[i]).eor != NULL) {
347  int status = (*periodic_modules[i]).eor();
348  if(status != SUCCESS) {
349  return status;
350  }
351  }
352  }
353 
354 
355  return SUCCESS;
356 }
INT frontend_early_init ( void  )

Definition at line 145 of file crate.cpp.

References crate_number, equipment, FALSE, frontend_index, frontend_name, i, printf(), sprintf(), and SUCCESS.

Referenced by main().

146 {
147  // Determine our crate ID by comparing against a list of hostnames
148  printf("Entering frontend_early_init ... \n");
149  //char *hostnames[] = {"fe1", "fe2", "fe3", "turtle", "fe5", "fe6"};
150  //char *hostnames[] = {"fe1", "fe2", "daq2.MuSIC", "fe4", "fe5", "fe6", "fe7"};
151  //int crate_numbers[] = {1, 2, 3, 4, 5, 6, 9};
152  //char *hostnames[] = {"daq2.MuSIC"};
153  //int crate_numbers[] = {3};
154  //BOOL crate_has_periodic[] = {FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE};
155 
156  //int num_hostnames = sizeof(hostnames)/sizeof(char *);
157 
158  //char my_hostname[256];
159 
160  //gethostname(my_hostname, sizeof(my_hostname));
161 
162 #if 0
163  BOOL has_periodic = FALSE;
164  for(int i = 0; i < num_hostnames; i++) {
165  if(!strcmp(my_hostname, hostnames[i])) {
166  crate_number = crate_numbers[i];
167  has_periodic = crate_has_periodic[i];
168  }
169  }
170 #endif
171 
172  crate_number = 3;
173  BOOL has_periodic = FALSE;
174 
175  printf("Hostname and crate cumber defined, crate number = %d ... \n",crate_number);
176 
177  if(crate_number > 0) {
178  frontend_name = new char[32];
179  strcpy(frontend_name, "Crate ");
180 
181 
182 #if 0
183  sprintf(equipment[0].name, "Crate %d", crate_number);
184  sprintf(equipment[0].info.buffer, "BUF%d", crate_number);
185  equipment[0].info.event_id = 1000 + crate_number;
186 #endif
188 
189  printf("Crate number = %d\n",crate_number);
190 
191  if(has_periodic) {
192  sprintf(equipment[1].name, "Periodic %d", crate_number);
193  equipment[1].info.event_id = 2000 + crate_number;
194  } else {
195  sprintf(equipment[1].name, "");
196  }
197  }
198  printf("Frontend early init returns success \n");
199  return SUCCESS;
200 }
INT frontend_exit ( void  )

Definition at line 244 of file crate.cpp.

245 {
246  for(int i = 0; i < num_trigger_modules; i++) {
247  if((*trigger_modules[i]).exit != NULL) {
248  (*trigger_modules[i]).exit();
249  }
250  }
251 
252  for(int i = 0; i < num_periodic_modules; i++) {
253  if((*periodic_modules[i]).exit != NULL) {
254  (*periodic_modules[i]).exit();
255  }
256  }
257 
258  return SUCCESS;
259 }
INT frontend_init ( void  )

Definition at line 207 of file crate.cpp.

208 {
209  printf("Entering frontend_init() ... \n");
210  INT run_state = odb_get_int("/Runinfo/State");
211  if (run_state != STATE_STOPPED) {
212  cm_msg(MERROR, "Crate",
213  "Run must be stopped before starting crate program.");
214  return FE_ERR_HW;
215  }
216 
217  for(int i = 0; i < num_trigger_modules; i++) {
218  if((*trigger_modules[i]).init != NULL) {
219  int status = (*trigger_modules[i]).init();
220  if(status != SUCCESS) {
221  return status;
222  }
223  }
224  }
225 
226  for(int i = 0; i < num_periodic_modules; i++) {
227  if((*periodic_modules[i]).init != NULL) {
228  int status = (*periodic_modules[i]).init();
229  if(status != SUCCESS) {
230  return status;
231  }
232  }
233  }
234 
235  return SUCCESS;
236 }
INT frontend_loop ( void  )

Definition at line 435 of file crate.cpp.

436 {
437  // If we're going to be pre-empted, get it over with during livetime
438  // rather than deadtime.
439  if (cycle_active || run_state != STATE_RUNNING || between_runs == TRUE) {
440  dm_area_flush();
441  sched_yield();
442  }
443 
444  // Exit immediately if no run in progress
445  if (run_state != STATE_RUNNING || between_runs == TRUE) {
446  return SUCCESS;
447  }
448 
449  // Call appropriate poll functions, depending on whether we're live or dead
450  //printf("fe loop: cycle_active %i\n",cycle_active);
451  if (cycle_active) {
452 
453  for(int i = 0; i < num_trigger_modules; i++) {
454  if((*trigger_modules[i]).poll_live != NULL) {
455 
456  // There are conditions that can lead to changes in run state between
457  // modules...
458  if (run_state != STATE_RUNNING || between_runs == TRUE) {
459  return SUCCESS;
460  }
461  int status = (*trigger_modules[i]).poll_live();
462 
463  if(status == FE_END_BLOCK) {
464  cycle_active = 0;
465  event_avail = true;
466  } else if(status == FE_NEED_STOP) {
467  stop_cycle();
468  } else if(status != SUCCESS) {
469  return status;
470  }
471  }
472  }
473  } else {
474  consider_start();
475  }
476 
477  return SUCCESS;
478 }
INT interrupt_configure ( INT  cmd,
INT  source,
PTYPE  adr 
)

Definition at line 505 of file crate.cpp.

506 {
507  switch (cmd) {
508  case CMD_INTERRUPT_ENABLE:
510  break;
511  case CMD_INTERRUPT_DISABLE:
513  break;
514  case CMD_INTERRUPT_ATTACH:
515  interrupt_handler = (void (*)(void)) adr;
516  break;
517  case CMD_INTERRUPT_DETACH:
519  interrupt_handler = NULL;
520  break;
521  }
522  return SUCCESS;
523 }
void interrupt_enable ( BOOL  flag)

Definition at line 1248 of file mfe_mucap.c.

References interrupt_configure(), interrupt_enabled, and interrupt_eq.

Referenced by main(), scheduler(), tr_pause(), tr_prepause(), tr_prestop(), tr_resume(), tr_start(), and tr_stop().

1249 {
1250  interrupt_enabled = flag;
1251 
1252  if (interrupt_eq)
1253  {
1254  if (interrupt_enabled)
1255  interrupt_configure(CMD_INTERRUPT_ENABLE,0,0);
1256  else
1257  interrupt_configure(CMD_INTERRUPT_DISABLE,0,0);
1258  }
1259 }
void interrupt_routine ( void  )

Definition at line 1263 of file mfe_mucap.c.

References actual_millitime, actual_time, interrupt_eq, interrupt_odb_buffer, interrupt_odb_buffer_valid, ODB_UPDATE_TIME, and TRUE.

Referenced by register_equipment().

1264 {
1265  EVENT_HEADER *pevent;
1266 
1267  /* get pointer for upcoming event.
1268  This is a blocking call if no space available */
1269 #ifndef USE_PVIC
1270  if ((pevent = dm_pointer_get()) == NULL)
1271  cm_msg(MERROR, "interrupt_routine", "interrupt, dm_pointer_get returned NULL");
1272 #else
1273  if ((pevent = pvic_pointer_get()) == NULL)
1274  cm_msg(MERROR, "interrupt_routine", "interrupt, pvic_pointer_get returned NULL");
1275 #endif
1276 
1277  /* compose MIDAS event header */
1278  pevent->event_id = interrupt_eq->info.event_id;
1279  pevent->trigger_mask = interrupt_eq->info.trigger_mask;
1280  pevent->data_size = 0;
1281  pevent->time_stamp = actual_time;
1282  pevent->serial_number = interrupt_eq->serial_number++;
1283 
1284  /* call user readout routine */
1285  pevent->data_size = interrupt_eq->readout((char *) (pevent+1), 0);
1286 
1287  /* send event */
1288  if (pevent->data_size)
1289  {
1290  interrupt_eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
1291  interrupt_eq->events_sent++;
1292 
1293  if (interrupt_eq->buffer_handle)
1294  {
1295 #ifdef USE_EVENT_CHANNEL
1296  dm_pointer_increment(interrupt_eq->buffer_handle,
1297  pevent->data_size + sizeof(EVENT_HEADER));
1298 #else
1299 #ifdef USE_PVIC
1300  pvic_send_event(interrupt_eq->buffer_handle, pevent,
1301  pevent->data_size + sizeof(EVENT_HEADER), SYNC);
1302 #else
1303  rpc_send_event(interrupt_eq->buffer_handle, pevent,
1304  pevent->data_size + sizeof(EVENT_HEADER), SYNC);
1305 #endif
1306 #endif
1307  }
1308 
1309  /* send event to ODB */
1310  if (interrupt_eq->info.read_on & RO_ODB ||
1311  interrupt_eq->info.history)
1312  {
1313  if (actual_millitime - interrupt_eq->last_called > ODB_UPDATE_TIME)
1314  {
1315  interrupt_eq->last_called = actual_millitime;
1316  memcpy(interrupt_odb_buffer, pevent, pevent->data_size + sizeof(EVENT_HEADER));
1318  interrupt_eq->odb_out++;
1319  }
1320  }
1321  }
1322  else
1323  interrupt_eq->serial_number--;
1324 
1325 }
BOOL logger_root ( )

Definition at line 1417 of file mfe_mucap.c.

References FALSE, hDB, hKey, i, size, status, and TRUE.

Referenced by scheduler().

1419 {
1420 int size, i, status;
1421 char str[80];
1422 HNDLE hKeyRoot, hKey;
1423 
1424  if (db_find_key(hDB, 0, "/Logger/Channels", &hKeyRoot) == DB_SUCCESS)
1425  {
1426  for (i=0; ; i++)
1427  {
1428  status = db_enum_key(hDB, hKeyRoot, i, &hKey);
1429  if (status == DB_NO_MORE_SUBKEYS)
1430  break;
1431 
1432  strcpy(str, "MIDAS");
1433  size = sizeof(str);
1434  db_get_value(hDB, hKey, "Settings/Format", str, &size, TID_STRING, TRUE);
1435 
1436  if (equal_ustring(str, "ROOT"))
1437  return TRUE;
1438  }
1439  }
1440 
1441  return FALSE;
1442 }
int main ( int  argc,
char *  argv[] 
)

Definition at line 2042 of file mfe_mucap.c.

References cm_get_environment(), cnaf_callback(), debug, DEFAULT_FE_TIMEOUT, display(), display_period, equipment, event_buffer_size, exp_name, FALSE, frontend_early_init(), frontend_exit(), frontend_init(), frontend_name, hDB, host_name, i, interrupt_configure(), interrupt_enable(), interrupt_eq, interrupt_odb_buffer, max_event_size, max_event_size_frag, message_print(), printf(), register_equipment(), run_state, scheduler(), status, SUCCESS, tr_prepause(), tr_prestart, tr_prestop(), tr_resume(), tr_start(), TRUE, and usage().

2044 {
2045 INT status, i, dm_size;
2046 INT daemon;
2047 
2048  host_name[0] = 0;
2049  exp_name[0] = 0;
2050  debug = FALSE;
2051  daemon = 0;
2052 
2053  setbuf(stdout,0);
2054  setbuf(stderr,0);
2055 
2056 #ifdef SIGPIPE
2057  signal(SIGPIPE,SIG_IGN);
2058 #endif
2059 
2060 #ifdef OS_VXWORKS
2061  if (ahost_name)
2062  strcpy(host_name, ahost_name);
2063  if (aexp_name)
2064  strcpy(exp_name, aexp_name);
2065  debug = adebug;
2066 #else
2067 
2068  /* get default from environment */
2070 
2071  /* parse command line parameters */
2072  for (i=1 ; i<argc ; i++)
2073  {
2074  if (argv[i][0] == '-' && argv[i][1] == 'd')
2075  debug = TRUE;
2076  else if (argv[i][0] == '-' && argv[i][1] == 'D')
2077  daemon = 1;
2078  else if (argv[i][0] == '-' && argv[i][1] == 'O')
2079  daemon = 2;
2080  else if (argv[i][0] == '-')
2081  {
2082  if (i+1 >= argc || argv[i+1][0] == '-')
2083  goto usage;
2084  if (argv[i][1] == 'e')
2085  strcpy(exp_name, argv[++i]);
2086  else if (argv[i][1] == 'h')
2087  strcpy(host_name, argv[++i]);
2088  else
2089  {
2090 usage:
2091  printf("usage: frontend [-h Hostname] [-e Experiment] [-d] [-D] [-O]\n");
2092  printf(" [-d] Used to debug the frontend\n");
2093  printf(" [-D] Become a daemon\n");
2094  printf(" [-O] Become a daemon but keep stdout\n");
2095  return 0;
2096  }
2097  }
2098  }
2099 #endif
2100 
2101 #ifdef PART_OF_MUCAP
2103 #endif
2104 
2105  /* check event and buffer sizes */
2107  {
2108  printf("event_buffer_size too small for max. event size\n");
2109  ss_sleep(5000);
2110  return 1;
2111  }
2112 
2113  if (max_event_size > MAX_EVENT_SIZE)
2114  {
2115  printf("Requested max_event_size (%d) exceeds max. system event size (%d)",
2116  max_event_size, MAX_EVENT_SIZE);
2117  ss_sleep(5000);
2118  return 1;
2119  }
2120 
2121  dm_size = event_buffer_size;
2122 
2123 #ifdef OS_VXWORKS
2124  /* override dm_size in case of VxWorks
2125  take remaining free memory and use 20% of it for dm_ */
2126  dm_size = 2*10*(max_event_size + sizeof(EVENT_HEADER) + sizeof(INT));
2127  if (dm_size > memFindMax())
2128  {
2129  cm_msg(MERROR,"mainFE","Not enough mem space for event size");
2130  return 0;
2131  }
2132  /* takes overall 20% of the available memory resource for dm_() */
2133  dm_size = 0.2 * memFindMax();
2134 
2135  /* there are two buffers */
2136  dm_size /= 2;
2137 #endif
2138 
2139  /* reduce memory size for MS-DOS */
2140 #ifdef OS_MSDOS
2141  if (dm_size > 0x4000)
2142  dm_size = 0x4000; /* 16k */
2143 #endif
2144 
2145  /* inform user of settings */
2146  printf("Event buffer size : %d\n", event_buffer_size);
2147  printf("Buffer allocation : 2 x %d\n", dm_size);
2148  printf("System max event size : %d\n", MAX_EVENT_SIZE);
2149  printf("User max event size : %d\n", max_event_size);
2150  if (max_event_size_frag > 0)
2151  printf("User max frag. size : %d\n", max_event_size_frag);
2152  printf("# of events per buffer : %d\n\n", dm_size/max_event_size);
2153 
2154  if (daemon)
2155  {
2156  printf("\nBecoming a daemon...\n");
2157  ss_daemon_init(daemon == 2);
2158  }
2159 
2160  /* now connect to server */
2161  if (display_period)
2162  {
2163  if (host_name[0])
2164  printf("Connect to experiment %s on host %s...", exp_name, host_name);
2165  else
2166  printf("Connect to experiment %s...", exp_name);
2167  }
2168 
2169  status = cm_connect_experiment1(host_name, exp_name, frontend_name,
2170  NULL, DEFAULT_ODB_SIZE, DEFAULT_FE_TIMEOUT);
2171  if (status != CM_SUCCESS)
2172  {
2173  /* let user read message before window might close */
2174  ss_sleep(5000);
2175  return 1;
2176  }
2177 
2178  if (display_period)
2179  printf("OK\n");
2180 
2181  /* book buffer space */
2182  status = dm_buffer_create(dm_size, max_event_size);
2183  if (status != CM_SUCCESS)
2184  {
2185  printf("dm_buffer_create: Not enough memory or event too big\n");
2186  return 1;
2187  }
2188 
2189  /* remomve any dead frontend */
2190  cm_cleanup(frontend_name, FALSE);
2191 
2192  /* shutdown previous frontend */
2193  status = cm_shutdown(frontend_name, FALSE);
2194  if (status == CM_SHUTDOWN && display_period)
2195  {
2196  printf("Previous frontend stopped\n");
2197  ss_sleep(1000);
2198  }
2199 
2200  /* register transition callbacks */
2201  if (cm_register_transition(TR_START, tr_start) != CM_SUCCESS ||
2202  cm_register_transition(TR_PRESTART, tr_prestart) != CM_SUCCESS ||
2203  cm_register_transition(TR_PRESTOP, tr_prestop) != CM_SUCCESS ||
2204  cm_register_transition(TR_PREPAUSE, tr_prepause) != CM_SUCCESS ||
2205  cm_register_transition(TR_RESUME, tr_resume) != CM_SUCCESS)
2206  {
2207  printf("Failed to start local RPC server");
2208  cm_disconnect_experiment();
2209  dm_buffer_release();
2210 
2211  /* let user read message before window might close */
2212  ss_sleep(5000);
2213  return 1;
2214  }
2215 
2216  /* register CNAF callback */
2217 #ifndef PART_OF_MUCAP
2218  cm_register_function(RPC_CNAF16, cnaf_callback);
2219  cm_register_function(RPC_CNAF24, cnaf_callback);
2220 #endif
2221  cm_get_experiment_database(&hDB, &status);
2222 
2223  /* set time from server */
2224 #ifdef OS_VXWORKS
2225  cm_synchronize(NULL);
2226 #endif
2227 
2228  /* turn off watchdog if in debug mode */
2229  if (debug)
2230  cm_set_watchdog_params(TRUE, 0);
2231 
2232  /* increase RPC timeout to 2min for logger with exabyte or blocked disk */
2233  rpc_set_option(-1, RPC_OTIMEOUT, 120000);
2234 
2235  /* set own message print function */
2236  if (display_period)
2237  cm_set_msg_print(MT_ALL, MT_ALL, message_print);
2238 
2239  /* call user init function */
2240  if (display_period)
2241  printf("Init hardware...");
2242  if (frontend_init() != SUCCESS)
2243  {
2244  if (display_period)
2245  printf("\n");
2246  cm_disconnect_experiment();
2247  dm_buffer_release();
2248 
2249  /* let user read message before window might close */
2250  ss_sleep(5000);
2251  return 1;
2252  }
2253 
2254  /* reqister equipment in ODB */
2255  if (register_equipment() != SUCCESS)
2256  {
2257  if (display_period)
2258  printf("\n");
2259  cm_disconnect_experiment();
2260  dm_buffer_release();
2261 
2262  /* let user read message before window might close */
2263  ss_sleep(5000);
2264  return 1;
2265  }
2266 
2267  if (display_period)
2268  printf("OK\n");
2269 
2270  /* initialize screen display */
2271  if (display_period)
2272  {
2273  ss_sleep(1000);
2274  display(TRUE);
2275  }
2276 
2277  /* switch on interrupts if running */
2278  if (interrupt_eq && run_state == STATE_RUNNING)
2280 
2281  /* initialize ss_getchar */
2282  ss_getchar(0);
2283 
2284  /* call main scheduler loop */
2285  status = scheduler();
2286 
2287  /* reset terminal */
2288  ss_getchar(TRUE);
2289 
2290  /* switch off interrupts */
2291  if (interrupt_eq)
2292  {
2293  interrupt_configure(CMD_INTERRUPT_DISABLE, 0, 0);
2294  interrupt_configure(CMD_INTERRUPT_DETACH, 0, 0);
2296  free(interrupt_odb_buffer);
2297  }
2298 
2299  /* detach interrupts */
2300  if (interrupt_eq != NULL)
2301  interrupt_configure(CMD_INTERRUPT_DETACH, interrupt_eq->info.source, 0);
2302 
2303  /* call user exit function */
2304  frontend_exit();
2305 
2306  /* close slow control drivers */
2307  for (i=0 ; equipment[i].name[0] ; i++)
2308  if ((equipment[i].info.eq_type & EQ_SLOW) &&
2309  equipment[i].status == FE_SUCCESS)
2310  equipment[i].cd(CMD_EXIT, &equipment[i]);
2311 
2312  /* close network connection to server */
2313  cm_disconnect_experiment();
2314 
2315  if (display_period)
2316  {
2317  if (status == RPC_SHUTDOWN)
2318  {
2319  ss_clear_screen();
2320  ss_printf(0, 0, "Frontend shut down.");
2321  ss_printf(0, 1, "");
2322  }
2323  }
2324 
2325  if (status != RPC_SHUTDOWN)
2326  printf("Network connection aborted.\n");
2327 
2328  dm_buffer_release();
2329 
2330  return 0;
2331 }
INT manual_trigger ( INT  index,
void *  prpc_param[] 
)

Definition at line 536 of file mfe_mucap.c.

References display(), display_period, equipment, event_id, FALSE, i, send_event(), and SUCCESS.

Referenced by register_equipment().

537 {
538 WORD event_id, i;
539 
540  event_id = CWORD(0);
541 
542  for (i=0 ; equipment[i].name[0] ; i++)
543  if (equipment[i].info.event_id == event_id)
544  send_event(i);
545 
546  if (display_period)
547  display(FALSE);
548 
549  return SUCCESS;
550 }
int message_print ( const char *  msg)

Definition at line 1329 of file mfe_mucap.c.

Referenced by main().

1330 {
1331 char str[160];
1332 
1333  memset(str, ' ', 159);
1334  str[159] = 0;
1335 
1336  if (msg[0] == '[')
1337  msg = strchr(msg, ']')+2;
1338 
1339  memcpy(str, msg, strlen(msg));
1340  ss_printf(0, 20, str);
1341 
1342  return 0;
1343 }
INT pause_run ( INT  run_number,
char *  error 
)

Definition at line 362 of file crate.cpp.

363 {
364  return SUCCESS;
365 }
INT poll_event ( INT  source,
INT  count,
BOOL  test 
)

Definition at line 486 of file crate.cpp.

487 {
488  INT retval = false;
489 
490  if(!test) {
491  count = 1;
492  }
493 
494  for (int i = 0; i < count; i++) {
495  frontend_loop();
496  if(event_avail) {
497  retval = true;
498  }
499  }
500 
501  return retval;
502 }
INT pre_begin_of_run ( INT  run_number,
char *  error 
)

Definition at line 264 of file crate.cpp.

References diag_print(), i, num_periodic_modules, num_trigger_modules, readout_module::pre_bor, status, and SUCCESS.

Referenced by tr_prestart().

265 {
266  diag_print(1, "*** Before begin of run %d ***\n", run_number);
267 
268  for(int i = 0; i < num_trigger_modules; i++) {
269  if((*trigger_modules[i]).pre_bor != NULL) {
270  int status = (*trigger_modules[i]).pre_bor();
271  if(status != SUCCESS) {
272  return status;
273  }
274  }
275  }
276 
277  for(int i = 0; i < num_periodic_modules; i++) {
278  if((*periodic_modules[i]).pre_bor != NULL) {
279  int status = (*periodic_modules[i]).pre_bor();
280  if(status != SUCCESS) {
281  return status;
282  }
283  }
284  }
285 
286 
287  return SUCCESS;
288 }
INT register_equipment ( void  )

Definition at line 554 of file mfe_mucap.c.

References count, display_period, equipment, EQUIPMENT_COMMON_STR, EQUIPMENT_STATISTICS_STR, FALSE, frontend_file_name, frontend_name, hDB, hKey, i, interrupt_configure(), interrupt_eq, interrupt_odb_buffer, interrupt_routine(), manual_trigger(), poll_event(), printf(), run_number, run_state, SERVER_CACHE_SIZE, size, sprintf(), start_time, status, SUCCESS, and TRUE.

Referenced by main().

555 {
556 INT index, count, size, status, i, j, k, n;
557 char str[256];
558 EQUIPMENT_INFO *eq_info;
559 EQUIPMENT_STATS *eq_stats;
560 DWORD start_time, delta_time;
561 HNDLE hKey;
562 BOOL manual_trig_flag = FALSE;
563 BANK_LIST *bank_list;
564 DWORD dummy;
565 
566  /* get current ODB run state */
567  size = sizeof(run_state);
568  run_state = STATE_STOPPED;
569  db_get_value(hDB, 0, "/Runinfo/State", &run_state, &size, TID_INT, TRUE);
570  size = sizeof(run_number);
571  run_number = 1;
572  db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
573 
574  /* scan EQUIPMENT table from FRONTEND.C */
575  for (index=0 ; equipment[index].name[0] ; index++)
576  {
577  eq_info = &equipment[index].info;
578  eq_stats = &equipment[index].stats;
579 
580  if (eq_info->event_id == 0)
581  {
582  printf("Event ID 0 for %s not allowed\n", equipment[index].name);
583  ss_sleep(5000);
584  }
585 
586  /* init status */
587  equipment[index].status = FE_SUCCESS;
588 
589  sprintf(str, "/Equipment/%s/Common", equipment[index].name);
590 
591  /* get last event limit from ODB */
592  if (eq_info->eq_type != EQ_SLOW)
593  {
594  db_find_key(hDB, 0, str, &hKey);
595  size = sizeof(double);
596  if (hKey)
597  db_get_value(hDB, hKey, "Event limit", &eq_info->event_limit, &size, TID_DOUBLE, TRUE);
598  }
599 
600  /* Create common subtree */
601  status = db_create_record(hDB, 0, str, EQUIPMENT_COMMON_STR);
602  if (status != DB_SUCCESS)
603  {
604  printf("Cannot init equipment record, probably other FE is using it\n");
605  ss_sleep(3000);
606  }
607  db_find_key(hDB, 0, str, &hKey);
608 
609  if (equal_ustring(eq_info->format, "YBOS"))
610  equipment[index].format = FORMAT_YBOS;
611  else if (equal_ustring(eq_info->format, "FIXED"))
612  equipment[index].format = FORMAT_FIXED;
613  else /* default format is MIDAS */
614  equipment[index].format = FORMAT_MIDAS;
615 
616  gethostname(eq_info->frontend_host, sizeof(eq_info->frontend_host));
617  strcpy(eq_info->frontend_name, frontend_name);
618  strcpy(eq_info->frontend_file_name, frontend_file_name);
619 
620  /* set record from equipment[] table in frontend.c */
621  db_set_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), 0);
622 
623  /* open hot link to equipment info */
624  db_open_record(hDB, hKey, eq_info, sizeof(EQUIPMENT_INFO), MODE_READ, NULL, NULL);
625 
626  /*---- Create variables record ---------------------------------*/
627  sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
628  if (equipment[index].event_descrip)
629  {
630  if (equipment[index].format == FORMAT_FIXED)
631  db_create_record(hDB, 0, str, (char *)equipment[index].event_descrip);
632  else
633  {
634  /* create bank descriptions */
635  bank_list = (BANK_LIST *)equipment[index].event_descrip;
636 
637  for (; bank_list->name[0] ; bank_list++)
638  {
639  /* mabye needed later...
640  if (bank_list->output_flag == 0)
641  continue;
642  */
643 
644  if (bank_list->type == TID_STRUCT)
645  {
646  sprintf(str, "/Equipment/%s/Variables/%s", equipment[index].name, bank_list->name);
647  db_create_record(hDB, 0, str, strcomb(bank_list->init_str));
648  }
649  else
650  {
651  sprintf(str, "/Equipment/%s/Variables/%s", equipment[index].name, bank_list->name);
652  dummy = 0;
653  db_set_value(hDB, 0, str, &dummy, rpc_tid_size(bank_list->type), 1, bank_list->type);
654  }
655  }
656  }
657  }
658  else
659  db_create_key(hDB, 0, str, TID_KEY);
660 
661  sprintf(str, "/Equipment/%s/Variables", equipment[index].name);
662  db_find_key(hDB, 0, str, &hKey);
663  equipment[index].hkey_variables = hKey;
664 
665  /*---- Create and initialize statistics tree -------------------*/
666  sprintf(str, "/Equipment/%s/Statistics", equipment[index].name);
667 
668  /*-PAA- Needed in case Statistics exists but size = 0 */
669  /*-SR- Not needed since db_create_record does a delete already */
670 
671  status = db_find_key(hDB, 0, str, &hKey);
672  if (status == DB_SUCCESS)
673  {
674  status = db_delete_key(hDB, hKey, FALSE);
675  if (status != DB_SUCCESS)
676  {
677  printf("Cannot delete statistics record, error %d\n",status);
678  ss_sleep(3000);
679  }
680  }
681 
682  status = db_create_record(hDB, 0, str, EQUIPMENT_STATISTICS_STR);
683  if (status != DB_SUCCESS)
684  {
685  printf("Cannot create statistics record, error %d\n",status);
686  ss_sleep(3000);
687  }
688 
689  status = db_find_key(hDB, 0, str, &hKey);
690  if (status != DB_SUCCESS)
691  {
692  printf("Cannot find statistics record, error %d\n",status);
693  ss_sleep(3000);
694  }
695 
696  eq_stats->events_sent = 0;
697  eq_stats->events_per_sec = 0;
698  eq_stats->kbytes_per_sec = 0;
699 
700  /* open hot link to statistics tree */
701  status = db_open_record(hDB, hKey, eq_stats, sizeof(EQUIPMENT_STATS), MODE_WRITE, NULL, NULL);
702  if (status != DB_SUCCESS)
703  {
704  printf("Cannot open statistics record, error %d. Probably other FE is using it\n",status);
705  ss_sleep(3000);
706  }
707 
708  /*---- open event buffer ---------------------------------------*/
709  if (eq_info->buffer[0])
710  {
711  status = bm_open_buffer(eq_info->buffer, EVENT_BUFFER_SIZE, &equipment[index].buffer_handle);
712  if (status != BM_SUCCESS && status != BM_CREATED)
713  {
714  cm_msg(MERROR, "register_equipment",
715  "Cannot open event buffer. Try to reduce EVENT_BUFFER_SIZE in midas.h \
716 and rebuild the system.");
717  return 0;
718  }
719 
720  /* set the default buffer cache size */
721  bm_set_cache_size(equipment[index].buffer_handle, 0, SERVER_CACHE_SIZE);
722  }
723  else
724  equipment[index].buffer_handle = 0;
725 
726  /*---- evaluate polling count ----------------------------------*/
727  if (eq_info->eq_type & EQ_POLLED)
728  {
729  if (display_period)
730  printf("\nCalibrating");
731 
732  count = 1;
733  do
734  {
735  if (display_period)
736  printf(".");
737 
738  start_time = ss_millitime();
739 
740  poll_event(equipment[index].info.source, count, TRUE);
741 
742  delta_time = ss_millitime() - start_time;
743 
744  if (delta_time > 0)
745  count = (INT) ((double) count * 100 / delta_time);
746  else
747  count*=100;
748  } while (delta_time > 120 || delta_time < 80);
749 
750  equipment[index].poll_count = (INT) ((double) eq_info->period / 100 * count);
751 
752  if (display_period)
753  printf("OK\n");
754  }
755 
756  /*---- initialize interrupt events -----------------------------*/
757  if (eq_info->eq_type & EQ_INTERRUPT)
758  {
759  /* install interrupt for interrupt events */
760 
761  for (i=0 ; equipment[i].name[0] ; i++)
762  if (equipment[i].info.eq_type & EQ_POLLED)
763  {
764  equipment[index].status = FE_ERR_DISABLED;
765  cm_msg(MINFO, "register_equipment",
766  "Interrupt readout cannot be combined with polled readout");
767  }
768 
769  if (equipment[index].status != FE_ERR_DISABLED)
770  {
771  if (eq_info->enabled)
772  {
773  if (interrupt_eq)
774  {
775  equipment[index].status = FE_ERR_DISABLED;
776  cm_msg(MINFO, "register_equipment",
777  "Defined more than one equipment with interrupt readout");
778  }
779  else
780  {
781  interrupt_configure(CMD_INTERRUPT_ATTACH, eq_info->source, (PTYPE) interrupt_routine);
782  interrupt_eq = &equipment[index];
783  interrupt_odb_buffer = malloc(MAX_EVENT_SIZE+sizeof(EVENT_HEADER));
784  }
785  }
786  else
787  {
788  equipment[index].status = FE_ERR_DISABLED;
789  cm_msg(MINFO, "register_equipment", "Equipment %s disabled in file \"frontend.c\"",
790  equipment[index].name);
791  }
792  }
793  }
794 
795  /*---- initialize slow control equipment -----------------------*/
796  if (eq_info->eq_type & EQ_SLOW)
797  {
798  /* resolve duplicate device names */
799  for (i=0 ; equipment[index].driver[i].name[0] ; i++)
800  for (j=i+1 ; equipment[index].driver[j].name[0] ; j++)
801  if (equal_ustring(equipment[index].driver[i].name,
802  equipment[index].driver[j].name))
803  {
804  strcpy(str, equipment[index].driver[i].name);
805  for (k=0,n=0 ; equipment[index].driver[k].name[0] ; k++)
806  if (equal_ustring(str, equipment[index].driver[k].name))
807  sprintf(equipment[index].driver[k].name, "%s_%d", str, n++);
808 
809  break;
810  }
811 
812  /* loop over equipment list and call class driver's init method */
813  if (eq_info->enabled)
814  equipment[index].status = equipment[index].cd(CMD_INIT, &equipment[index]);
815  else
816  {
817  equipment[index].status = FE_ERR_DISABLED;
818  cm_msg(MINFO, "register_equipment", "Equipment %s disabled in file \"frontend.c\"",
819  equipment[index].name);
820  }
821 
822  /* let user read error messages */
823  if (equipment[index].status != FE_SUCCESS)
824  ss_sleep(3000);
825  }
826 
827  /*---- register callback for manual triggered events -----------*/
828  if (eq_info->eq_type & EQ_MANUAL_TRIG)
829  {
830  if (!manual_trig_flag)
831  cm_register_function(RPC_MANUAL_TRIG, manual_trigger);
832 
833  manual_trig_flag = TRUE;
834  }
835  }
836 
837  return SUCCESS;
838 }
INT resume_run ( INT  run_number,
char *  error 
)

Definition at line 371 of file crate.cpp.

372 {
373  return SUCCESS;
374 }
INT scheduler ( void  )

Definition at line 1446 of file mfe_mucap.c.

References actual_millitime, actual_time, auto_restart, display(), display_period, eq, equipment, FALSE, fe_stop, frontend_call_loop, frontend_loop(), hDB, i, interrupt_enable(), interrupt_eq, interrupt_odb_buffer, interrupt_odb_buffer_valid, logger_root(), MAX, max_bytes_per_sec, max_event_size, ODB_UPDATE_TIME, optimize, poll_event(), run_number, run_state, send_event(), SERVER_CACHE_SIZE, size, status, SUCCESS, TRUE, and update_odb().

Referenced by main().

1447 {
1448 EQUIPMENT_INFO *eq_info;
1449 EQUIPMENT *eq;
1450 EVENT_HEADER *pevent;
1451 DWORD last_time_network=0, last_time_display=0,
1452  last_time_flush=0, readout_start;
1453 INT i, j, index, status, ch, source, size, state;
1454 char str[80];
1455 BOOL buffer_done, flag, force_update = FALSE;
1456 
1457 INT opt_max=0, opt_index=0, opt_tcp_size=128, opt_cnt=0;
1458 INT err;
1459 
1460 #ifdef OS_VXWORKS
1461  rpc_set_opt_tcp_size(1024);
1462 #ifdef PPCxxx
1463  rpc_set_opt_tcp_size(NET_TCP_SIZE);
1464 #endif
1465 #endif
1466 
1467  /*----------------- MAIN equipment loop ------------------------------*/
1468 
1469  do
1470  {
1471  actual_millitime = ss_millitime();
1472  actual_time = ss_time();
1473 
1474  /*---- loop over equipment table -------------------------------*/
1475  for (index=0 ; ; index++)
1476  {
1477  eq = &equipment[index];
1478  eq_info = &eq->info;
1479 
1480  /* check if end of equipment list */
1481  if (!eq->name[0])
1482  break;
1483 
1484  if (!eq_info->enabled)
1485  continue;
1486 
1487  if (eq->status != FE_SUCCESS)
1488  continue;
1489 
1490  /*---- call idle routine for slow control equipment ----*/
1491  if ((eq_info->eq_type & EQ_SLOW) &&
1492  eq->status == FE_SUCCESS)
1493  {
1494  if (eq_info->event_limit>0 && run_state == STATE_RUNNING)
1495  {
1496  if (actual_time - eq->last_idle >= (DWORD) eq_info->event_limit)
1497  {
1498  eq->cd(CMD_IDLE, eq);
1499  eq->last_idle = actual_time;
1500  }
1501  }
1502  else
1503  eq->cd(CMD_IDLE, eq);
1504  }
1505 
1506  if (run_state == STATE_STOPPED && (eq_info->read_on & RO_STOPPED) == 0)
1507  continue;
1508  if (run_state == STATE_PAUSED && (eq_info->read_on & RO_PAUSED) == 0)
1509  continue;
1510  if (run_state == STATE_RUNNING && (eq_info->read_on & RO_RUNNING) == 0)
1511  continue;
1512 
1513  /*---- check periodic events ----*/
1514  if ((eq_info->eq_type & EQ_PERIODIC) || (eq_info->eq_type & EQ_SLOW))
1515  {
1516  if (eq_info->period == 0)
1517  continue;
1518 
1519  /* check if period over */
1520  if (actual_millitime - eq->last_called >= (DWORD) eq_info->period)
1521  {
1522  /* disable interrupts during readout */
1524 
1525  /* readout and send event */
1526  status = send_event(index);
1527 
1528  if (status != CM_SUCCESS)
1529  {
1530  cm_msg(MERROR, "scheduler", "send_event error %d",status);
1531  goto net_error;
1532  }
1533 
1534  /* re-enable the interrupt after periodic */
1536  }
1537  } /* end of periodic equipments */
1538 
1539  /*---- check polled events ----*/
1540  if (eq_info->eq_type & EQ_POLLED)
1541  {
1542  readout_start = actual_millitime;
1543  pevent = NULL;
1544 
1545  while ((source = poll_event(eq_info->source, eq->poll_count, FALSE)) > 0)
1546  {
1547 #ifndef USE_PVIC
1548  pevent = dm_pointer_get();
1549 #else
1550  pevent = pvic_pointer_get();
1551 #endif
1552  if (pevent == NULL)
1553  {
1554  cm_msg(MERROR, "scheduler", "polled, dm_pointer_get not returning valid pointer");
1555  status = SS_NO_MEMORY;
1556  goto net_error;
1557  }
1558 
1559  /* compose MIDAS event header */
1560  pevent->event_id = eq_info->event_id;
1561  pevent->trigger_mask = eq_info->trigger_mask;
1562  pevent->data_size = 0;
1563  pevent->time_stamp = actual_time;
1564  pevent->serial_number = eq->serial_number;
1565 
1566  /* put source at beginning of event, will be overwritten by
1567  user readout code, just a special feature used by some
1568  multi-source applications */
1569  *(INT *) (pevent+1) = source;
1570 
1571  if (eq->info.num_subevents)
1572  {
1573  eq->subevent_number = 0;
1574  do
1575  {
1576  *(INT *) ((char *)(pevent+1)+pevent->data_size) = source;
1577 
1578  /* call user readout routine for subevent indicating offset */
1579  size = eq->readout((char *) (pevent+1), pevent->data_size);
1580  pevent->data_size += size;
1581  if (size > 0)
1582  {
1583  if (pevent->data_size+sizeof(EVENT_HEADER) > (DWORD) max_event_size)
1584  {
1585  cm_msg(MERROR, "scheduler", "Event size %ld larger than maximum size %d",
1586  (long)(pevent->data_size+sizeof(EVENT_HEADER)), max_event_size);
1587  }
1588 
1589  eq->subevent_number++;
1590  eq->serial_number++;
1591  }
1592 
1593  /* wait for next event */
1594  do
1595  {
1596  source = poll_event(eq_info->source, eq->poll_count, FALSE);
1597 
1598  if (source == FALSE)
1599  {
1600  actual_millitime = ss_millitime();
1601 
1602  /* repeat no more than period */
1603  if (actual_millitime - readout_start > (DWORD) eq_info->period)
1604  break;
1605  }
1606  } while (source == FALSE);
1607 
1608  } while (eq->subevent_number < eq->info.num_subevents && source);
1609 
1610  /* notify readout routine about end of super-event */
1611  pevent->data_size = eq->readout((char *) (pevent+1), -1);
1612  }
1613  else
1614  {
1615  /* call user readout routine indicating event source */
1616  pevent->data_size = eq->readout((char *) (pevent+1), 0);
1617 
1618  /* check event size */
1619  if (pevent->data_size+sizeof(EVENT_HEADER) > (DWORD) max_event_size)
1620  {
1621  cm_msg(MERROR, "scheduler", "Event size %ld larger than maximum size %d",
1622  (long)(pevent->data_size+sizeof(EVENT_HEADER)), max_event_size);
1623  }
1624 
1625  /* increment serial number if event read out sucessfully */
1626  if (pevent->data_size)
1627  eq->serial_number++;
1628  }
1629 
1630  /* send event */
1631  if (pevent->data_size)
1632  {
1633  if (eq->buffer_handle)
1634  {
1635  /* send first event to ODB if logger writes in root format */
1636  if (pevent->serial_number == 1)
1637  if (logger_root())
1638  update_odb(pevent, eq->hkey_variables, eq->format);
1639 
1640 #ifdef USE_EVENT_CHANNEL
1641  dm_pointer_increment(eq->buffer_handle,
1642  pevent->data_size + sizeof(EVENT_HEADER));
1643 #else
1644 #ifdef USE_PVIC
1645  status = pvic_send_event(eq->buffer_handle, pevent,
1646  pevent->data_size + sizeof(EVENT_HEADER), SYNC);
1647 #else
1648  status = rpc_send_event(eq->buffer_handle, pevent,
1649  pevent->data_size + sizeof(EVENT_HEADER), SYNC);
1650 #endif
1651 
1652  if (status != SUCCESS)
1653  {
1654  cm_msg(MERROR, "scheduler", "rpc_send_event error %d", status);
1655  goto net_error;
1656  }
1657 #endif
1658 
1659  eq->bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
1660 
1661  if (eq->info.num_subevents)
1662  eq->events_sent += eq->subevent_number;
1663  else
1664  eq->events_sent++;
1665  }
1666  }
1667 
1668  actual_millitime = ss_millitime();
1669 
1670  /* repeat no more than period */
1671  if (actual_millitime - readout_start > (DWORD) eq_info->period)
1672  break;
1673 
1674  /* quit if event limit is reached */
1675  if (eq_info->event_limit > 0 &&
1676  eq->stats.events_sent + eq->events_sent >= eq_info->event_limit)
1677  break;
1678  }
1679 
1680  /* send event to ODB */
1681  if (pevent && (eq_info->read_on & RO_ODB || eq_info->history))
1682  {
1683  if (actual_millitime - eq->last_called > ODB_UPDATE_TIME && pevent != NULL)
1684  {
1685  eq->last_called = actual_millitime;
1686  update_odb(pevent, eq->hkey_variables, eq->format);
1687  eq->odb_out++;
1688  }
1689  }
1690  }
1691 
1692  /*---- send interrupt events ----*/
1693  if (eq_info->eq_type & EQ_INTERRUPT)
1694  {
1695  /* not much to do as work being done independently in interrupt_routine() */
1696 
1697  /* update ODB */
1699  {
1700  update_odb(interrupt_odb_buffer, interrupt_eq->hkey_variables,
1701  interrupt_eq->format);
1703  }
1704 
1705  }
1706 
1707  /*---- check if event limit is reached ----*/
1708  if (eq_info->eq_type != EQ_SLOW &&
1709  eq_info->event_limit > 0 &&
1710  eq->stats.events_sent + eq->events_sent >= eq_info->event_limit &&
1711  run_state == STATE_RUNNING)
1712  {
1713  /* stop run */
1714  if (cm_transition(TR_STOP, 0, str, sizeof(str), SYNC, FALSE) != CM_SUCCESS)
1715  cm_msg(MERROR, "scheduler", "cannot stop run: %s", str);
1716 
1717  /* check if autorestart, main loop will take care of it */
1718  size = sizeof(BOOL);
1719  flag = FALSE;
1720  db_get_value(hDB, 0, "/Logger/Auto restart", &flag, &size, TID_BOOL, TRUE);
1721 
1722  if (flag)
1723  auto_restart = ss_time() + 20; /* restart in 20 sec. */
1724 
1725  /* update event display correctly */
1726  force_update = TRUE;
1727  }
1728  }
1729 
1730  /*---- call frontend_loop periodically -------------------------*/
1731  if (frontend_call_loop)
1732  {
1733  status = frontend_loop();
1734  if (status != CM_SUCCESS)
1735  status = RPC_SHUTDOWN;
1736  }
1737 
1738  /*---- check for deferred transitions --------------------------*/
1739  cm_check_deferred_transition();
1740 
1741  /*---- calculate rates and update status page periodically -----*/
1742  if (force_update ||
1743  (display_period && actual_millitime - last_time_display > (DWORD) display_period) ||
1744  (!display_period && actual_millitime - last_time_display > 3000))
1745  {
1746  force_update = FALSE;
1747 
1748  /* calculate rates */
1749  if (actual_millitime != last_time_display)
1750  {
1751  max_bytes_per_sec = 0;
1752  for (i=0 ; equipment[i].name[0] ; i++)
1753  {
1754  eq = &equipment[i];
1755  eq->stats.events_sent += eq->events_sent;
1756  eq->stats.events_per_sec =
1757  eq->events_sent/((actual_millitime-last_time_display)/1000.0);
1758  eq->stats.kbytes_per_sec =
1759  eq->bytes_sent/1024.0/((actual_millitime-last_time_display)/1000.0);
1760 
1761  if ((INT) eq->bytes_sent > max_bytes_per_sec)
1762  max_bytes_per_sec = eq->bytes_sent;
1763 
1764  eq->bytes_sent = 0;
1765  eq->events_sent = 0;
1766  }
1767 
1769  ((double)max_bytes_per_sec/((actual_millitime-last_time_display)/1000.0));
1770 
1771  /* tcp buffer size evaluation */
1772  if (optimize)
1773  {
1774  opt_max = MAX(opt_max, (INT)max_bytes_per_sec);
1775  ss_printf(0, opt_index, "%6d : %5.1lf %5.1lf", opt_tcp_size, opt_max/1024.0,
1776  max_bytes_per_sec/1024.0);
1777  if (++opt_cnt == 10)
1778  {
1779  opt_cnt = 0;
1780  opt_max = 0;
1781  opt_index++;
1782  opt_tcp_size = 1<<(opt_index+7);
1783  rpc_set_opt_tcp_size(opt_tcp_size);
1784  if (1<<(opt_index+7) > 0x8000)
1785  {
1786  opt_index = 0;
1787  opt_tcp_size = 1<<7;
1788  rpc_set_opt_tcp_size(opt_tcp_size);
1789  }
1790  }
1791  }
1792 
1793  /* propagate changes in equipment to ODB */
1794  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
1795  db_send_changed_records();
1796  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
1797 
1798  }
1799 
1800 
1801  if (display_period)
1802  {
1803  display(FALSE);
1804 
1805  /* check keyboard */
1806  ch = 0;
1807  status = 0;
1808  while (ss_kbhit())
1809  {
1810  ch = ss_getchar(0);
1811  if (ch == -1)
1812  ch = getchar();
1813 
1814  if (ch == '!')
1815  status = RPC_SHUTDOWN;
1816  }
1817 
1818  if (ch > 0)
1819  display(TRUE);
1820  if (status == RPC_SHUTDOWN)
1821  break;
1822  }
1823 
1824  last_time_display = actual_millitime;
1825  }
1826 
1827  /*---- check to flush cache ------------------------------------*/
1828  if (actual_millitime - last_time_flush > 1000)
1829  {
1830  last_time_flush = actual_millitime;
1831 
1832  /* if cache on server is not filled in one second at current
1833  data rate, flush it now to make events available to consumers */
1834 
1836  {
1838 
1839 #ifdef USE_EVENT_CHANNEL
1840  if ((status = dm_area_flush()) != CM_SUCCESS)
1841  cm_msg(MERROR, "scheduler", "dm_area_flush: %i", status);
1842 #endif
1843 
1844  for (i=0 ; equipment[i].name[0] ; i++)
1845  {
1846  if (equipment[i].buffer_handle)
1847  {
1848  /* check if buffer already flushed */
1849  buffer_done = FALSE;
1850  for (j=0 ; j<i ; j++)
1851  if (equipment[i].buffer_handle == equipment[j].buffer_handle)
1852  {
1853  buffer_done = TRUE;
1854  break;
1855  }
1856 
1857  if (!buffer_done)
1858  {
1859  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP);
1860  rpc_flush_event();
1861  err = bm_flush_cache(equipment[i].buffer_handle, ASYNC);
1862  if (err != BM_SUCCESS)
1863  {
1864  cm_msg(MERROR,"scheduler","bm_flush_cache(ASYNC) error %d",err);
1865  return err;
1866  }
1867  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
1868  }
1869  }
1870  }
1872  }
1873  }
1874 
1875  /*---- check for auto restart --------------------------------*/
1876  if (auto_restart > 0 && ss_time() > auto_restart)
1877  {
1878  /* check if really stopped */
1879  size = sizeof(state);
1880  status = db_get_value(hDB, 0, "Runinfo/State", &state, &size, TID_INT, TRUE);
1881  if (status != DB_SUCCESS)
1882  cm_msg(MERROR, "scheduler", "cannot get Runinfo/State in database");
1883 
1884  if (state == STATE_STOPPED)
1885  {
1886  auto_restart = 0;
1887  size = sizeof(run_number);
1888  db_get_value(hDB, 0, "/Runinfo/Run number", &run_number, &size, TID_INT, TRUE);
1889 
1890  cm_msg(MTALK, "main", "starting new run");
1891  status = cm_transition(TR_START, run_number+1, NULL, 0, SYNC, FALSE);
1892  if (status != CM_SUCCESS)
1893  cm_msg(MERROR, "main", "cannot restart run");
1894  }
1895  }
1896 
1897  /*---- check network messages ----------------------------------*/
1898  if (run_state == STATE_RUNNING && interrupt_eq == NULL)
1899  {
1900 //#ifndef PART_OF_MUCAP
1901  /* only call yield once every 500ms when running */
1902  if (actual_millitime - last_time_network > 500)
1903 //#else
1904 // /* only call yield once every 1 ms when running */
1905 // if (actual_millitime - last_time_network > 0)
1906 // if(1)
1907 //#endif
1908  {
1909  status = cm_yield(0);
1910  last_time_network = actual_millitime;
1911  }
1912  else
1913  status = RPC_SUCCESS;
1914  }
1915  else
1916  /* when run is stopped or interrupts used,
1917  call yield with 100ms timeout */
1918  status = cm_yield(100);
1919 
1920  /* exit for VxWorks */
1921  if (fe_stop)
1922  status = RPC_SHUTDOWN;
1923 
1924  } while (status != RPC_SHUTDOWN && status != SS_ABORT);
1925 
1926 net_error:
1927 
1928  return status;
1929 }
void send_all_periodic_events ( INT  transition)

Definition at line 1219 of file mfe_mucap.c.

References equipment, i, and send_event().

Referenced by tr_pause(), tr_prepause(), tr_prestop(), tr_resume(), tr_start(), and tr_stop().

1220 {
1221  EQUIPMENT_INFO *eq_info;
1222  INT i;
1223 
1224  for (i=0 ; equipment[i].name[0] ; i++)
1225  {
1226  eq_info = &equipment[i].info;
1227 
1228  if (!eq_info->enabled || equipment[i].status != FE_SUCCESS)
1229  continue;
1230 
1231  if (transition == TR_START && (eq_info->read_on & RO_BOR) == 0)
1232  continue;
1233  if (transition == TR_STOP && (eq_info->read_on & RO_EOR) == 0)
1234  continue;
1235  if (transition == TR_PAUSE && (eq_info->read_on & RO_PAUSE) == 0)
1236  continue;
1237  if (transition == TR_RESUME && (eq_info->read_on & RO_RESUME) == 0)
1238  continue;
1239 
1240  send_event(i);
1241  }
1242 }
int send_event ( INT  index)

Definition at line 1003 of file mfe_mucap.c.

References equipment, i, max_event_size, max_event_size_frag, size, status, and update_odb().

Referenced by manual_trigger(), scheduler(), and send_all_periodic_events().

1004 {
1005 EQUIPMENT_INFO *eq_info;
1006 EVENT_HEADER *pevent, *pfragment;
1007 char *pdata;
1008 unsigned char *pd;
1009 INT i, status;
1010 DWORD sent, size;
1011 static void *frag_buffer = NULL;
1012 
1013  eq_info = &equipment[index].info;
1014 
1015  /* check for fragmented event */
1016  if (eq_info->eq_type & EQ_FRAGMENTED)
1017  {
1018  if (frag_buffer == NULL)
1019  frag_buffer = malloc(max_event_size_frag);
1020 
1021  if (frag_buffer == NULL)
1022  {
1023  cm_msg(MERROR, "send_event", "Not enough memory to allocate buffer for fragmented events");
1024  return SS_NO_MEMORY;
1025  }
1026 
1027  pevent = frag_buffer;
1028  }
1029  else
1030  {
1031  /* return value should be valid pointer. if NULL BIG error ==> abort */
1032  pevent = dm_pointer_get();
1033  if (pevent == NULL)
1034  {
1035  cm_msg(MERROR, "send_event", "dm_pointer_get not returning valid pointer");
1036  return SS_NO_MEMORY;
1037  }
1038  }
1039 
1040  /* compose MIDAS event header */
1041  pevent->event_id = eq_info->event_id;
1042  pevent->trigger_mask = eq_info->trigger_mask;
1043  pevent->data_size = 0;
1044  pevent->time_stamp = ss_time();
1045  pevent->serial_number = equipment[index].serial_number++;
1046 
1047  equipment[index].last_called = ss_millitime();
1048 
1049  /* call user readout routine */
1050  *((EQUIPMENT **)(pevent+1)) = &equipment[index];
1051  pevent->data_size = equipment[index].readout((char *) (pevent+1), 0);
1052 
1053  /* send event */
1054  if (pevent->data_size)
1055  {
1056  if (eq_info->eq_type & EQ_FRAGMENTED)
1057  {
1058 
1059  /* fragment event */
1060  if (pevent->data_size+sizeof(EVENT_HEADER) > (DWORD) max_event_size_frag)
1061  {
1062  cm_msg(MERROR, "send_event", "Event size %ld larger than maximum size %d for frag. ev.",
1063  (long)(pevent->data_size+sizeof(EVENT_HEADER)), max_event_size_frag);
1064  return SS_NO_MEMORY;
1065  }
1066 
1067  /* compose fragments */
1068  pfragment = dm_pointer_get();
1069  if (pfragment == NULL)
1070  {
1071  cm_msg(MERROR, "send_event", "dm_pointer_get not returning valid pointer");
1072  return SS_NO_MEMORY;
1073  }
1074 
1075  /* compose MIDAS event header */
1076  memcpy(pfragment, pevent, sizeof(EVENT_HEADER));
1077  pfragment->event_id |= EVENTID_FRAG1;
1078 
1079  /* store total event size */
1080  pd = (char *)(pfragment+1);
1081  size = pevent->data_size;
1082  for (i=0 ; i<4 ; i++)
1083  {
1084  pd[i] = (unsigned char)(size & 0xFF); /* little endian, please! */
1085  size >>= 8;
1086  }
1087 
1088  pfragment->data_size = sizeof(DWORD);
1089 
1090  pdata=(char *)(pevent+1);
1091 
1092  for (i=0,sent=0 ; sent<pevent->data_size ; i++)
1093  {
1094  if (i>0)
1095  {
1096  pfragment = dm_pointer_get();
1097 
1098  /* compose MIDAS event header */
1099  memcpy(pfragment, pevent, sizeof(EVENT_HEADER));
1100  pfragment->event_id |= EVENTID_FRAG;
1101 
1102  /* copy portion of event */
1103  size = pevent->data_size - sent;
1104  if (size > max_event_size-sizeof(EVENT_HEADER))
1105  size = max_event_size-sizeof(EVENT_HEADER);
1106 
1107  memcpy(pfragment+1, pdata, size);
1108  pfragment->data_size = size;
1109  sent += size;
1110  pdata += size;
1111  }
1112 
1113  /* send event to buffer */
1114  if (equipment[index].buffer_handle)
1115  {
1116 #ifdef USE_EVENT_CHANNEL
1117  dm_pointer_increment(equipment[index].buffer_handle,
1118  pfragment->data_size + sizeof(EVENT_HEADER));
1119 #else
1120  rpc_flush_event();
1121  status = bm_send_event(equipment[index].buffer_handle, pfragment,
1122  pfragment->data_size + sizeof(EVENT_HEADER), SYNC);
1123  if (status != BM_SUCCESS)
1124  {
1125  cm_msg(MERROR, "send_event", "bm_send_event(SYNC) error %d", status);
1126  return status;
1127  }
1128 #endif
1129  }
1130  }
1131 
1132  if (equipment[index].buffer_handle) {
1133 #ifndef USE_EVENT_CHANNEL
1134  status = bm_flush_cache(equipment[index].buffer_handle, SYNC);
1135  if (status != BM_SUCCESS)
1136  {
1137  cm_msg(MERROR,"send_event","bm_flush_cache(SYNC) error %d", status);
1138  return status;
1139  }
1140 #endif
1141  }
1142  }
1143  else
1144  {
1145  /* send unfragmented event */
1146 
1147  if (pevent->data_size+sizeof(EVENT_HEADER) > (DWORD) max_event_size)
1148  {
1149  cm_msg(MERROR, "send_event", "Event size %ld larger than maximum size %d",
1150  (long)(pevent->data_size+sizeof(EVENT_HEADER)), max_event_size);
1151  return SS_NO_MEMORY;
1152  }
1153 
1154  /* send event to buffer */
1155  if (equipment[index].buffer_handle)
1156  {
1157 #ifdef USE_EVENT_CHANNEL
1158  dm_pointer_increment(equipment[index].buffer_handle,
1159  pevent->data_size + sizeof(EVENT_HEADER));
1160 #else
1161  rpc_flush_event();
1162  status = bm_send_event(equipment[index].buffer_handle, pevent,
1163  pevent->data_size + sizeof(EVENT_HEADER), SYNC);
1164  if (status != BM_SUCCESS)
1165  {
1166  cm_msg(MERROR,"send_event","bm_send_event(SYNC) error %d",status);
1167  return status;
1168  }
1169  status = bm_flush_cache(equipment[index].buffer_handle, SYNC);
1170  if (status != BM_SUCCESS)
1171  {
1172  cm_msg(MERROR,"send_event","bm_flush_cache(SYNC) error %d",status);
1173  return status;
1174  }
1175 #endif
1176  }
1177 
1178  /* send event to ODB if RO_ODB flag is set or history is on. Do not
1179  send SLOW events since the class driver does that */
1180  if ((eq_info->read_on & RO_ODB) ||
1181  (eq_info->history > 0 && (eq_info->eq_type & ~EQ_SLOW)))
1182  {
1183  update_odb(pevent, equipment[index].hkey_variables, equipment[index].format);
1184  equipment[index].odb_out++;
1185  }
1186  }
1187 
1188  equipment[index].bytes_sent += pevent->data_size + sizeof(EVENT_HEADER);
1189  equipment[index].events_sent++;
1190 
1191  equipment[index].stats.events_sent += equipment[index].events_sent;
1192  equipment[index].events_sent = 0;
1193  }
1194  else
1195  equipment[index].serial_number--;
1196 
1197  /* emtpy event buffer */
1198 #ifdef USE_EVENT_CHANNEL
1199  if ((status = dm_area_flush()) != CM_SUCCESS)
1200  cm_msg(MERROR,"send_event","dm_area_flush: %i", status);
1201 #endif
1202 
1203  for (i=0 ; equipment[i].name[0] ; i++)
1204  if (equipment[i].buffer_handle)
1205  {
1206  status = bm_flush_cache(equipment[i].buffer_handle, SYNC);
1207  if (status != BM_SUCCESS)
1208  {
1209  cm_msg(MERROR,"send_event","bm_flush_cache(SYNC) error %d", status);
1210  return status;
1211  }
1212  }
1213 
1214  return CM_SUCCESS;
1215 }
INT tr_prepause ( INT  rn,
char *  error 
)

Definition at line 484 of file mfe_mucap.c.

References display_period, FALSE, interrupt_enable(), pause_run(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

Referenced by main().

485 {
486 INT status;
487 
488  /* disable interrupts */
490 
491  status = pause_run(rn, error);
492 
493  if (status == CM_SUCCESS)
494  {
495  run_state = STATE_PAUSED;
496  run_number = rn;
497 
498  send_all_periodic_events(TR_PAUSE);
499 
500  if (display_period)
501  ss_printf(14, 2, "Paused ");
502  }
503  else
505 
506  return status;
507 }
INT tr_prestart ( INT  rn,
char *  error 
)

Definition at line 396 of file mfe_mucap.c.

References pre_begin_of_run(), and status.

397 {
398  INT status;
399  status = pre_begin_of_run(rn, error);
400  return status;
401 }
INT tr_prestop ( INT  rn,
char *  error 
)

Definition at line 442 of file mfe_mucap.c.

References display_period, end_of_run(), equipment, FALSE, i, interrupt_enable(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

Referenced by main().

443 {
444 INT status, i;
445 
446  /* disable interrupts */
448 
449  status = end_of_run(rn, error);
450 
451  if (status == CM_SUCCESS)
452  {
453  /* don't send events if already stopped */
454  if (run_state != STATE_STOPPED)
455  send_all_periodic_events(TR_STOP);
456 
457  run_state = STATE_STOPPED;
458  run_number = rn;
459 
460  if (display_period)
461  ss_printf(14, 2, "Stopped ");
462  }
463  else
465 
466  /* flush remaining buffered events */
467  rpc_flush_event();
468  for (i=0 ; equipment[i].name[0] ; i++)
469  if (equipment[i].buffer_handle)
470  {
471  INT err = bm_flush_cache(equipment[i].buffer_handle, SYNC);
472  if (err != BM_SUCCESS)
473  {
474  cm_msg(MERROR,"tr_prestop","bm_flush_cache(SYNC) error %d",err);
475  return err;
476  }
477  }
478 
479  return status;
480 }
INT tr_resume ( INT  rn,
char *  error 
)

Definition at line 511 of file mfe_mucap.c.

References display_period, interrupt_enable(), resume_run(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

Referenced by main().

512 {
513 INT status;
514 
515  status = resume_run(rn, error);
516 
517  if (status == CM_SUCCESS)
518  {
519  run_state = STATE_RUNNING;
520  run_number = rn;
521 
522  send_all_periodic_events(TR_RESUME);
523 
524  if (display_period)
525  ss_printf(14, 2, "Running ");
526 
527  /* enable interrupts */
529  }
530 
531  return status;
532 }
INT tr_start ( INT  rn,
char *  error 
)

Definition at line 405 of file mfe_mucap.c.

References begin_of_run(), display_period, equipment, i, interrupt_enable(), run_number, run_state, send_all_periodic_events(), status, and TRUE.

Referenced by main().

406 {
407 INT i, status;
408 
409  /* reset serial numbers */
410  for (i=0 ; equipment[i].name[0] ; i++)
411  {
412  equipment[i].serial_number = 1;
413  equipment[i].subevent_number = 0;
414  equipment[i].stats.events_sent = 0;
415  equipment[i].odb_in = equipment[i].odb_out = 0;
416  }
417 
418  status = begin_of_run(rn, error);
419 
420  if (status == CM_SUCCESS)
421  {
422  run_state = STATE_RUNNING;
423  run_number = rn;
424 
425  send_all_periodic_events(TR_START);
426 
427  if (display_period)
428  {
429  ss_printf(14, 2, "Running ");
430  ss_printf(36, 2, "%d", rn);
431  }
432 
433  /* enable interrupts */
435  }
436 
437  return status;
438 }
void update_odb ( EVENT_HEADER *  pevent,
HNDLE  hKey,
INT  format 
)

Definition at line 842 of file mfe_mucap.c.

References hDB, i, key, MIN, printf(), size, and status.

Referenced by scheduler(), and send_event().

843 {
844 INT size, i, ni4, tsize, status, n_data;
845 void *pdata;
846 char name[5];
847 BANK_HEADER *pbh;
848 BANK *pbk;
849 BANK32 *pbk32;
850 void *pydata;
851 DWORD odb_type;
852 DWORD *pyevt, bkname;
853 WORD bktype;
854 HNDLE hKeyRoot, hKeyl;
855 KEY key;
856 
857  /* outcommented sind db_find_key does not work in FTCP mode, SR 25.4.03
858  rpc_set_option(-1, RPC_OTRANSPORT, RPC_FTCP); */
859 
860  if (format == FORMAT_FIXED)
861  {
862  if (db_set_record(hDB, hKey, (char *) (pevent+1),
863  pevent->data_size, 0) != DB_SUCCESS)
864  cm_msg(MERROR, "update_odb", "event #%d size mismatch", pevent->event_id);
865  }
866  else if (format == FORMAT_MIDAS)
867  {
868  pbh = (BANK_HEADER *) (pevent+1);
869  pbk = NULL;
870  pbk32 = NULL;
871  do
872  {
873  /* scan all banks */
874  if (bk_is32(pbh))
875  {
876  size = bk_iterate32(pbh, &pbk32, &pdata);
877  if (pbk32 == NULL)
878  break;
879  bkname = *((DWORD *) pbk32->name);
880  bktype = (WORD) pbk32->type;
881  }
882  else
883  {
884  size = bk_iterate(pbh, &pbk, &pdata);
885  if (pbk == NULL)
886  break;
887  bkname = *((DWORD *) pbk->name);
888  bktype = (WORD) pbk->type;
889  }
890 
891  n_data = size;
892  if (rpc_tid_size(bktype & 0xFF))
893  n_data /= rpc_tid_size(bktype & 0xFF);
894 
895  /* get bank key */
896  *((DWORD *) name) = bkname;
897  name[4] = 0;
898 
899  if (bktype == TID_STRUCT)
900  {
901  status = db_find_key(hDB, hKey, name, &hKeyRoot);
902  if (status != DB_SUCCESS)
903  {
904  cm_msg(MERROR, "update_odb", "please define bank %s in BANK_LIST in frontend.c", name);
905  continue;
906  }
907 
908  /* write structured bank */
909  for (i=0 ;; i++)
910  {
911  status = db_enum_key(hDB, hKeyRoot, i, &hKeyl);
912  if (status == DB_NO_MORE_SUBKEYS)
913  break;
914 
915  db_get_key(hDB, hKeyl, &key);
916 
917  /* adjust for alignment */
918  if (key.type != TID_STRING && key.type != TID_LINK)
919  pdata = (void *) VALIGN(pdata, MIN(ss_get_struct_align(), key.item_size));
920 
921  status = db_set_data(hDB, hKeyl, pdata, key.item_size*key.num_values,
922  key.num_values, key.type);
923  if (status != DB_SUCCESS)
924  {
925  cm_msg(MERROR, "update_odb", "cannot write %s to ODB", name);
926  continue;
927  }
928 
929  /* shift data pointer to next item */
930  (char *) pdata += key.item_size*key.num_values;
931  }
932  }
933  else
934  {
935  /* write variable length bank */
936  if (n_data > 0)
937  db_set_value(hDB, hKey, name, pdata, size, n_data, bktype & 0xFF);
938  }
939 
940  } while (1);
941  }
942  else if (format == FORMAT_YBOS)
943  {
944 #ifdef YBOS_SUPPORT
945  YBOS_BANK_HEADER *pybkh;
946 
947  /* skip the lrl (4 bytes per event) */
948  pyevt = (DWORD *) (pevent+1);
949  pybkh = NULL;
950  do
951  {
952  /* scan all banks */
953  ni4 = ybk_iterate(pyevt, &pybkh, &pydata);
954  if (pybkh == NULL || ni4 == 0)
955  break;
956 
957  /* find the corresponding odb type */
958  tsize = odb_type = 0;
959  for (i=0;id_map[0].ybos_type > 0; i++)
960  {
961  if (pybkh->type == id_map[i].ybos_type)
962  {
963  odb_type = id_map[i].odb_type;
964  tsize = id_map[i].tsize;
965  break;
966  }
967  }
968 
969  /* extract bank name (key name) */
970  *((DWORD *)name) = pybkh->name;
971  name[4] = 0;
972 
973  /* reject EVID bank */
974  if (strncmp(name, "EVID", 4) == 0)
975  continue;
976 
977  /* correct YBS number of entries */
978  if (pybkh->type == D8_BKTYPE)
979  ni4 /= 2;
980  if (pybkh->type == I2_BKTYPE)
981  ni4 *= 2;
982  if (pybkh->type == I1_BKTYPE || pybkh->type == A1_BKTYPE)
983  ni4 *= 4;
984 
985  /* write bank to ODB, ni4 always in I*4 */
986  size = ni4 * tsize;
987  if ((status = db_set_value(hDB, hKey, name, pydata, size, ni4, odb_type & 0xFF)) != DB_SUCCESS)
988  {
989  printf("status:%i odb_type:%li name:%s ni4:%i size:%i tsize:%i\n",
990  status, odb_type, name, ni4, size, tsize);
991  for (i=0;i<6;i++)
992  printf("data: %f\n",*((float *)(pydata))++);
993  }
994  } while (1);
995 #endif /* YBOS_SUPPORT */
996  }
997 
998  rpc_set_option(-1, RPC_OTRANSPORT, RPC_TCP);
999 }

Variable Documentation

DWORD actual_millitime

Definition at line 325 of file mfe_mucap.c.

Referenced by interrupt_routine(), main(), scan_fragment(), and scheduler().

DWORD actual_time

Definition at line 324 of file mfe_mucap.c.

Referenced by interrupt_routine(), and scheduler().

DWORD auto_restart = 0

Definition at line 334 of file mfe_mucap.c.

Referenced by scheduler().

BOOL debug
INT display_period

Definition at line 43 of file crate.cpp.

EQUIPMENT equipment[]

Definition at line 72 of file crate.cpp.

INT event_buffer_size

Definition at line 53 of file crate.cpp.

char exp_name[NAME_LENGTH]

Definition at line 328 of file mfe_mucap.c.

Referenced by main(), and process_file().

INT fe_stop = 0

Definition at line 332 of file mfe_mucap.c.

Referenced by scheduler().

BOOL frontend_call_loop

Definition at line 39 of file crate.cpp.

char* frontend_file_name

Definition at line 36 of file crate.cpp.

char* frontend_name

Definition at line 33 of file crate.cpp.

HNDLE hDB

Definition at line 336 of file mfe_mucap.c.

char host_name[HOST_NAME_LENGTH]

Definition at line 327 of file mfe_mucap.c.

Referenced by display(), main(), and process_file().

BOOL interrupt_enabled

Definition at line 1246 of file mfe_mucap.c.

Referenced by interrupt_enable().

EQUIPMENT* interrupt_eq = NULL

Definition at line 356 of file mfe_mucap.c.

Referenced by interrupt_enable(), interrupt_routine(), main(), register_equipment(), and scheduler().

EVENT_HEADER* interrupt_odb_buffer

Definition at line 357 of file mfe_mucap.c.

Referenced by interrupt_routine(), main(), register_equipment(), and scheduler().

BOOL interrupt_odb_buffer_valid

Definition at line 358 of file mfe_mucap.c.

Referenced by interrupt_routine(), and scheduler().

INT max_bytes_per_sec

Definition at line 330 of file mfe_mucap.c.

Referenced by scheduler().

INT max_event_size

Definition at line 47 of file crate.cpp.

INT max_event_size_frag

Definition at line 50 of file crate.cpp.

INT optimize = 0

Definition at line 331 of file mfe_mucap.c.

Referenced by scheduler().

INT run_number
INT run_state

PROGRAM: crate.cpp DESCRIPTION: Control and readout of CAEN V1724 digitizers. author: V.Tishchenko date: 12-Aug-2012

Modifications:

Definition at line 322 of file mfe_mucap.c.