Changeset 183 for hvcontrol


Ignore:
Timestamp:
03/12/10 15:54:15 (15 years ago)
Author:
ogrimm
Message:
Various updates
Location:
hvcontrol
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • hvcontrol/hvcontrol.cpp

    r161 r183  
    1414#include <pthread.h>
    1515#include <signal.h>
    16 #include <sys/socket.h>
    17 #include <netdb.h>
    18 #include <arpa/inet.h>
    1916
    2017#include "ProcessIO.h"
     
    2320#include <readline/history.h>
    2421
    25 #define DEFAULT_CONFIG "../config/HV.conf"     // Default configuration file
    2622#define LOCKFILE "/tmp/CTX_HV_LOCK"
    2723
    2824// Function prototypes
    2925void ConsoleCommand(ProcessIO *);
    30 void CCCommand(ProcessIO *);
    3126void HVMonitor(ProcessIO *);
    3227void DummyHandler(int);
     
    4338
    4439  char str[MAX_COM_SIZE];
    45   pthread_t thread_ConsoleCommand,thread_HVMonitor,thread_CCCommand;
     40  pthread_t thread_ConsoleCommand,thread_HVMonitor;
    4641  int LockDescriptor;
    47 
    48   // Interpret command line (do before lockfile creation in case of exit())
    49   if((argc==3 && strcmp(argv[1],"-c")!=0) || argc==2) {
    50     printf("Usage: %s [-c <ConfigFile>]    Default file is \"%s\"\n", argv[0], DEFAULT_CONFIG);
    51     exit(EXIT_SUCCESS);
    52   }
    5342
    5443  // Assure only one instance of the HV control program runs
     
    6958 
    7059  system("clear");                   
    71   printf("\n*** HV Control built %s, %s (S.Commichau, S.Stark, O.Grimm) ***\n\n",__DATE__,__TIME__);
     60  printf("\n*** Bias control (%s, %s, O. Grimm, S.Commichau, S.Stark) ***\n\n",__DATE__,__TIME__);
    7261 
    7362  // Install signal handler and set signal SIGUSR1 to interrupt blocking system calls
     
    8473 
    8574  // Construct main instance and create mutex for thread synchronization
    86   ProcessIO pio(argc==3 ? argv[2] : DEFAULT_CONFIG);
     75  ProcessIO pio;
    8776  if (pthread_mutex_init(&pio.control_mutex, NULL) != 0) {
    8877    perror("pthread_mutex_init failed");
     
    10594    throw;
    10695  }
    107   if ((pthread_create(&thread_CCCommand, NULL, (void * (*)(void *)) CCCommand,(void *) &pio)) != 0) {
    108     perror("pthread_create failed with socket thread");
    109     throw;
    110   }
    11196
    11297  // Threads should be accessible for sending signals
    11398  pio.HVMonitor = thread_HVMonitor;
    114   pio.SocketThread = thread_CCCommand;
    11599
    116100  // Wait for threads to quit
    117   pthread_join(thread_CCCommand, NULL);
    118101  pthread_join(thread_ConsoleCommand, NULL);
    119102  pthread_join(thread_HVMonitor, NULL);
     
    169152    if(strlen(Command)>0) add_history(Command);
    170153
    171     // Log command
    172     m->PrintMessage(Log, "CONSOLE> %s\n", Command);
    173 
    174     // Process command     
    175     pthread_mutex_lock(&m->control_mutex);
    176     m->CommandControl(Command);
    177     pthread_mutex_unlock(&m->control_mutex);
    178          
     154    // Process command (via DIM gives automatic serialisation)
     155        DimClient::sendCommand("Bias/Command", Command);
    179156    free(Command);
    180157  }
    181 }
    182 
    183 
    184 /********************************************************************\
    185 
    186   CCCommand thread
    187 
    188   Listen to commands from socket (Central Control)
    189  
    190   This thread will block execution in the accept() and read() socket function
    191   while waiting for a connection or data. If the exit function is invoked through
    192   keyboard command, these blocking functions are interrupted by raising the signal
    193   SIGUSR1. Testing on errno=EINTR indicates this termination. The dummy signal
    194   handler below is needed to prevent the standard thread termination occurring
    195   when this signal is received.
    196  
    197 \********************************************************************/
    198 
    199 
    200 void CCCommand(ProcessIO *m) {
    201 
    202   int ServerSocket,ConnectionSocket,ReadResult;
    203   struct sockaddr_in SocketAddress, ClientAddress;
    204   struct hostent *ClientName;
    205   socklen_t SizeClientAddress=sizeof(ClientAddress);
    206   char Command[MAX_COM_SIZE];
    207 
    208   // Set up server socket
    209   if ((ServerSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
    210     m->PrintMessage(All, "Could not open server socket, no remote connection possible (%s).\n", strerror(errno));
    211     return;
    212   }
    213 
    214   // Allows immediate reuse of socket after closing (circumvents TIME_WAIT)
    215   int Value=1;
    216   if (setsockopt(ServerSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &Value, sizeof (Value)) == -1) {
    217     m->PrintMessage(All, "Warning: Could not set server socket option SO_REUSEADDR (%s)\n", strerror(errno));
    218   }
    219 
    220   SocketAddress.sin_family = PF_INET;
    221   SocketAddress.sin_port = htons((unsigned short) m->fCCPort);
    222   SocketAddress.sin_addr.s_addr = INADDR_ANY;
    223 
    224   if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
    225     m->PrintMessage(All, "Could not bind port to socket (%s)\n", strerror(errno));
    226     close(ServerSocket);
    227     return;
    228   }
    229   if (listen(ServerSocket, 0) == -1) {
    230     m->PrintMessage(All, "Could not set socket to listening (%s)\n", strerror(errno));
    231     close(ServerSocket);
    232     return;
    233   }
    234  
    235   while (!m->Exit) { // Looping to wait for incoming connection
    236 
    237     if ((ConnectionSocket = accept(ServerSocket, (struct sockaddr *) &ClientAddress, &SizeClientAddress)) == -1) {
    238       if (errno!=EINTR) m->PrintMessage(All, "Failed to accept incoming connection (%s)\n", strerror(errno));
    239       close(ServerSocket);
    240       return;
    241     }
    242 
    243     ClientName = gethostbyaddr((char *) &ClientAddress.sin_addr ,sizeof(struct sockaddr_in),AF_INET);
    244     m->PrintMessage(All, "Connected to client at %s (%s).\n", inet_ntoa(ClientAddress.sin_addr), ClientName!=NULL ? ClientName->h_name:"name unknown");
    245     m->Socket = ConnectionSocket;
    246 
    247     // Looping as long as client exists and program not terminated
    248     while (!m->Exit) {
    249 
    250       // Try to read command from socket
    251       memset(Command, 0, sizeof(Command));
    252       ReadResult = read(ConnectionSocket, Command, MAX_COM_SIZE);
    253       if (ReadResult==0) break; // Client does not exist anymore
    254       if (ReadResult==-1) {
    255                 if (errno!=EINTR) m->PrintMessage(All, "Error read from socket (%s)\n", strerror(errno));
    256                 break;
    257       }
    258       if (Command[strlen(Command)-1]=='\n') Command[strlen(Command)-1]='\0';  // Remove trailing newline
    259      
    260       // Log command
    261       //m->PrintMessage(Console, "SOCKET> %s\n", Command);
    262       //m->PrintMessage(Log, "SOCKET> %s\n", Command);
    263            
    264       // Process command
    265       pthread_mutex_lock(&m->control_mutex);
    266       m->CmdFromSocket = true;
    267       m->CommandControl(Command);
    268       m->CmdFromSocket = false;
    269       pthread_mutex_unlock(&m->control_mutex); 
    270     }
    271 
    272     m->Socket = -1;
    273     m->PrintMessage(All, "Disconnected from client.\n");
    274     close(ConnectionSocket);
    275   }
    276   close(ServerSocket);
    277158}
    278159
  • hvcontrol/src/HV.cc

    r161 r183  
    3030  Name = new DimService (Buffer, BoardName);
    3131
    32   for (int i=0; i<NUM_CHAINS; i++) {
    33     for (int j=0; j<NUM_CHANNELS; j++) {
    34       snprintf(Buffer, sizeof(Buffer), SERVER_NAME"/VOLT/ID%.2d/%.2d-%.3d", BoardNumber, i, j);
    35       BiasVolt[i][j] = new DimService (Buffer, HVV[i][j]);
    36     }
    37     Overcurrent[i] = false;
    38   }
     32  snprintf(Buffer, sizeof(Buffer), SERVER_NAME"/VOLT/ID%.2d", BoardNumber);
     33  BiasVolt = new DimService (Buffer, "D", HVV, NUM_CHAINS*NUM_CHANNELS*sizeof(double));
     34
     35  for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i] = false;
    3936  ResetButton = false;
    4037  WrapOK = true;
     
    8784
    8885  delete Name;
    89   for (int i=0; i<NUM_CHAINS; i++) {
    90     for (int j=0; j<NUM_CHANNELS; j++) {
    91       delete BiasVolt[i][j];
    92     }
    93   }
     86  delete BiasVolt;
    9487}
    9588
     
    202195    for (int k=0; k<NUM_CHANNELS; k++){
    203196      HV[j][k] = 0;
    204       HVV[j][k] = 0.0;
    205      
    206       // Update DIM services
    207       BiasVolt[j][k]->updateService();
     197      HVV[j][k] = 0.0;     
    208198    }
    209199  }
     200  // Update DIM services
     201  BiasVolt->updateService();
    210202}
    211203
  • hvcontrol/src/HV.h

    r161 r183  
    5555
    5656   DimService *Name;
    57    DimService *BiasVolt[NUM_CHAINS][NUM_CHANNELS];
     57   DimService *BiasVolt;
    5858
    5959   void ClearVoltageArrays();
  • hvcontrol/src/ProcessIO.cc

    r161 r183  
    1414static char* state_str[]    = {"active", "stopped", "n.a."};
    1515
    16 
    17 ProcessIO::ProcessIO(const char *ConfigFile):
     16ProcessIO::ProcessIO():
    1817            DimCommand((char *) SERVER_NAME"/Command", (char *) "C"),
    1918            EvidenceServer(SERVER_NAME) {
     
    2423  // Create DIM text output service
    2524  Textout = new DimService (SERVER_NAME"/Textout", (char *) "");
     25  UpdateDelay = 0.0;
    2626
    2727  // Initialize status variables
    2828  state     = active;
    2929  Exit      = false;
    30   CmdFromSocket = false;
    31   Socket    = -1;
    3230 
    3331  NumHVBoards = 0;
     
    3836
    3937  // Get configuration data
    40   char *Boards = GetConfig(SERVER_NAME " Boards");
    41   fPixMapTable = GetConfig(SERVER_NAME " PixMapTable");
    42   fTimeOut = atof(GetConfig(SERVER_NAME " TimeOut"));
    43   fStatusRefreshRate = atof(GetConfig(SERVER_NAME " StatusRefreshRate"));
    44   fCCPort = atoi(GetConfig(SERVER_NAME " CCPort"));
    45   DACMin = atoi(GetConfig(SERVER_NAME " DACMin"));
    46   DACMax = atoi(GetConfig(SERVER_NAME " DACMax"));
    47   fHVCalibOffset = atof(GetConfig(SERVER_NAME " HVCalibOffset"));
    48   fHVCalibSlope = atof(GetConfig(SERVER_NAME " HVCalibSlope"));
    49   fHVMaxDiff = atoi(GetConfig(SERVER_NAME " HVMaxDiff"));
     38  char *Boards = GetConfig("Boards");
     39  fPixMapTable = GetConfig("PixMapTable");
     40  fTimeOut = atof(GetConfig("TimeOut"));
     41  fStatusRefreshRate = atof(GetConfig("StatusRefreshRate"));
     42  DACMin = atoi(GetConfig("DACMin"));
     43  DACMax = atoi(GetConfig("DACMax"));
     44  fHVCalibOffset = atof(GetConfig("HVCalibOffset"));
     45  fHVCalibSlope = atof(GetConfig("HVCalibSlope"));
     46  fHVMaxDiff = atoi(GetConfig("HVMaxDiff"));
    5047
    5148  if (fStatusRefreshRate < MIN_RATE || fStatusRefreshRate > MAX_RATE)  fStatusRefreshRate = 1;
     
    164161    PrintMessage( " TimeOut:           %.2f s\n"
    165162                  " StatusRefreshRate: %.2f Hz\n"
    166                   " CCPort:            %d\n"
    167163                  " DACMin value:      %d\n"
    168164                  " DACMax value:      %d\n"
     
    170166                  " HVCalibSlope :     %f\n"
    171167                  " HVMaxDiff :        %u\n", fTimeOut,
    172                   fStatusRefreshRate, fCCPort, DACMin,
     168                  fStatusRefreshRate, DACMin,
    173169                  DACMax, fHVCalibOffset, fHVCalibSlope,
    174170                  fHVMaxDiff);
     
    182178    PrintMessage(" board <i>|<i> <j>|<all>           Address board i, boards i-j or all boards or list boards\n"
    183179        " chain <i>|<i> <j>|<all>           Address chain i, chains i-j or all chains\n"
    184         " hv <PXL id>|<ch>|<all> <v>        Set bias of pixel ID, ch. or all ch. of active chain(s)/board(s)\n"
    185         " hvdiff <PXL id>|<ch>|<all> <diff> Change bias by <diff>\n"
     180        " hv <PXL id>|<ch>|<all> <v>        Set/change bias of pixel, ch. or all ch. of active chain(s)/board(s)\n"
    186181                " status [dac]                      Show status information (DAC values if requested)\n"
    187182                " config                            Print configuration\n"
     
    204199  // Set new bias voltage (if no boards available, simply returns OK)
    205200  // First reponse to socket should be 'OK' if no error occurred.
    206   if (Match(Param[0], "hv") || Match(Param[0], "hvdiff")) {
     201  if (Match(Param[0], "hv")) {
    207202
    208203    int hvoltage, DACValue, Errors=0, Board=-1, Chain=-1, Channel=-1;
     
    212207    // Need two or parameters
    213208    if (NParam<3 || NParam>4) {
    214       PrintMessage("Usage: hv/hvdiff <channel>|<all> <voltage> [dac]\n");
     209      PrintMessage("Usage: hv <channel>|<all> <voltage> [dac]\n");
    215210      return;
    216211    }
     
    250245          if (k!=Channel && Channel!=-1) continue;
    251246
    252           // hvdiff is ignored if DAC value is zero
    253           if ((strlen(Param[0])>2 || isdigit(*Param[2])==0) && (fHVBoard[i]->HV[j][k] == 0)) continue;
     247          // Voltage change ignored if DAC value is zero
     248          if (isdigit(*Param[2])==0 && fHVBoard[i]->HV[j][k] == 0) continue;
    254249
    255250          // Determine new DAC values
    256251          if (!SetDac){
    257                 if (strlen(Param[0])>2 || isdigit(*Param[2])==0) fHVBoard[i]->HVV[j][k] += hvoltageV; // hvdiff
     252                if (isdigit(*Param[2])==0) fHVBoard[i]->HVV[j][k] += hvoltageV; // voltage change
    258253            else fHVBoard[i]->HVV[j][k] = hvoltageV;
    259254            DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
    260255          }
    261256          else {
    262             if(strlen(Param[0])>2 || isdigit(*Param[2])==0) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // hvdiff
     257            if (isdigit(*Param[2])==0) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // voltage change
    263258            else DACValue = hvoltage;
    264259          }
     
    269264
    270265      // Update DIM services
    271       fHVBoard[i]->BiasVolt[j][k]->updateService();
    272 
     266      //fHVBoard[i]->BiasVolt[j][k]->updateService();
     267          UpdateDelay = 1.0;
    273268        } // Channels   
    274269    } // Chains
    275270    } // Boards
    276271
    277     if (Errors > 0) PrintMessage("ERROR - Errors on %d channel(s) occurred\n", Errors);
    278     else PrintMessage("OK - no errors\n");
     272    if (Errors > 0) PrintMessage("Errors on %d channel(s) occurred\n", Errors);
    279273   
    280274    return;
     
    318312
    319313            // Update DIM services
    320             fHVBoard[Board]->BiasVolt[Chain][Channel]->updateService();
    321 
     314            //fHVBoard[Board]->BiasVolt[Chain][Channel]->updateService();
     315                UpdateDelay = 1.0;
    322316            if(++Channel == NUM_CHANNELS) {
    323317              Chain++;
     
    440434    PrintMessage("\n Status monitor: %s\n", state_str[state]);
    441435    PrintMessage(" Status refresh rate [Hz]: %.2f\n", fStatusRefreshRate);
    442     PrintMessage(" Socket state: %s\n", Socket==-1 ? "disconnected":"connected");
    443436    PrintMessage(" Total number of boards: %d\n", NumHVBoards);
    444437    PrintMessage(" Active boards: %d\n\n", LastBoard - FirstBoard + 1);
     
    519512  else if(Match(Param[0], "exit")) {
    520513
    521     if (CmdFromSocket) {
    522       PrintMessage("Exit command not allowed over socket.\n");
    523       return;
    524     }   
    525 
    526514    Exit = true;
    527     pthread_kill(HVMonitor, SIGUSR1);
    528     pthread_kill(SocketThread, SIGUSR1);
    529  
     515    pthread_kill(HVMonitor, SIGUSR1);
    530516    return;
    531517  }
     
    549535  va_list ArgumentPointer;
    550536  va_start(ArgumentPointer, Format);
    551   if (CmdFromSocket) DoPrintMessage(Format, ArgumentPointer, Client);
    552   else DoPrintMessage(Format, ArgumentPointer, Console);
     537  DoPrintMessage(Format, ArgumentPointer, Console);
    553538  va_end(ArgumentPointer);
    554539}
     
    575560  Textout->updateService(Textbuffer);
    576561
    577   // Print to socket
    578   if((Target & Client) && Socket!=-1) {
    579     write(Socket, Textbuffer, strlen(Textbuffer));
    580   }
    581 
    582562  // Send to log
    583563  if(Target & Log) {
    584564    char *Buf;
    585565    if (asprintf(&Buf, "%s %s", SERVER_NAME, Textbuffer) != -1) {
    586       DimClient::sendCommand("DColl/Log", Buf);
     566      DimClient::sendCommandNB("DColl/Log", Buf);
    587567      free(Buf);
    588568    }
    589     else DimClient::sendCommand("DColl/Log", SERVER_NAME" asprintf() failed");
     569    else DimClient::sendCommandNB("DColl/Log", SERVER_NAME" asprintf() failed");
    590570  }
    591571}
     
    648628      }
    649629    }
    650    
     630  }
     631
     632  if (UpdateDelay >= 0) {
     633        UpdateDelay -= 1.0/(NumHVBoards*fStatusRefreshRate);
     634        if (UpdateDelay <= 0) for (int i=0; i<NumHVBoards; i++) {
     635          fHVBoard[i]->BiasVolt->updateService();
     636        }
    651637  }
    652638}
     
    700686
    701687//
    702 // Command handling (the only command is 'BIAS/Command')
     688// Command handling (the only command is 'Bias/Command')
    703689//
    704690void ProcessIO::commandHandler() {
    705691
    706     // Log command
    707     PrintMessage(Log, "DIM> %s\n", getString());
    708 
    709     // Process command     
    710692    pthread_mutex_lock(&control_mutex);
    711693    CommandControl(getString());
  • hvcontrol/src/ProcessIO.h

    r161 r183  
    2828#define MAX_NUM_TOKEN 10
    2929
    30 enum MsgTarget {Console=1, Log=2, Client=4, All=7};
     30enum MsgTarget {Console=1, Log=2, All=7};
    3131typedef enum stateenum {active, stopped, na} state_enum;
    3232
     
    3636  PixelMap *pm;
    3737  DimService *Textout;
    38  
     38  float UpdateDelay;
     39
    3940  void commandHandler();
    4041
    4142 public:
    42  
    43   //HVConfig    *config;
     43
    4444  HVCalib     *calib;
    4545  HVBoard **fHVBoard;
     
    5050  const char *Param[MAX_NUM_TOKEN]; // For parser
    5151  int NParam;
    52   bool CmdFromSocket;
    5352
    5453  // Configuration data
     
    5655  float fTimeOut;
    5756  float fStatusRefreshRate;
    58   int fCCPort;
    5957  int DACMin;
    6058  int DACMax;
     
    6563  // Status variables 
    6664  pthread_t HVMonitor;       // exit function sends signal to these threads
    67   pthread_t SocketThread;
    6865 
    69   int Socket;                // -1 if not connected
    70 
    7166  int NumHVBoards;
    7267  int FirstBoard;
     
    7974   
    8075  // Methods
    81   ProcessIO(const char *);
     76  ProcessIO();
    8277  ~ProcessIO();
    8378
Note: See TracChangeset for help on using the changeset viewer.