Changeset 226 for hvcontrol/src


Ignore:
Timestamp:
06/18/10 12:25:29 (15 years ago)
Author:
ogrimm
Message:
Small changes to mutex handling in hvcontrol and drsdaq
Location:
hvcontrol/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • hvcontrol/src/ProcessIO.cc

    r220 r226  
    2222  } CommandList[] =
    2323   {{"board", &ProcessIO::cmd_board, 1, "<i>|<i j>|<all>" ,"Address board i, boards i-j or all boards or list boards"},
    24         {"chain", &ProcessIO::cmd_chain, 1, "<i>|<i> <j>|<all>","Address chain i, chains i-j or all chains"},
    25         {"hv", &ProcessIO::cmd_hv, 2, "<id>|<ch>|<all> <v>", "Change bias of pixel, ch. or all ch. of active chain(s)/board(s)"},
     24        {"hv", &ProcessIO::cmd_hv, 2, "<id>|<ch>|<all> <v>", "Change bias of pixel or (all) chan. of active boards"},
    2625        {"status", &ProcessIO::cmd_status, 0, "[dac]", "Show status information (DAC values if requested)"},
    2726        {"config", &ProcessIO::cmd_config, 0, "", "Print configuration"},
     
    4039using namespace std;
    4140
     41
     42// Constructor
    4243ProcessIO::ProcessIO(): EvidenceServer(SERVER_NAME) {
    4344
     
    4647
    4748  // Initialize status variables
    48   state     = active;
    49   Exit      = false;
    50  
     49  state       = active;
     50  ConsoleText = NULL;
     51
    5152  NumHVBoards = 0;
    5253  FirstBoard  = 0;
    5354  LastBoard   = -1;
    54   FirstChain  = 0;
    55   LastChain   = NUM_CHAINS-1;
     55
     56  // Initialize mutex for thread synchronisation
     57  if (pthread_mutex_init(&Mutex, NULL) != 0) {
     58    Message(FATAL, "pthread_mutex_init() failed");
     59  }
     60
     61  // DIM console service used in PrintMessage()
     62  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
    5663
    5764  // Get configuration data
     
    94101
    95102
     103// Destructor
    96104ProcessIO::~ProcessIO() {
    97105 
     
    101109  delete[] fHVBoard;
    102110   
    103   delete pm;        delete calib;
     111  delete pm;
     112  delete calib;
     113  delete ConsoleOut;   
     114  free(ConsoleText);
     115 
     116  // Destroy mutex
     117  if (pthread_mutex_destroy(&Mutex) != 0) Message(ERROR, "pthread_mutex_destroy() failed");
    104118}
    105119
     
    180194}
    181195
    182 // Adress chains
    183 void ProcessIO::cmd_chain() {
    184    
    185   if (!NumHVBoards) return;
    186 
    187   if (Match(Parameter[1],"all")) {
    188     FirstChain = 0;
    189     LastChain = 3;
    190   }
    191   else if (Parameter.size()==2 && atoi(Parameter[1].c_str())>=0 && atoi(Parameter[1].c_str())<NUM_CHAINS) {
    192     FirstChain = atoi(Parameter[1].c_str());
    193     LastChain = FirstChain;
    194   }
    195   else if (Parameter.size()==3 && atoi(Parameter[1].c_str())>=0 && atoi(Parameter[1].c_str())<NUM_CHAINS &&
    196          atoi(Parameter[2].c_str())>0 && atoi(Parameter[2].c_str())<NUM_CHAINS) {
    197     FirstChain = atoi(Parameter[1].c_str());
    198     LastChain = atoi(Parameter[2].c_str());
    199   }
    200   else PrintMessage("Cannot address chain(s), out of range.\n");
    201 }
    202196
    203197// Print configuration
     
    209203  for (int i=0; i<NumHVBoards; i++) PrintMessage(" Board %d: %s\n", i, fHVBoard[i]->BoardName);
    210204
    211   PrintMessage( " TimeOut:           %.2f s\n"
    212                 " StatusRefreshRate: %.2f Hz\n"
     205  PrintMessage( " StatusRefreshRate: %.2f Hz\n"
    213206                " DACMin value:      %d\n"
    214207                " DACMax value:      %d\n"
     
    216209                " HVCalibSlope :     %f\n"
    217210                " HVMaxDiff :        %u\n",
    218                 fTimeOut, fStatusRefreshRate, DACMin,
     211                fStatusRefreshRate, DACMin,
    219212                DACMax, fHVCalibOffset, fHVCalibSlope, fHVMaxDiff);
    220213}
     
    236229void ProcessIO::cmd_hv() {
    237230
    238   int hvoltage, DACValue, Errors=0, Board=-1, Chain=-1, Channel=-1;
    239   double hvoltageV;
     231  int Int, SingleChannel;
     232  unsigned int DACValue, Errors=0;
     233  double Double;
    240234  bool SetDac;
    241235
    242   // If array of channels, evaluate here (used by DIM)
    243   if (Parameter.size()>3 && pm->Pixel_to_HVboard(Parameter[3]) != 999999999) {
    244         for (unsigned int n=1; n<Parameter.size()-1; n+=2) {
    245           if (pm->Pixel_to_HVboard(Parameter[n]) != 999999999) {
    246         Board = pm->Pixel_to_HVboard(Parameter[n]);
    247         Chain = pm->Pixel_to_HVchain(Parameter[n]);
    248         Channel = pm->Pixel_to_HVchannel(Parameter[n]);
    249                 hvoltageV = atof(Parameter[n+1].c_str());
    250                 if (isdigit(Parameter[n+1][0])==0) fHVBoard[Board]->HVV[Chain][Channel] += hvoltageV;
    251             else fHVBoard[Board]->HVV[Chain][Channel] = hvoltageV;
    252             DACValue = calib->HVToDAC(fHVBoard[Board]->HVV[Chain][Channel], Board, Chain, Channel);
    253 
    254           }
    255         }       
    256     return;
    257   }
    258 
    259   // Evaluate voltage parameter
    260   if (Parameter.size()==4 && Match(Parameter[3], "dac")) {
    261     SetDac = true;
    262     if (!ConvertToInt(Parameter[2], &hvoltage)) {
    263       PrintMessage("Error: Wrong number format for DAC voltage setting\n");
    264       return;
    265     }
    266   }
    267   else {
    268     SetDac = false;
    269     if (!ConvertToDouble(Parameter[2], &hvoltageV)) {
    270       PrintMessage("Error: Wrong number format for voltage setting\n");
    271       return;
    272     }
    273   }
    274 
    275   // Evaluate pixel or channel parameter   
    276   if(pm->Pixel_to_HVboard(Parameter[1]) != 999999999) {
    277     Board = pm->Pixel_to_HVboard(Parameter[1]);
    278     Chain = pm->Pixel_to_HVchain(Parameter[1]);
    279     Channel = pm->Pixel_to_HVchannel(Parameter[1]);
    280   }
    281   else if (!Match(Parameter[1], "all") && !ConvertToInt(Parameter[1], &Channel)) {
    282     PrintMessage("Error: Wrong channel identification\n");
    283     return;
    284   }
    285 
     236  // Interpretation as DAC value requested?
     237  if (Parameter.size() == 4 && Match(Parameter[3], "dac")) SetDac = true;
     238  else SetDac = false;
     239
     240  // Interprete first number (might be channel number)
     241  if (!ConvertToInt(Parameter[1], &SingleChannel)) SingleChannel = -1;
     242
     243  // Loop over all boards
    286244  for (int i=FirstBoard; i<=LastBoard; i++) {
    287     if (i!=Board && Board!=-1) continue;
    288   for (int j=FirstChain; j<=LastChain; j++) {
    289       if (j!=Chain && Chain!=-1) continue;
    290   for (int k=0; k<NUM_CHANNELS; k++) {
    291         if (k!=Channel && Channel!=-1) continue;
    292 
    293         // Voltage change ignored if DAC value is zero
    294         if (isdigit(Parameter[2][0])==0 && fHVBoard[i]->HV[j][k] == 0) continue;
    295 
    296         // Determine new DAC values
    297         if (!SetDac){
    298           if (isdigit(Parameter[2][0])==0) fHVBoard[i]->HVV[j][k] += hvoltageV; // voltage change
    299           else fHVBoard[i]->HVV[j][k] = hvoltageV;
    300           DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
    301         }
    302         else {
    303           if (isdigit(Parameter[2][0])==0) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // voltage change
    304           else DACValue = hvoltage;
    305         }
    306 
    307         // Set new voltage (if DAC value, update calibrated value)
    308         if (!RampVoltage(DACValue, i, j, k)) Errors++;
    309         if (SetDac) fHVBoard[i]->HVV[j][k] = calib->DACToHV(fHVBoard[i]->HV[j][k], i, j, k);
    310   } // Channels
    311   } // Chains
    312 
    313   // Update DIM service
    314   fHVBoard[i]->BiasVolt->updateService();
     245        // Loop over all channels given as command parameter
     246        for (unsigned int n=1; n<Parameter.size()-1; n+=2) {
     247          // Loop over all channels
     248          for (int j=0; j<NUM_CHAINS; j++) for (int k=0; k<NUM_CHANNELS; k++) {
     249
     250                // Current channel must be considered?
     251                if (!Match(Parameter[1], "all") && !(i == (int) pm->Pixel_to_HVboard(Parameter[n]) &&
     252                        j == (int) pm->Pixel_to_HVchain(Parameter[n]) && k == (int) pm->Pixel_to_HVchannel(Parameter[n])) &&
     253                        !(j == SingleChannel/NUM_CHANNELS && k == SingleChannel%NUM_CHANNELS)) continue;
     254
     255                // Voltage change (number starts with + oder -) ignored if current DAC value is zero
     256                if (isdigit(Parameter[n+1][0])==0 && fHVBoard[i]->HV[j][k] == 0) continue;
     257
     258                // Set new voltage/DAC value
     259                if (!SetDac){
     260                  // Convert voltage value and check format
     261                  if (!ConvertToDouble(Parameter[n+1], &Double)) {
     262                        PrintMessage("Error: Wrong number format for voltage setting\n");
     263                        goto LeaveLoop;
     264                  }
     265                  // Adjust voltage and DAV value
     266                  if (isdigit(Parameter[n+1][0]) == 0) fHVBoard[i]->HVV[j][k] += Double;
     267                  else fHVBoard[i]->HVV[j][k] = Double;
     268                  DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
     269                }
     270                else {
     271                  // Convert DAC value and check format
     272                  if (!ConvertToInt(Parameter[n+1], &Int)) {
     273                        PrintMessage("Error: Wrong number format for DAC voltage setting\n");
     274                        goto LeaveLoop;
     275                  }
     276                  // Adjust DAC value
     277                  if (isdigit(Parameter[n+1][0]) == 0) DACValue = fHVBoard[i]->HV[j][k] + Int;
     278                  else DACValue = Int;
     279                }
     280
     281                // Set new voltage (if DAC value, update calibrated value)
     282                if (!RampVoltage(DACValue, i, j, k)) Errors++;
     283                if (SetDac) fHVBoard[i]->HVV[j][k] = calib->DACToHV(fHVBoard[i]->HV[j][k], i, j, k);
     284          } // Channels and chains     
     285        } // Loop over command argument
     286
     287        // Update DIM service for this boar
     288        LeaveLoop:
     289        fHVBoard[i]->BiasVolt->updateService();
    315290  } // Boards
    316 
     291 
    317292  if (Errors > 0) PrintMessage("Errors on %d channel(s) occurred\n", Errors);
    318293}
     
    454429  for (int i=FirstBoard; i<=LastBoard; i++) {
    455430    PrintMessage(" BOARD %d (%s)   Wrap counter: %s (%d)  Manual reset: %s\n    Time-out: %.2f s  Error count: %d\n\n",
    456   fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
    457   fHVBoard[i]->WrapOK ? "ok":"error",
    458   fHVBoard[i]->LastWrapCount,
    459   fHVBoard[i]->ResetButton ? "yes" : "no",
    460   fHVBoard[i]->fTimeOut,
    461   fHVBoard[i]->ErrorCount);
    462 
    463     for (int j=FirstChain; j<=LastChain; j++) {
     431                fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
     432                fHVBoard[i]->WrapOK ? "ok":"error",     fHVBoard[i]->LastWrapCount,
     433                fHVBoard[i]->ResetButton ? "yes" : "no", fHVBoard[i]->fTimeOut, fHVBoard[i]->ErrorCount);
     434
     435    for (int j=0; j<NUM_CHAINS; j++) {
    464436          PrintMessage("  CHAIN %d     Over-current: %s\n", j, fHVBoard[i]->Overcurrent[j] ? "yes" : "no");
    465           for (int k=0;k<4;k++) {
    466         PrintMessage("\r");
    467             for (int l=0;l<8;l++) {
    468                   if(Parameter.size() == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][k*8+l]);
    469           else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][k*8+l]);
    470         }
    471             PrintMessage("\n");
    472           }
     437          for (int l=0; l<NUM_CHANNELS; l++) {
     438                if (l%8 == 0) PrintMessage("\r%3.1d:  ", j*NUM_CHANNELS+l);
     439                if (Parameter.size() == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][l]);
     440        else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][l]);
     441                if (l%8 == 7) PrintMessage("\n");
     442      }
    473443    }
    474444  }
     
    508478void ProcessIO::cmd_exit() {
    509479
    510   Exit = true;
     480  ExitRequest = true;
    511481  pthread_kill(HVMonitor, SIGUSR1);
    512482}
     
    535505void ProcessIO::DoPrintMessage(const char *Format, va_list ArgumentPointer, MsgTarget Target) {
    536506
    537   static char Textbuffer[MAX_COM_SIZE]; // static because of DIM service
    538 
    539   memset(Textbuffer, 0, sizeof(Textbuffer)); 
    540   vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
     507  static char Error[] = "vasprintf() failed in DoPrintMessage()";
     508  char *Text;
     509
     510  // Evaluate arguments   
     511  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
    541512 
    542513  // Print to console
    543514  if(Target & Console) {
    544     if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
    545       printf("\r%s%s", Textbuffer, Prompt);   // New prompt
    546     }
    547     else printf("%s", Textbuffer);
     515    if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%s%s", Text, Prompt); // New prompt
     516    else printf("%s", Text);
    548517    fflush(stdout);
    549518  }
    550519
    551   // Send to DIM service
    552   SetStdOut(Textbuffer);
    553 
    554   // Send to log
    555   if(Target & Log) {
    556     char *Buf;
    557     if (asprintf(&Buf, "%s %s", SERVER_NAME, Textbuffer) != -1) {
    558       DimClient::sendCommandNB("DColl/Log", Buf);
    559       free(Buf);
    560     }
    561     else DimClient::sendCommandNB("DColl/Log", SERVER_NAME" asprintf() failed");
    562   }
     520  // Send to DIM console service and log
     521  ConsoleOut->updateService(Text);
     522  if(Target & Log) SendToLog("%s %s", SERVER_NAME, Text);
     523
     524  // Free old text
     525  if (ConsoleText != Error) free(ConsoleText);
     526  ConsoleText = Text;
    563527}
    564528
     
    572536
    573537    if (fHVBoard[Board]->SetHV(Chain, Channel, fHVBoard[Board]->HV[Chain][Channel]+Diff) != 1) {
    574       State(ERROR, "Could not set bias of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
     538      Message(ERROR, "Could not set bias of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
    575539      return false;
    576540    }
     
    585549
    586550  static bool Warned = false;
    587  
     551  int Ret;
     552
     553  // Lock because command execution runs in different thread
     554  if ((Ret = pthread_mutex_lock(&Mutex)) != 0) {
     555        Message(FATAL, "pthread_mutex_lock() failed in commandHandler() (%s)", strerror(Ret));
     556  }
     557
    588558  for (int i=0; i<NumHVBoards; i++) {
    589559    if (fHVBoard[i]->ErrorCount > 10) {
     
    591561        Warned = true;
    592562        PrintMessage(All, "Warning: Some board has many read/write errors, status monitor disabled\n");
    593         State(WARN, "Warning: Some board has many read/write errors, status monitor disabled\n");
     563        Message(WARN, "Warning: Some board has many read/write errors, status monitor disabled\n");
    594564      }
    595565      continue;
     
    598568    if (fHVBoard[i]->GetStatus() != 1) {
    599569      PrintMessage(All, "Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
    600       State(ERROR, "Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
     570      Message(ERROR, "Error: Monitor could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
    601571    }
    602572   
    603573    if (fHVBoard[i]->ResetButton) {
    604574      PrintMessage(All, "Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
    605       State(INFO, "Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
     575      Message(INFO, "Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
    606576      ResetBoard(i);
    607577    }
     
    609579    if (!fHVBoard[i]->WrapOK) {
    610580      PrintMessage(All, "Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
    611       State(ERROR, "Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
     581      Message(ERROR, "Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
    612582    }
    613583
     
    615585      if (fHVBoard[i]->Overcurrent[j]) {
    616586                PrintMessage(All, "Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
    617                 State(WARN, "Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
     587                Message(WARN, "Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
    618588                ResetBoard(i);
    619589      }
    620590    }
    621591  }
     592 
     593  // Unlock
     594  if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) {
     595        Message(FATAL, "pthread_mutex_lock() failed in commandHandler() (%s)", strerror(Ret));
     596  }
     597
    622598}
    623599
     
    651627void ProcessIO::commandHandler() {
    652628
    653   pthread_mutex_lock(&control_mutex);
     629  int Ret;
     630
     631  if ((Ret = pthread_mutex_lock(&Mutex)) != 0) {
     632        Message(FATAL, "pthread_mutex_lock() failed in commandHandler() (%s)", strerror(Ret));
     633  }
     634
    654635  if (getCommand() == Command) CommandControl(getCommand()->getString());
    655   pthread_mutex_unlock(&control_mutex);
     636
     637  if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) {
     638        Message(FATAL, "pthread_mutex_unlock() failed in commandHandler() (%s)", strerror(Ret));
     639  }
    656640}
    657641
  • hvcontrol/src/ProcessIO.h

    r220 r226  
    3333        PixelMap *pm;
    3434        DimCommand *Command;
     35        DimService *ConsoleOut;
     36        char *ConsoleText;
    3537
    3638        void commandHandler();
     
    3941        HVCalib     *calib;
    4042        HVBoard **fHVBoard;
    41 
    42         pthread_mutex_t control_mutex;
    4343
    4444        char Prompt[MAX_COM_SIZE];
     
    5757        // Status variables 
    5858        pthread_t HVMonitor;       // exit function sends signal to these threads
     59        pthread_mutex_t Mutex;
    5960
    6061        int NumHVBoards;
    6162        int FirstBoard;
    6263        int LastBoard;
    63         int FirstChain;
    64         int LastChain;
    65  
    6664        state_enum   state;
    67         bool Exit;
    6865
    6966        // Methods
     
    8784        void cmd_start();       void cmd_stop();
    8885        void cmd_uptime();      void cmd_help();
    89         void cmd_chain();
    9086};
    9187
Note: See TracChangeset for help on using the changeset viewer.