- Timestamp:
- 06/18/10 12:25:29 (15 years ago)
- Location:
- drsdaq
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq/DAQReadout.cc
r211 r226 64 64 // 65 65 66 DAQReadout::DAQReadout(): 67 DimCommand((char *) SERVER_NAME"/Command", (char *) "C"), 68 EvidenceServer(SERVER_NAME) { 69 70 // Global class pointer 66 DAQReadout::DAQReadout(): EvidenceServer(SERVER_NAME) { 67 68 // Initialization 71 69 This = this; 72 70 MainThread = getpid(); 73 74 // Start time of DAQ 71 ConsoleText = NULL; 75 72 time(&StartTime); 73 74 // DIM console service used in PrintMessage() 75 ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) ""); 76 76 77 77 // Initialize mutex for thread synchronisation 78 78 if (pthread_mutex_init(&Mutex, NULL) != 0) { 79 State(FATAL, "pthread_mutex_init() failed");79 Message(FATAL, "pthread_mutex_init() failed"); 80 80 } 81 81 … … 89 89 LastBoard = -1; 90 90 MinDelay = 1; 91 91 92 92 // Get configuration data 93 93 fRawDataPath = GetConfig("RawDataPath"); … … 145 145 // Create instance of HV feedback (must be called after board detection) 146 146 HVFB = new HVFeedback(this); 147 148 // Install DIM command (after all initialized) 149 Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this); 147 150 } 148 151 … … 153 156 DAQReadout::~DAQReadout() { 154 157 155 delete EventService; 156 delete[] DIMEventData; 158 delete Command; 159 160 delete EventService; delete[] DIMEventData; 157 161 delete RHeader; delete EHeader; 158 162 delete HVFB; delete[] ACalibTemp; … … 160 164 delete[] DRSFreq; delete[] BStruct; 161 165 delete[] WaveForm; delete[] TriggerCell; 162 163 // Destroy mutex 164 if (pthread_mutex_destroy(&Mutex) != 0) State(ERROR, "pthread_mutex_destroy() failed"); 166 167 delete ConsoleOut; 168 free(ConsoleText); 169 170 if (pthread_mutex_destroy(&Mutex) != 0) Message(ERROR, "pthread_mutex_destroy() failed"); 165 171 } 166 172 … … 171 177 void DAQReadout::Execute(char *Command) { 172 178 173 if (strlen(Command)==0) return; // Ignore empty commands 174 175 if(Command[0]=='.') { // Shell command 179 if (Command[0]=='.') { // Shell command 176 180 system(&(Command[1])); 177 181 return; 178 182 } 179 183 180 for (int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = ""; // All pointers point initially to empty string184 for (int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = ""; // All pointers point initially to empty string 181 185 NParam = ParseInput(Command, Param); 182 183 for(CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++) 184 if (Match(Param[0], CommandList[CmdNumber].Name)) { 185 if(CommandList[CmdNumber].NeedNotBusy && daq_state==active) PrintMessage("DAQ is busy\n"); 186 else if(CommandList[CmdNumber].NeedNotBusy && NumBoards==0) PrintMessage("No boards available\n"); 187 else { 188 pthread_mutex_lock(&Mutex); 189 (this->*CommandList[CmdNumber].CommandPointer)(); 190 pthread_mutex_unlock(&Mutex); 191 } 192 return; 193 } 194 PrintMessage("Unknown command '%s'\n",Param[0]); 186 187 // Search for command 188 unsigned int Count; 189 for (Count=0; Count<sizeof(CommandList)/sizeof(CL_Struct); Count++) { 190 if (Match(Param[0], CommandList[Count].Name)) break; 191 } 192 193 // Command not found? 194 if (Count == sizeof(CommandList)/sizeof(CL_Struct)) { 195 PrintMessage("Unknown command '%s'\n", Param[0]); 196 return; 197 } 198 199 if(CommandList[Count].NeedNotBusy && daq_state==active) PrintMessage("DAQ is busy\n"); 200 else if(CommandList[Count].NeedNotBusy && NumBoards==0) PrintMessage("No boards available\n"); 201 else { 202 int Ret; 203 204 // Lock (Execute() runs in thread spawned by commandHandler()) 205 if ((Ret = pthread_mutex_lock(&Mutex)) != 0) { 206 Message(FATAL, "pthread_mutex_lock() failed (%s)", strerror(Ret)); 207 } 208 // Run command 209 CmdNumber = Count; 210 (this->*CommandList[CmdNumber].CommandPointer)(); 211 // Unlock 212 if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) { 213 Message(FATAL, "pthread_mutex_unlock() failed (%s)", strerror(Ret)); 214 } 215 } 195 216 } 196 217 … … 199 220 time_t ActualT; 200 221 time (&ActualT); 201 PrintMessage("% d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);222 PrintMessage("%02d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60); 202 223 } 203 224 … … 1116 1137 } 1117 1138 1118 // Event data (It is required that at least three chunks can be written with writev(), therefore 1119 // IOV_MAX>=3 is checked at startup 1120 1121 1122 // First chunk: trigger cells 1123 //DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*RHeader->NChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) ! 1124 //DataPart[Count++].iov_len = RHeader->NBoards * RHeader->NChips * sizeof(int); 1125 //Size += DataPart[Count-1].iov_len; 1126 1127 // Remaining chunks: ADC data (two chucks per channel if wrap around of pipeline occurred) 1139 // ADC data (two chucks per channel if wrap around of pipeline occurred, therefore 1140 // IOV_MAX>=2 is checked at startup 1128 1141 for (int i=FirstBoard; (i<=LastBoard + (NumBoards==0)); i++) { 1129 1142 for (unsigned int k=0; k<RHeader->NChips; k++) { … … 1202 1215 void DAQReadout::DoPrintMessage(const char *Format, va_list ArgumentPointer, int Target) { 1203 1216 1204 static char Textbuffer[MAX_COM_SIZE]; 1205 1206 memset(Textbuffer, 0, sizeof(Textbuffer)); 1207 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer); 1217 static char Error[] = "vasprintf() failed in DoPrintMessage()"; 1218 char *Text; 1219 1220 // Evaluate arguments 1221 if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error; 1208 1222 1209 1223 // Print to console 1210 1224 if(Target & MsgToConsole) { 1211 if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') { 1212 printf("\r%s%s", Textbuffer, Prompt); // New prompt 1213 } 1214 else printf("%s", Textbuffer); 1225 if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%s%s", Text, Prompt); // New prompt 1226 else printf("%s", Text); 1215 1227 fflush(stdout); 1216 1228 } 1217 1229 1218 // Send to DIM service 1219 SetStdOut(Textbuffer); 1220 1221 // Send to log 1222 if(Target & MsgToLog) { 1223 char *Buf; 1224 if (asprintf(&Buf, "%s %s", SERVER_NAME, Textbuffer) != -1) { 1225 DimClient::sendCommandNB("DColl/Log", Buf); 1226 free(Buf); 1227 } 1228 else DimClient::sendCommandNB("DColl/Log", SERVER_NAME" asprintf() failed"); 1229 } 1230 // Send to DIM console service and to log if requested 1231 ConsoleOut->updateService(Text); 1232 if(Target & MsgToLog) SendToLog("%s %s", SERVER_NAME, Text); 1233 1234 // Free old text 1235 if (ConsoleText != Error) free(ConsoleText); 1236 ConsoleText = Text; 1230 1237 } 1231 1238 … … 1233 1240 void DAQReadout::commandHandler() { 1234 1241 1235 // Copy command to new buffer (must be freed by the new thread) 1242 // Ignore empty or illegal strings 1243 if (getCommand()->getSize() == 0 || 1244 *((char *) getCommand()->getData()+getCommand()->getSize()-1) != '\0' || 1245 strlen(getCommand()->getString()) == 0) return; 1246 1247 // Copy command to new buffer (will be freed by global Execute() function) 1236 1248 char *Command; 1237 if (asprintf(&Command, "%s", get String()) == -1) {1249 if (asprintf(&Command, "%s", getCommand()->getString()) == -1) { 1238 1250 PrintMessage("asprintf() failed in DRSReadout::commandHandler() (%s)\n", strerror(errno)); 1239 1251 return; … … 1314 1326 else if (daq_runtype == pedestal) StopDRS(); // ..or for software trigger 1315 1327 1316 // Read event data 1328 // Read event data and restart (reduces dead-time because waiting for next trigger while writing) 1317 1329 ReadCalibratedDRSData(); 1318 1319 // Restart here reduces dead-time (already waiting for next trigger while writing)1320 1330 StartDRS(); 1321 1331 … … 1386 1396 else PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n", RunNumber, daq_runtype_str[daq_runtype], NumEvents); 1387 1397 1388 // Write run summary to slow data file1389 //m->SlowDataClass->NewEntry("Runinfo");1390 //m->SlowDataClass->AddToEntry("%d %s %s %d %d %s", m->RunNumber, WriteError?"Error":"OK", daq_runtype_str[m->daq_runtype], m->NumEvents, m->FileNumber, m->RHeader->Description);1391 1392 1398 // Print run statistics 1393 1399 if (NumEvents>0 && !WriteError) { … … 1445 1451 } 1446 1452 1453 // Stub to call Execute() metho of class and free command memory 1447 1454 void Execute(char *Command) { 1448 1455 -
drsdaq/DAQReadout.h
r211 r226 33 33 enum runtype_enum {data, pedestal, reserved, test}; 34 34 35 class DAQReadout : public DRS, public DRSCallback, public DimCommand, publicEvidenceServer {35 class DAQReadout : public DRS, public DRSCallback, public EvidenceServer { 36 36 37 37 time_t StartTime; 38 38 pid_t MainThread; 39 39 DimService *EventService; 40 40 int MinDelay; 41 41 unsigned int CmdNumber; 42 DimCommand *Command; 43 DimService *ConsoleOut; 44 char *ConsoleText; 42 45 43 46 void PrintUsage(); -
drsdaq/HVFeedback.cc
r211 r226 25 25 // Constructor: Initialise feedback 26 26 // 27 HVFeedback::HVFeedback(DAQReadout* DAQClass){//: 28 //EvidenceServer(SERVER_NAME){ 27 HVFeedback::HVFeedback(DAQReadout* DAQClass){ 29 28 30 29 m = DAQClass; … … 139 138 } 140 139 141 // Update DIM service regularly140 // Update DIM count service regularly 142 141 if (time(NULL)-LastServiceUpdate > 2) { 143 142 LastServiceUpdate = time(NULL); … … 148 147 149 148 // Feedback action 149 std::stringstream Cmd; 150 150 151 for (i=m->FirstBoard; i<=m->LastBoard; i++) { 151 152 for (j=0; j<fNumberOfChips; j++) { … … 165 166 166 167 if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n"); 167 else WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), Correction); 168 168 else { 169 Cmd << PixMap->DRS_to_Pixel(i,j,k)+" " << std::showpos << Correction << " "; 170 } 169 171 break; 170 172 … … 175 177 case FB_ResponseFirst: // First point of response measurement done 176 178 Buffer[i][j][k] = Average[i][j][k]; 177 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage); 179 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) { 180 Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << DiffVoltage << " "; 181 } 178 182 break; 179 183 … … 184 188 } 185 189 else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]); 186 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2); 190 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) { 191 Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -DiffVoltage/2 << " "; 192 } 187 193 break; 188 194 … … 196 202 FeedbackAverage->updateService(); 197 203 FeedbackSigma->updateService(); 204 205 // Send command 206 if (!Cmd.str().empty()) { 207 DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str()); 208 } 198 209 199 210 switch (FBMode) { … … 269 280 else { 270 281 FBMode = Mode; 271 if (Mode != FB_ResponseFirst) m-> State(m->INFO, "%s", FBState_Description[FBMode]);272 else m-> State(m->INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage);282 if (Mode != FB_ResponseFirst) m->Message(m->INFO, "%s", FBState_Description[FBMode]); 283 else m->Message(m->INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage); 273 284 ClearAverages(); 274 285 } … … 320 331 void HVFeedback::MeasureResponse(float U) { 321 332 333 std::stringstream Cmd; 334 322 335 if (U==0) { 323 336 m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n"); … … 325 338 } 326 339 327 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 328 for (int j=0; j<fNumberOfChips; j++) 329 for (int k=0; k<fNumberOfChannels; k++) { 330 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) { 331 WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2); 332 } 333 } 340 for (int i=m->FirstBoard; i<=m->LastBoard; i++) { 341 for (int j=0; j<fNumberOfChips; j++) { 342 for (int k=0; k<fNumberOfChannels; k++) { 343 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) { 344 Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -U/2 << " "; 345 } 346 } 347 } 348 } 349 350 // Send command 351 if (!Cmd.str().empty()) { 352 DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str()); 353 } 354 334 355 DiffVoltage = U; 335 356 SetFBMode(FB_ResponseFirst, true); … … 351 372 352 373 // 353 // Write bias voltage commmand354 //355 bool HVFeedback::WriteHVCommand(const char *Format, ...) {356 357 char Textbuffer[MAX_COM_SIZE];358 359 va_list ArgumentPointer; va_start(ArgumentPointer, Format);360 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);361 362 DimClient::sendCommand("Bias/Command", Textbuffer);363 return true;364 }365 366 //367 374 // Print feedback configuration 368 375 // -
drsdaq/HVFeedback.h
r211 r226 6 6 #include <stdlib.h> 7 7 #include <math.h> 8 #include <sstream> 8 9 9 10 #include "RawDataCTX.h" … … 12 13 enum FBState {FB_Off, FB_Active, FB_Targets, FB_ResponseFirst, FB_ResponseSecond}; 13 14 14 class HVFeedback: public DimServer { //EvidenceServer {15 class HVFeedback: public DimServer { 15 16 16 17 class DAQReadout *m; … … 70 71 void GetResponse(); 71 72 void ClearAverages(); 72 bool WriteHVCommand(const char *, ...);73 73 void PrintConfig(int); 74 74 }; -
drsdaq/drsdaq.cpp
r211 r226 36 36 int LockDescriptor; 37 37 38 // Readline library uses getc() (allows interruption by signal)39 rl_getc_function = getc;40 41 // writev() in DAQ thread needs to be able to write at least 3 chunks42 if(IOV_MAX < 3) {43 printf("Fatal error: IOV_MAX is less than 3, cannot use writev() to write event data.\n");44 exit(EXIT_FAILURE);45 }46 47 38 // Assure only one instance of program runs (lock creator written to log file) 48 // Lock file deleted by ExitFunction()39 // Lock file deleted by destructor 49 40 if((LockDescriptor = open(LOCKFILE,O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) { 50 41 if(errno==EEXIST) { … … 59 50 sprintf(str,"echo Created >%s; date >>%s; echo by $USER@$HOSTNAME >>%s",LOCKFILE,LOCKFILE,LOCKFILE); 60 51 system(str); 61 52 53 // Readline library uses getc() (allows interruption by signal) 54 rl_getc_function = getc; 55 56 // writev() in DAQ thread needs to be able to write at least 3 chunks 57 if(IOV_MAX < 2) { 58 printf("Fatal error: IOV_MAX is less than 2, cannot use writev() to write event data.\n"); 59 exit(EXIT_FAILURE); 60 } 61 62 62 system("clear"); 63 63 printf("\n*** DRS readout (built %s, %s, revision %s) *** \n\n",__DATE__, __TIME__, REVISION); 64 65 // Set exit function 66 atexit(&ExitFunction); 64 67 65 68 // Construct main instance (static ensures destructor is called with exit()) 66 69 static DAQReadout M; 67 70 68 // Set signal and exit handlers 69 atexit(&ExitFunction); 71 // Set signal handlers 70 72 signal(SIGILL, &CrashHandler); 71 73 signal(SIGABRT, &CrashHandler); … … 88 90 // Process command 89 91 DimClient::sendCommand(SERVER_NAME"/Command", Command); 90 91 92 free(Command); 92 93 } … … 94 95 95 96 96 //*****************97 // Signal handlers98 //*****************99 100 97 // Remove lock file before running default signal code 101 98 void CrashHandler(int Signal) { 102 99 remove(LOCKFILE); 103 printf("Caught signal number %d. Remov inglockfile and performing standard signal action. Good luck.\n",Signal);100 printf("Caught signal number %d. Removed lockfile and performing standard signal action. Good luck.\n",Signal); 104 101 signal(Signal, SIG_DFL); 105 102 raise(Signal); … … 109 106 void ExitFunction() { 110 107 111 if (remove(LOCKFILE) ==-1) {108 if (remove(LOCKFILE) == -1) { 112 109 printf("Could not remove lock file %s (%s)\n", LOCKFILE, strerror(errno)); 113 110 } 114 115 return;116 111 }
Note:
See TracChangeset
for help on using the changeset viewer.