#define IDENT "1B10" /* ** +--------------------------------------------------------------+ ** | Paul Scherrer Institute | ** | SINQ Division | ** | | ** | This software may be used freely by non-profit organizations.| ** | It may be copied provided that the name of P.S.I. and of the | ** | author is included. Neither P.S.I. nor the author assume any | ** | responsibility for the use of this software outside of P.S.I.| ** +--------------------------------------------------------------+ ** ** Module Name . . . . . . . . : [...SINQHM]SinqHM_bootParamsConfig.c ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Jun 1997 ** ** Updates: ** 1A01 10-Jun-1997 DM Initial version. **--------------------------------------------------------------------------- ** SinqHM_bootParamsConfig.c is a simple VxWorks utility program for ** obtaining the "other" field of the VxWorks boot line and using it ** to automatically start the SINQ Histogram Memory processes. */ /* ** The "other" string may be specified as follows: ** ** =,..,/... ** ** There may be no white space characters in the string. Tokens ** in the string may be specified in upper or lower case. ** ** may be "sp" for "Spawn a task" ** "sps" for "Spawn and suspend a task" ** "cfg" for "Configure SinqHM_srv" ** "wt" for "Wait" **---------------------------------------------------- ** If = "sp" or "sps", then ** ** = name of task to spawn. This may be: ** "SinqHM" for SinqHM_srv or ** "lwl" for lwl_server or ** "bootUtil" for SinqHM_bootUtil or ** "focus" for FOCUS_srv ** ,.. = integer args for the spawn, as follows: ** ** If = "SinqHM" ** = TCP/IP port number for server (dflt=2400). ** = flag. If non-zero, then use level ** generator to generate timing signals (dflt=0). ** = base address of VMIO10 level generator ** module (dflt=0x1900). ** ** If = "lwl" ** = TCP/IP port number for lwl_server (dflt=3501). ** = base address of Histogram Test-generator ** module (dflt=0x1800). ** = verbosity. If non-zero, be verbose (dflt=0). ** ** If = "bootUtil" ** = TCP/IP port number for SinqHM_bootUtil (dflt=2300). ** ** If = "focus" ** = name of hostM (Mittel-bank) (dflt=localhost). ** = #-counters in Mittel-bank (dflt=150). ** = name of hostO (Ober-bank) (dflt=lnse05.vme). ** = #-counters in Ober-bank (dflt=117). ** = name of hostU (Unter-bank) (dflt=lnse06.vme). ** = #-counters in Unter-bank (dflt=116). ** = Client-side TCP/IP port number (dflt=2500). ** = Server-side TCP/IP port number (dflt=2400). ** ** In addition, will be set to 0 for "sp" and 1 for ** "sps". SinqHM_srv, lwl_server and SinqHM_bootUtil will suspend ** themselves immediately if they find is non-zero. This ** cooperation on the part of the spawned task is intended as a ** debugging aid. ** ** "SinqHM" and "SinqHM_bootUtil" will be spawned with priority ** 100, "lwl" with priority 250. ** ** Notes: ** a) Lower numbers imply higher priority. ** b) "SinqHM_Filler" also gets spawned with priority 250. It is ** important that "lwl" and "SinqHM_Filler" have the same ** priority. **---------------------------------------------------- ** If = "cfg": ** = HM_DIG, HM_PSD, TOF, HRPT or TRANS to specify the ** hist memory mode. ** = sub-mode bits to "or" with (dflt=0) ** = TCP/IP port # of server (dflt=2400) ** And for = HM_DIG or HRPT, ** = # bins (no dflt) ** = # histograms (dflt=1) ** = bytes per bin (dflt=4) ** = bin compression (dflt=0) ** = first bin (dflt=0) ** ** And for = TOF, ** = # counters (no dflt) ** = # bins per counter (no dflt) ** = time_span_per_bin (no dflt) ** = Start delay (dflt=0) ** = # of first counter (dflt=0) ** = bytes per bin (dflt=4) ** ** Note: The built-in "cfg" program can only define bins of equal ** width. For non-equal width bins, one must send the ** SQHM_CONFIG message to SinqHM_srv from a host computer. ** ** And for = TRANS, ** = #-buffers (dflt = 8) ** = buff-size (dflt = 4096) ** ** And for = HM_PSD, the arguments still need defining. **---------------------------------------------------- ** If = "wt", then ** ** = number of seconds to wait (may be useful for ** FOCUS startup). **---------------------------------------------------- ** For example: ** ** other = "sp=bootUtil/sp=SinqHM/cfg=HM_DIG,400" ** ** will cause bootUtil and SinqHM_srv to be automatically started ** after the system has been booted and will configure it in HM_DIG ** mode with a single histogram of 400 bins (as used for DMC). **---------------------------------------------------- */ /* ** Communication with SinqHM_srv is via TCP/IP protocol. ** ** To compile and link this program for VxWorks on PSS123, use: ** set src = "lnsa09:ud0:[maden.pss123.wind.sinqhm]" rcp "${src}SinqHM_bootParamsConfig.c" SinqHM_bootParamsConfig.c ccvx -I${WIND_BASE}/target/config/all SinqHM_bootParamsConfig.c ** where ccvx = ccppc -O0 \ -mcpu=603 \ -I${WIND_BASE}/target/h \ -fno-builtin \ -fno-for-scope \ -nostdinc \ -DCPU=PPC603 \ -D_GNU_TOOL \ -gdwarf -c -Wimplicit ** and, on the target, ** ** -> ld < /home/pss123/aco/maden/wind/SinqHM/SinqHM_bootParamsConfig.o ** -> taskSpawn "hmConfig", 100, 8, 20000, SinqHM_bootParamsConfig, ** ^ ** | ** TCP/IP port number of SinqHM_srv, e.g. 2400 --------+ ** **==================================================================== */ #include "vxWorks.h" /* always first */ #include "taskLib.h" #include "sockLib.h" #include "bootLib.h" #include "ioLib.h" #ifdef MV2600 #include "../config/mv2604/config.h" #elif MEN_A012 #include "../config/men_824x_ali/config.h" #else #if (CPU == PPC603) #include "../config/mv1603/config.h" #elif (CPU == PPC604) #include "../config/mv1604/config.h" #endif #endif #include #include #include #include #include #include #include #include #include #include /* **==================== Global Definitions ===================================== */ #include "SinqHM_def.h" #define MAX_ACTIONS 8 #define MAX_ARGS 10 #define NIL '\0' /* **==================== Global Variables ===================================== */ extern uint Port_base; /* The base port of SinqHM_srv */ /* **============================================================================= ** Local routine prototypes. */ int sbpc_config (int mode, char *a1, char *a2, char *a3, char *a4, char *a5, char *a6, char *a7, char *a8, char *a9); int sbpc_doAction (char *action); void sbpc_failInet (char *text); void sbpc_getErrno (int *his_errno); int sbpc_spawnBootUtil (int spnd_flg, char *a1, char *a2, char *a3, char *a4); int sbpc_spawnFocus (int spnd_flg, char *a1, char *a2, char *a3, char *a4, char *a5, char *a6, char *a7, char *a8); int sbpc_spawnLwl (int spnd_flg, char *a1, char *a2, char *a3, char *a4); int sbpc_spawnSinqHM (int spnd_flg, char *a1, char *a2, char *a3, char *a4); void sbpc_showHelp (char *errmsg); /* **--------------------------------------------------------------------------*/ int sbpc_config ( /* =========== */ int mode, char *p_arg1, char *p_arg2, char *p_arg3, char *p_arg4, char *p_arg5, char *p_arg6, char *p_arg7, char *p_arg8, char *p_arg9) { char errmsg[128]; int i, port, sub_mode; int nbins, nhists, ncntrs, bytes_per_bin, compress; int lo_bin, lo_cntr, span, delay, status, my_errno; int xSize, xOff, xFac, ySize, yOff, yFac; int hm_mode, nbuffs, nbytes; int bytes_to_come, skt; char *nxt_byte; struct sockaddr_in lcl_sockname; struct sockaddr_in rmt_sockname; int rmt_sockname_len; struct req_buff_struct req_buff; struct rply_buff_struct rply_buff; /*----------------------------------------------------------------- */ printf ("Configuring SinqHM_srv ...\n"); if (p_arg9 == NULL) { port = 2400; }else { if ((sscanf (p_arg9, "%i", &port) != 1) || (port < 128) || (port > 32767)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n", p_arg9); sbpc_showHelp (errmsg); return False; } } if (p_arg8 == NULL) { sub_mode = 0; }else { if ((sscanf (p_arg8, "%i", &sub_mode) != 1) || ((sub_mode & (~SQHM__SUB_MODE_MSK)) != 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n", p_arg8); sbpc_showHelp (errmsg); return False; } } /*----------------------------------------------------------------- ** If mode is SQHM__HM_DIG, the 5 args should be <#-bins>, ** <#-hists>, ** , ** and ** . ** ** If mode is SQHM__TOF, the 6 args should be <#-cntrs>, ** <#-bins>, ** , ** , ** and ** . ** ** If mode is SQHM__TRANS, no arguments are used. ** ** Mode SQHM__HM_PSD, is not yet supported. ** ** If mode is SQHM__HRPT, the 5 args should be <#-bins>, ** <#-hists>, ** , ** and ** . */ hm_mode = mode | sub_mode; if ((mode == SQHM__HM_DIG) || (mode == SQHM__HRPT)) { /*---------- <#-bins> */ if (p_arg1 == NULL) { sbpc_showHelp ("No value specified for <#-bins>. No default allowed!"); return False; }else { if ((sscanf (p_arg1, "%i", &nbins) != 1) || (nbins <= 0)) { sprintf (errmsg, "The value for <#-nbins>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } } /*---------- <#-hists> */ if (p_arg2 == NULL) p_arg2 = "1"; i = sscanf (p_arg2, "%i", &nhists); if ((i != 1) || (nhists <= 0)) { sprintf (errmsg, "The value for <#-hists>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg2); sbpc_showHelp (errmsg); return False; } /*---------- */ if (p_arg3 == NULL) p_arg3 = "4"; i = sscanf (p_arg3, "%i", &bytes_per_bin); if ((i != 1) || ((bytes_per_bin != 1) && (bytes_per_bin != 2) && (bytes_per_bin != 4))) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be 1, 2 or 4.", p_arg3); sbpc_showHelp (errmsg); return False; } /*---------- */ if (p_arg4 == NULL) p_arg4 = "0"; if ((sscanf (p_arg4, "%i", &compress) != 1) || (compress < 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a non-negative integer.", p_arg4); sbpc_showHelp (errmsg); return False; } /*---------- */ if (p_arg5 == NULL) p_arg5 = "0"; if ((sscanf (p_arg5, "%i", &lo_bin) != 1) || (lo_bin < 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a non-negative integer.", p_arg5); sbpc_showHelp (errmsg); return False; } if (mode == SQHM__HM_DIG) { printf (" Histogramming mode = SQHM__HM_DIG\n"); }else if (mode == SQHM__HRPT) { printf (" Histogramming mode = SQHM__HRPT\n"); hm_mode = SQHM__HRPT | SQHM__REFLECT; /* Force histogram reflection */ } printf (" Number of bins per histogram = %d\n", nbins); printf (" Number of histograms = %d\n", nhists); printf (" Number of bytes per bin = %d\n", bytes_per_bin); printf (" Bin compression factor = %d\n", compress); printf (" First bin = %d\n", lo_bin); if ((hm_mode & SQHM__REFLECT) != 0) printf (" Histogram reflection requested\n"); }else if (mode == SQHM__HM_PSD) { /* xSize*/ if ((sscanf (p_arg1, "%i", &xSize) != 1) || (xSize <= 0)) { sprintf (errmsg, "The value for <#-xSize>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /* xOff*/ if ((sscanf (p_arg2, "%i", &xOff) != 1)) { sprintf (errmsg, "The value for <#-xOff>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /* xFac */ if ((sscanf (p_arg3, "%i", &xFac) != 1)|| xFac <= 0) { sprintf (errmsg, "The value for <#-xFac>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /* ySize */ if ((sscanf (p_arg4, "%i", &ySize) != 1) || (ySize <= 0)) { sprintf (errmsg, "The value for <#-ySize>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /* yOff*/ if ((sscanf (p_arg5, "%i", &yOff) != 1)) { sprintf (errmsg, "The value for <#-yOff>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /* yFac */ if ((sscanf (p_arg6, "%i", &yFac) != 1) || (yFac <= 0)) { sprintf (errmsg, "The value for <#-yFac>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } printf("\tHistogramming Mode = SINQHM_PSD\n"); printf("\txSize, xOff, yFac = %5d, %5d, %5d\n",xSize, xOff, xFac); printf("\tySize, yOff, yFac = %5d, %5d, %5d\n",ySize, yOff, yFac); }else if (mode == SQHM__TOF) { /*---------- <#-cntrs> */ if (p_arg1 == NULL) { sbpc_showHelp ("No value specified for <#-cntrs>. No default allowed!"); return False; }else { if ((sscanf (p_arg1, "%i", &ncntrs) != 1) || (ncntrs <= 0)) { sprintf (errmsg, "The value for <#-ncntrs>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } } /*---------- <#-bins> */ if (p_arg2 == NULL) { sbpc_showHelp ("No value specified for <#-bins>. No default allowed!"); return False; }else { if ((sscanf (p_arg2, "%i", &nbins) != 1) || (nbins <= 0)) { sprintf (errmsg, "The value for <#-nbins>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg2); sbpc_showHelp (errmsg); return False; } } /*---------- */ if (p_arg3 == NULL) { sbpc_showHelp ("No value specified for . No default allowed!"); return False; }else { if ((sscanf (p_arg3, "%i", &span) != 1) || (span <= 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a positive integer.", p_arg3); sbpc_showHelp (errmsg); return False; } } /*---------- */ if (p_arg4 == NULL) p_arg4 = "0"; if ((sscanf (p_arg4, "%i", &delay) != 1) || (delay < 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a non-negative integer.", p_arg4); sbpc_showHelp (errmsg); return False; } /*---------- */ if (p_arg5 == NULL) p_arg5 = "0"; if ((sscanf (p_arg5, "%i", &lo_cntr) != 1) || (lo_cntr < 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a non-negative integer.", p_arg5); sbpc_showHelp (errmsg); return False; } /*---------- */ if (p_arg6 == NULL) p_arg6 = "4"; i = sscanf (p_arg6, "%i", &bytes_per_bin); if ((i != 1) || ((bytes_per_bin != 1) && (bytes_per_bin != 2) && (bytes_per_bin != 4))) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be 1, 2 or 4.", p_arg6); sbpc_showHelp (errmsg); return False; } printf (" Histogramming mode = SQHM__TOF\n"); printf (" Number of counters = %d\n", ncntrs); printf (" Number of bins per counter = %d\n", nbins); printf (" Bin span = %d\n", span); printf (" Start delay = %d\n", delay); printf (" First counter = %d\n", lo_cntr); printf (" Number of bytes per bin = %d\n", bytes_per_bin); }else if (mode == SQHM__TRANS) { /*---------- <#-buffers> */ if (p_arg1 == NULL) p_arg1 = "8"; if ((sscanf (p_arg1, "%i", &nbuffs) != 1) || (nbuffs <= 0)) { sprintf (errmsg, "The value for <#-buffers>, \"%s\", is illegal!\n" "It must be a positive integer.", p_arg1); sbpc_showHelp (errmsg); return False; } /*---------- <#-bins> */ if (p_arg2 == NULL) p_arg2 = "4096"; if ((sscanf (p_arg2, "%i", &nbytes) != 1) || (nbytes <= 0)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n" "It must be a positive integer.", p_arg2); sbpc_showHelp (errmsg); return False; } printf (" Histogramming mode = SQHM__TRANS\n"); nbuffs = 8; nbytes = 4096; printf (" Number buffers = %d\n", nbuffs); printf (" Buffer size = %d bytes\n", nbytes); } printf ("\nConnecting to SinqHM_srv via TCP/IP port %d ...\n", port); /*============================================================================ ** Create a TCP/IP socket for connecting to SinqHM_srv root and bind it. */ skt = socket (AF_INET, SOCK_STREAM, 0); if (skt == -1) sbpc_failInet ("\nSocket error."); lcl_sockname.sin_family = AF_INET; lcl_sockname.sin_port = htons (0); lcl_sockname.sin_addr.s_addr = 0; status = bind (skt, (struct sockaddr *) &lcl_sockname, sizeof (lcl_sockname)); if (status == -1) sbpc_failInet ("\nBind error."); /*============================================================================ ** Connect to SinqHM_srv root. */ rmt_sockname_len = sizeof (rmt_sockname); rmt_sockname.sin_family = AF_INET; rmt_sockname.sin_port = htons (port); rmt_sockname.sin_addr.s_addr = 0; /* Connect to local machine */ status = connect (skt, (struct sockaddr *) &rmt_sockname, sizeof (rmt_sockname)); if (status == -1) { sbpc_getErrno (&my_errno); sbpc_failInet ("\nConnect error"); } /*============================================================================ ** Set up and send the configure message. */ req_buff.bigend = htonl (0x12345678); req_buff.cmnd = htonl (SQHM_CONFIG); req_buff.u.cnfg.mode = htonl (hm_mode); if ((mode == SQHM__HM_DIG) || (mode == SQHM__HRPT)) { req_buff.u.cnfg.u.hm_dig.n_hists = htonl (nhists); req_buff.u.cnfg.u.hm_dig.lo_bin = htonl (lo_bin); req_buff.u.cnfg.u.hm_dig.num_bins = htonl (nbins); req_buff.u.cnfg.u.hm_dig.bytes_per_bin = htonl (bytes_per_bin); req_buff.u.cnfg.u.hm_dig.compress = htonl (compress); }else if (mode == SQHM__HM_PSD) { req_buff.u.cnfg.u.psd.n_extra_bytes = htonl (0); req_buff.u.cnfg.u.psd.n_edges = htons (1); req_buff.u.cnfg.u.psd.n_banks = htons (1); req_buff.u.cnfg.u.psd.xOffset = htonl (xOff); req_buff.u.cnfg.u.psd.yOffset = htonl (yOff); req_buff.u.cnfg.u.psd.xFactor = htonl (xFac); req_buff.u.cnfg.u.psd.yFactor = htonl (yFac); req_buff.u.cnfg.u.psd.xSize = htons (xSize); req_buff.u.cnfg.u.psd.ySize = htons (ySize); req_buff.u.cnfg.u.psd.edge_0.n_bins = htonl (1); req_buff.u.cnfg.u.psd.edge_0.flag = htonl (0); /* Fixed bin span */ req_buff.u.cnfg.u.psd.edge_0.edges[0] = htonl (0); req_buff.u.cnfg.u.psd.edge_0.edges[1] = htonl (10000); req_buff.u.cnfg.u.psd.preset_delay = htonl (0); req_buff.u.cnfg.u.psd.bank_0.first = htons (0); req_buff.u.cnfg.u.psd.bank_0.n_cntrs = htons (xSize*ySize); req_buff.u.cnfg.u.psd.bank_0.edge_indx = htons (0); req_buff.u.cnfg.u.psd.bank_0.bytes_per_bin = htons (4); }else if (mode == SQHM__TOF) { req_buff.u.cnfg.u.tof.n_extra_bytes = htonl (0); req_buff.u.cnfg.u.tof.n_edges = htons (1); req_buff.u.cnfg.u.tof.n_banks = htons (1); req_buff.u.cnfg.u.tof.edge_0.n_bins = htonl (nbins); req_buff.u.cnfg.u.tof.edge_0.flag = htonl (0); req_buff.u.cnfg.u.tof.edge_0.edges[0] = htonl (0); req_buff.u.cnfg.u.tof.edge_0.edges[1] = htonl (span); req_buff.u.cnfg.u.tof.preset_delay = htonl (delay); req_buff.u.cnfg.u.tof.bank_0.first = htons (lo_cntr); req_buff.u.cnfg.u.tof.bank_0.n_cntrs = htons (ncntrs); req_buff.u.cnfg.u.tof.bank_0.edge_indx = htons (0); req_buff.u.cnfg.u.tof.bank_0.bytes_per_bin = htons (bytes_per_bin); }else if (mode == SQHM__TRANS) { req_buff.u.cnfg.u.trans.n_buffs = htonl (nbuffs); req_buff.u.cnfg.u.trans.n_bytes = htonl (nbytes); } status = send (skt, (char *) &req_buff, sizeof (req_buff), 0); if (status == -1) sbpc_failInet ("\nSend error"); if (status != sizeof (req_buff)) { printf ("\nWrong number of bytes sent: %d", status); close (skt); return False; } /*============================================================================ ** Wait for the status response. */ bytes_to_come = sizeof (rply_buff); nxt_byte = (char *) &rply_buff; while (bytes_to_come > 0) { status = recv (skt, nxt_byte, bytes_to_come, 0); if (status == -1) { sbpc_failInet ("\nRecv error"); close (skt); return False; } else if (status <= 0) { printf ("Recv error - unexpected byte count: %d/%d\n", sizeof (rply_buff), status); close (skt); return False; } bytes_to_come = bytes_to_come - status; nxt_byte = nxt_byte + status; } if (ntohl (rply_buff.bigend) != 0x12345678) { printf ("Big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); close (skt); return False; } status = ntohl (rply_buff.status); if (status != KER__SUCCESS) { if (status == KER__BAD_CREATE) { printf ("Status response is KER__BAD_CREATE\n"); printf (" Sub-status = %d\n", ntohl (rply_buff.sub_status)); }else if (status == KER__BAD_STATE) { printf ("Status response is KER__BAD_STATE\n"); }else if (status == KER__BAD_VALUE) { printf ("Status response is KER__BAD_VALUE\n"); }else if (status == KER__BAD_RECV) { printf ("Status response is KER__BAD_RECV\n"); }else if (status == KER__BAD_ALLOC) { printf ("Status response is KER__BAD_ALLOC\n"); }else { printf ("Bad and unrecognised status response: 0x%x\n", status); } if (rply_buff.u.message[0] != '\0') { printf (" Message = \"%s\"\n", &rply_buff.u.message[0]); } close (skt); return False; } /* ** Close the connection. */ status = close (skt); if ((status != 0) && (errno != ECONNRESET)) sbpc_failInet ("\nClose error"); taskDelay (1 * sysClkRateGet ()); /* Wait for 1 second to let .. ** .. SinqHM_srv to do its printing. */ printf ("\nSinqHM_srv has been configured.\n"); return 1; } /* **--------------------------------------------------------------------------*/ int sbpc_doAction (char *action) { /* ============= */ int i, j, a_len, n_args, status, spnd_flg; char errmsg[100]; char *p_verb, *p_arg[MAX_ARGS], *p_nxt; for (i = 0; action[i] != '\0'; i++) action[i] = tolower (action[i]); for (i = 0; i < MAX_ARGS; i++) p_arg[i] = NULL; a_len = strlen (action); p_verb = strtok (action, "="); /* Get the action verb */ n_args = 0; for (i = 0; i < MAX_ARGS; i++) p_arg[i] = NULL; /* ** Now loop to get the args. ** Note: ** The loop does not use strtok since it wants to ** allow null arguments, i.e. adjacent commas may be ** used to indicate default args. This is not possible ** if one uses strtok. */ p_nxt = p_verb + strlen (p_verb) + 1; /* Get addr of start of args */ while ((n_args < MAX_ARGS) && ((p_nxt - action) < a_len)) { p_arg[n_args] = p_nxt; n_args++; i = strcspn (p_nxt, ","); /* Find next comma (or end of string) */ p_nxt[i] = NIL; /* Change it to a NIL */ p_nxt = p_nxt + i + 1; /* Move to next argement */ } if ((strcmp (p_verb, "sp") == 0) || (strcmp (p_verb, "sps") == 0)) { spnd_flg = 0; spnd_flg = (strcmp (p_verb, "sps") == 0) ? 1 : 0; if (n_args == 0) { sbpc_showHelp ("\"sp\" action has no arguments!"); return False; }else if (strcmp (p_arg[0], "bootutil") == 0) { status = sbpc_spawnBootUtil (spnd_flg, p_arg[1], p_arg[2], p_arg[3], p_arg[4]); if (!status) return status; }else if (strcmp (p_arg[0], "focus") == 0) { status = sbpc_spawnFocus (spnd_flg, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8]); if (!status) return status; }else if (strcmp (p_arg[0], "lwl") == 0) { status = sbpc_spawnLwl (spnd_flg, p_arg[1], p_arg[2], p_arg[3], p_arg[4]); if (!status) return status; }else if (strcmp (p_arg[0], "sinqhm") == 0) { status = sbpc_spawnSinqHM (spnd_flg, p_arg[1], p_arg[2], p_arg[3], p_arg[4]); if (!status) return status; }else { sprintf (errmsg, "\"%s\" is an unrecognised thing to spawn!\n", p_arg[0]); sbpc_showHelp (errmsg); return False; } }else if (strcmp (p_verb, "cfg") == 0) { if (n_args == 0) { sbpc_showHelp ("\"cfg\" action has no arguments!"); return False; }else if (strcmp (p_arg[0], "hm_dig") == 0) { status = sbpc_config (SQHM__HM_DIG, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8], p_arg[9]); if (!status) return status; }else if (strcmp (p_arg[0], "tof") == 0) { status = sbpc_config (SQHM__TOF, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8], p_arg[9]); if (!status) return status; }else if (strcmp (p_arg[0], "hm_psd") == 0) { status = sbpc_config (SQHM__HM_PSD, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8], p_arg[9]); if (!status) return status; }else if (strcmp (p_arg[0], "hrpt") == 0) { status = sbpc_config (SQHM__HRPT, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8], p_arg[9]); if (!status) return status; }else if (strcmp (p_arg[0], "trans") == 0) { status = sbpc_config (SQHM__TRANS, p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6], p_arg[7], p_arg[8], p_arg[9]); if (!status) return status; }else { sprintf (errmsg, "\"%s\" is an unrecognised thing to configure!\n", p_arg[0]); sbpc_showHelp (errmsg); return False; } }else if (strcmp (p_verb, "wt") == 0) { if (n_args == 0) { sbpc_showHelp ("\"wt\" action has no arguments!"); return False; }else if ((sscanf (p_arg[0], "%i", &i) != 1) || (i <= 0) || (i > 300)) { sprintf (errmsg, "The value for , \"%s\", is illegal!\n", p_arg[0]); sbpc_showHelp (errmsg); return False; } printf ("Waiting for %d secs ", i); for (j = 0; j < i; j++) { taskDelay (1 * sysClkRateGet ()); /* Wait as requested .. */ printf ("."); } printf ("\n"); }else { sprintf (errmsg, "\"%s\" is an unrecognised action!\n", p_verb); sbpc_showHelp (errmsg); return False; } return True; } /* **--------------------------------------------------------------------------*/ void sbpc_failInet (char *text) { /* ============= ** Output the given text and exit the process. */ int my_errno; sbpc_getErrno (&my_errno); printf ("### Internet Error ###\n"); printf (" ### errno = %d.\n", my_errno); perror (text); exit (EXIT_FAILURE); } /*--------------------------------------------------------------------------*/ void sbpc_getErrno (int *his_errno) { /* ============= */ *his_errno = errno; /* Make copy of errno */ return; } /* **--------------------------------------------------------------------------*/ void sbpc_showHelp (char *errmsg) { /* ============= */ if (errmsg != NULL) { printf ("\007\n%s\n", errmsg); taskDelay (5 * sysClkRateGet ()); /* Give user time to read message */ } printf ("\n" "The \"other\" field may be specified as follows:\n" "\n" " =,..,/=...\n" "\n" "There must be no white space characters in the string. The string may\n" "be specified in upper or lower case.\n" "\n" " may be \"sp\" for \"spawn a task\" or\n" " \"sps\" for \"spawn and suspend a task\" or\n" " \"cfg\" for \"configure SinqHM_srv (or FOCUS_srv)\"\n" "\n" "The following \"sp\" (or \"sps\") commands are available:\n" "\n" " a) sp=SinqHM,,,\n" " where\n" " = TCP/IP port number for server. Dflt=2400.\n" " = flag to indicate if timing levels should be\n" " generated via a VMIO10 module. If non-zero,\n" " timing levels are generated. Dflt=0.\n" " = base address of VMIO10 level-generator\n" " module. Dflt=0x1900.\n" " This action spawns the SinqHM histogram memory server task.\n" "\n" " b) sp=lwl,,,\n" " where\n" " = TCP/IP port number for server. Dflt=3501.\n" " = base address of VMIO10 test-generator\n" " module. Dflt=0x1800.\n" " = verbosity flag. If non-zero, the program is\n" " verbose. Dflt=0.\n" " This action spawns the lwl_server task which can be used to feed\n" " data packets into the hist memory fibre-optic (Licht-Wellen-Leiter)\n" " link via a VMIO10 test-generator. If the test generator is absent,\n" " the action can be omitted to avoid a boot-time error message.\n" "\n" " c) sp=bootUtil,\n" " where\n" " = TCP/IP port number for server. Dflt=2300.\n" "\n" "The following \"cfg\" commands are available:\n" "\n" " a) cfg=HM_DIG,<#-bins>,<#-hists>,,,\n" " where\n" " <#-bins> = number of bins per histogram. No default.\n" " <#-hists> = number of defined histograms. Dflt=1.\n" " = Number of bytes per bin. Dflt=4.\n" " = Bin compression factor. Dflt=1.\n" " = First bin. Dflt=0.\n" "\n" " b) cfg=TOF,<#-bins>,<#-cntrs>,,,\n" " where\n" " <#-bins> = number of bins per histogram. No default.\n" " <#-cntrs> = number of neutron counters. No default.\n" " = Number of bytes per bin. Dflt=4.\n" " = Bin compression factor. Dflt=1.\n" " = # of first counter. Dflt=0.\n" "\n" " c) cfg=HM_PSD,... same arguments as HM_DIG (for now).\n" "\n" "For example:\n" " other=\"sp=SinqHM/cfg=HM_DIG,400\"\n" "\n"); } /* **--------------------------------------------------------------------------*/ int sbpc_spawnBootUtil ( /* ================== */ int spnd_flg, /* Suspend flag (arg10) */ char *p_arg1, /* TCP/IP port number. Dflt = 2300 */ char *p_arg2, /* Not used */ char *p_arg3, /* Not used */ char *p_arg4) { /* Not used */ int port; int status; void SinqHM_bootUtil (void); /* Define template for SinqHM_bootUtil */ if (p_arg1 == NULL) { port = 2300; }else if (p_arg1[0] == NIL) { port = 2300; }else { if (sscanf (p_arg1, "%i", &port) != 1) { printf ("bootUtil has not been spawned: invalid argument \"%s\"\n", p_arg1); return False; } if (port <= 0) port = 2300; } printf ("Spawning bootUtil ..\n TCP/IP port = %d.\n", port); status = taskSpawn ("bootUtil", 100, VX_FP_TASK, 20000, (FUNCPTR) SinqHM_bootUtil, port, 0, 0, 0, 0, 0, 0, 0, 0, spnd_flg); if (status == ERROR) { printf ("\007\nSpawn of SinqHM_bootUtil failed!\n\n"); return False; } taskDelay (1 * sysClkRateGet ()); /* Give bootUtil time to get going */ return True; } /* **--------------------------------------------------------------------------*/ int sbpc_spawnFocus ( /* =============== */ int spnd_flg, /* Suspend flag (arg10) */ char *p_arg1, /* hostM */ char *p_arg2, /* #-cntrs for hostM */ char *p_arg3, /* hostO */ char *p_arg4, /* #-cntrs for hostO */ char *p_arg5, /* hostU */ char *p_arg6, /* #-cntrs for hostU */ char *p_arg7, /* Client side port number */ char *p_arg8) { /* Server side port number */ char *hostM, *hostO, *hostU; int ndetM, ndetO, ndetU, c_port, s_port; int status; char tsknam[32]; #ifndef FOCUS printf ("\n\"/sp=focus\" is only permitted on the FOCUS instrument!\n"); return False; #else void FOCUS_main (void); /* Define template for FOCUS_main */ hostM = (p_arg1 != NULL) ? p_arg1 : "localhost"; if (hostM[0] == NIL) hostM = "localhost"; if (p_arg2 == NULL) { ndetM = 150; }else if (p_arg2[0] == NIL) { ndetM = 150; }else { if ((sscanf (p_arg2, "%i", &ndetM) != 1) || (ndetM <= 0) || (ndetM > 1023)) { printf ("FOCUS_main has not been spawned: invalid argument \"%s\"\n", p_arg2); return False; } } hostO = (p_arg3 != NULL) ? p_arg3 : "lnse05.vme"; if (hostO[0] == NIL) hostO = "lnse05.vme"; if (p_arg4 == NULL) { ndetO = 117; }else if (p_arg4[0] == NIL) { ndetO = 117; }else { if ((sscanf (p_arg4, "%i", &ndetO) != 1) || (ndetO <= 0) || (ndetO > 1023)) { printf ("FOCUS_main has not been spawned: invalid argument \"%s\"\n", p_arg4); return False; } } hostU = (p_arg5 != NULL) ? p_arg5 : "lnse06.vme"; if (hostU[0] == NIL) hostU = "lnse06.vme"; if (p_arg6 == NULL) { ndetU = 116; }else if (p_arg6[0] == NIL) { ndetU = 116; }else { if ((sscanf (p_arg6, "%i", &ndetU) != 1) || (ndetU <= 0) || (ndetU > 1023)) { printf ("FOCUS_main has not been spawned: invalid argument \"%s\"\n", p_arg6); return False; } } if (p_arg7 == NULL) { c_port = 2500; }else if (p_arg7[0] == NIL) { c_port = 2500; }else { if ((sscanf (p_arg7, "%i", &c_port) != 1) || (c_port <= 1024) || (c_port > 65535)) { printf ("FOCUS_main has not been spawned: invalid argument \"%s\"\n", p_arg7); return False; } } if (p_arg8 == NULL) { s_port = 2400; }else if (p_arg8[0] == NIL) { s_port = 2400; }else { if ((sscanf (p_arg8, "%i", &s_port) != 1) || (s_port <= 1024) || (s_port > 65535)) { printf ("FOCUS_main has not been spawned: invalid argument \"%s\"\n", p_arg8); return False; } } printf ("Spawning FOCUS_main ..\n"); printf (" Mittel-bank: %3d cntrs, host = \"%s\"\n", ndetM, hostM); printf (" Ober-bank: %3d cntrs, host = \"%s\"\n", ndetO, hostO); printf (" Unter-bank: %3d cntrs, host = \"%s\"\n", ndetU, hostU); printf (" Client TCP/IP port = %d.\n", c_port); printf (" Server TCP/IP port = %d.\n", s_port); sprintf (tsknam, "Focus%04d", s_port); status = taskSpawn (tsknam, 100, VX_FP_TASK, 20000, (FUNCPTR) FOCUS_main, (long int) hostM, ndetM, (long int) hostO, ndetO, (long int) hostU, ndetU, c_port, s_port, 0, spnd_flg); if (status == ERROR) { printf ("\007\nSpawn of FOCUS_main failed!\n\n"); return False; } taskDelay (1 * sysClkRateGet ()); /* Give FOCUS_main time to get going */ return True; #endif } /* **--------------------------------------------------------------------------*/ int sbpc_spawnLwl ( /* ============= */ int spnd_flg, /* Suspend flag (arg10) */ char *p_arg1, /* TCP/IP port number. Dflt = 3501 */ char *p_arg2, /* Base addr of VMIO10 module. Dflt = 0x1800 */ char *p_arg3, /* Verbosity. Dflt = 0 */ char *p_arg4) { /* Not used */ int port, vmio_base, verbosity; int status; void lwl_server (void); /* Define template for lwl_server */ if (p_arg1 == NULL) { port = 3501; }else if (p_arg1[0] == NIL) { port = 3501; }else { if ((sscanf (p_arg1, "%i", &port) != 1) || (port < 0)) { printf ("lwl_server has not been spawned: invalid argument \"%s\"\n", p_arg1); return False; } if (port == 0) port = 3501; } if (p_arg2 == NULL) { vmio_base = 0x1800; }else if (p_arg2[0] == NIL) { vmio_base = 0x1800; }else { if (sscanf (p_arg2, "%i", &vmio_base) != 1) { printf ("lwl_server has not been spawned: invalid argument \"%s\"\n", p_arg2); return False; } } if (p_arg3 == NULL) { verbosity = 0; }else if (p_arg3[0] == NIL) { verbosity = 0; }else { if (sscanf (p_arg3, "%i", &verbosity) != 1) { printf ("lwl_server has not been spawned: invalid argument \"%s\"\n", p_arg3); return False; } } printf ("Spawning lwl_server ..\n TCP/IP port = %d.\n", port); printf (" VMIO10 base address = 0x%x\n", vmio_base); if (verbosity == 0) { printf (" Terse mode.\n"); }else { printf (" Verbose mode.\n"); } /* ** Note: lwlServer must have exactly the same priority as ** ==== the Filler task (hmFill2400). ** ** If the priority of lwlServer is lower that that of Filler, ** then lwlServer will never get to run because Filler only ** relinquishes the CPU via a "taskDelay (0)" and this only ** lets tasks of the same priority as Filler run. ** ** If the priority of lwlServer is higher that that of Filler, ** it is possible that the Filler gets blocked by lwlServer ** so that the LWL Fifo gets filled up and overflows. */ status = taskSpawn ("lwlServer", 250, VX_FP_TASK, 20000, (FUNCPTR) lwl_server, port, vmio_base, verbosity, 0, 0, 0, 0, 0, 0, spnd_flg); if (status == ERROR) { printf ("\007\nSpawn of lwl_Server failed!\n\n"); return False; } taskDelay (1 * sysClkRateGet ()); /* Give lwl_server time to get going */ return True; } /* **--------------------------------------------------------------------------*/ #ifdef MEN_A012 extern int Hist_base_MEN_alloc; #endif int sbpc_spawnSinqHM ( /* ================ */ int spnd_flg, /* Suspend flag (arg10) */ char *p_arg1, /* TCP/IP port number. Dflt = 2400 */ char *p_arg2, /* Use VMIO10 module if non-zero. Dflt = 0 */ char *p_arg3, /* Base addr of VMIO10 module. Dflt = 0x1900 */ char *p_arg4) { /* Not used */ int port, use_level_gen, vmio_base; int status; char tsknam[32]; void SinqHM_srv (void); /* Define template for SinqHM_srv */ if (p_arg1 == NULL) { port = 2400; }else if (p_arg1[0] == NIL) { port = 2400; }else { if ((sscanf (p_arg1, "%i", &port) != 1) || (port < 0)) { printf ("SinqHM has not been spawned: invalid argument \"%s\"\n", p_arg1); return False; } if (port == 0) port = 2400; } if (p_arg2 == NULL) { use_level_gen = 0; }else if (p_arg2[0] == NIL) { use_level_gen = 0; }else { if (sscanf (p_arg2, "%i", &use_level_gen) != 1) { printf ("SinqHM has not been spawned: invalid argument \"%s\"\n", p_arg2); return False; } } if (use_level_gen != 0) use_level_gen = 1; if (p_arg3 == NULL) { vmio_base = 0x1900; }else if (p_arg3[0] == NIL) { vmio_base = 0x1900; }else { if (sscanf (p_arg3, "%i", &vmio_base) != 1) { printf ("SinqHM has not been spawned: invalid argument \"%s\"\n", p_arg3); return False; } } #ifdef MEN_A012 /* make sure that the memory allocation flag is properly initialized at the first time */ Hist_base_MEN_alloc = 0; #endif printf ("Spawning SinqHM_srv ..\n TCP/IP port = %d.\n", port); if (use_level_gen == 0) { printf (" No timing signal generation requested.\n"); }else { printf (" Timing signal generation requested.\n"); printf (" VMIO10 base address = 0x%x\n", vmio_base); } sprintf (tsknam, "hmRoot%04d", port); status = taskSpawn (tsknam, 100, VX_FP_TASK, 20000, (FUNCPTR) SinqHM_srv, port, use_level_gen, vmio_base, 0, 0, 0, 0, 0, 0, spnd_flg); if (status == ERROR) { printf ("\007\nSpawn of SinqHM_srv failed!\n\n"); return False; } taskDelay (1 * sysClkRateGet ()); /* Give SinqHM_srv time to get going */ return True; } /* **============================================================================== ** ** Main line program ** **============================================================================*/ int SinqHM_bootParamsConfig () { /* ======================= */ char *local_mem, *p_item; BOOT_PARAMS my_params; int i, n_actions, status; char *action_token[MAX_ACTIONS]; char recd[132]; /*============================================================================ ** Perform the initialisation of variables ... */ local_mem = (char *) BOOT_LINE_ADRS; /* Get pointer to the boot line */ /*============================================================================ */ bootStringToStruct (local_mem, &my_params); /* Parse boot line */ /* ** Parse the "other" string */ if (my_params.other[0] == '\0') { printf ("\n" "There is no \"other\" field defined in the boot line.\n" "SinqHM_srv will not be automatically configured!\n"); sbpc_showHelp (NULL); return True; } printf ("\nParsing the \"other\" field defined in the boot line\n\n" " Other = \"%s\"\n\n", my_params.other); /* ** Start by splitting up into "/" terminated strings. ** These are "actions". */ n_actions = 0; p_item = strtok (my_params.other, "/"); while ((n_actions < MAX_ACTIONS) && (p_item != NULL)) { action_token[n_actions] = p_item; n_actions++; p_item = strtok (NULL, "/"); /* Get the next action token */ } /* ** Now process the actions in order. */ for (i = 0; i < n_actions; i++) { status = sbpc_doAction (action_token[i]); if (!status) return status; } return True; } /*================================= End of SinqHM_bootParamsConfig.c ========*/