From b8e66289bae4e49901c54e2e78fabb4474a9f4d8 Mon Sep 17 00:00:00 2001 From: cvs Date: Mon, 6 Nov 2000 13:05:08 +0000 Subject: [PATCH] *** empty log message *** --- sinqhm/sinqhm_bootparamsconfig.c | 986 +++++++++++++++++++++++++++++++ 1 file changed, 986 insertions(+) create mode 100755 sinqhm/sinqhm_bootparamsconfig.c diff --git a/sinqhm/sinqhm_bootparamsconfig.c b/sinqhm/sinqhm_bootparamsconfig.c new file mode 100755 index 00000000..2e37d444 --- /dev/null +++ b/sinqhm/sinqhm_bootparamsconfig.c @@ -0,0 +1,986 @@ +#define IDENT "1B09" +/* +** +--------------------------------------------------------------+ +** | 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" + **---------------------------------------------------- + ** If = "sp" or "sps", then + ** + ** = name of task to spawn. This may be: + ** "SinqHM" for SinqHM_srv or + ** "lwl" for lwl_server. + ** "bootUtil" for SinqHM_bootUtil. + ** ,.. = 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). + ** + ** 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. + ** 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. + **---------------------------------------------------- + ** 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" + +#if (CPU == PPC603) +#include "../config/mv1603/config.h" +#elif (CPU == PPC604) +#include "../config/mv1603/config.h" +#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 port, int mode, + char *a1, char *a2, char *a3, + char *a4, char *a5, char *a6); + 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_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 port, + int mode, + char *p_arg1, + char *p_arg2, + char *p_arg3, + char *p_arg4, + char *p_arg5, + char *p_arg6) { + char errmsg[128]; + int i, nbins, nhists, ncntrs, bytes_per_bin, compress; + int lo_bin, lo_cntr, span, delay, status, my_errno; + int hm_mode, nbuffs, nbytes; + char *arg4_txt; + + 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 ((port < 128) || (port > 32767)) { + printf (" ... SinqHM_srv is not running!\n"); + 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; + + 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) { + /* SQHM__HM_PSD still needs to be programmed */ + printf (" Histogramming mode = SQHM__HM_PSD\n"); + printf (" Not yet supported!\n"); + return False; + }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.hm_dig.n_hists = htonl (1); + req_buff.u.cnfg.u.hm_dig.lo_bin = htonl (0); + req_buff.u.cnfg.u.hm_dig.num_bins = htonl (1024); + req_buff.u.cnfg.u.hm_dig.bytes_per_bin = htonl (4); + req_buff.u.cnfg.u.hm_dig.compress = htonl (0); + }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"); + } +/* +**--------------------------------------------------------------------------*/ + int sbpc_doAction (char *action) { +/* ============= +*/ + int i, 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], "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 (Port_base, SQHM__HM_DIG, + p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6]); + if (!status) return status; + }else if (strcmp (p_arg[0], "tof") == 0) { + status = sbpc_config (Port_base, SQHM__TOF, + p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6]); + if (!status) return status; + }else if (strcmp (p_arg[0], "hm_psd") == 0) { + status = sbpc_config (Port_base, SQHM__HM_PSD, + p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6]); + if (!status) return status; + }else if (strcmp (p_arg[0], "hrpt") == 0) { + status = sbpc_config (Port_base, SQHM__HRPT, + p_arg[1], p_arg[2], p_arg[3], p_arg[4], p_arg[5], p_arg[6]); + if (!status) return status; + }else { + sprintf (errmsg, "\"%s\" is an unrecognised thing to configure!\n", + p_arg[0]); + sbpc_showHelp (errmsg); + return False; + } + }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\"\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_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; + } +/* +**--------------------------------------------------------------------------*/ + 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; + } + } + + 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 ========*/