- Timestamp:
- 07/28/09 09:13:41 (15 years ago)
- Location:
- drsdaq
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq/DAQReadout.cc
r89 r92 12 12 #include "SlowData.h" 13 13 14 #define TMPNAME "/tmp/__tmp__drsdaq__" 14 #define TMPNAME "/tmp/__tmp__drsdaq__" // ..for log file truncation 15 15 16 16 static const char* daq_state_str[] = {"active", "stopped"}; … … 26 26 {"status", &DAQReadout::cmd_status, false, "[daq|drs]", "Show DAQ/DRS status information"}, 27 27 {"freq", &DAQReadout::cmd_freq, true, "<GHz> [reg]", "Set DRS sampling frequency (regulated)"}, 28 {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f> [dir]", "Response calibration"},28 {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f>", "Response calibration"}, 29 29 {"trigger", &DAQReadout::cmd_trigger, true, "<on|off>", "Hardware trigger on or off"}, 30 30 {"delayed", &DAQReadout::cmd_delayed, true, "<on|off>", "Switch delayed start on or off"}, … … 76 76 LastBoard = -1; 77 77 CmdFromSocket = false; 78 79 // Read configuration file 78 ConfigOK = true; 79 80 // Read configuration file (if any item missing, program will be terminated in main() routine) 80 81 FILE *File; 81 82 if ((File = fopen(Configfile,"r")) == NULL) { 82 83 printf("Error: Could not open drsdaq configuration file '%s'\n", Configfile); 84 ConfigOK = false; 85 return; 83 86 } 84 87 else { 85 88 printf("Reading drsdaq configuration file %s\n", Configfile); 86 ReadCard("LogFile", fLogFile, 's', File); 87 ReadCard("MaxLogLines", &fMaxLogLines, 'U', File); 88 ReadCard("RawDataPath", fRawDataPath, 's', File); 89 ReadCard("FirstSample", &fFirstSample, 'I', File); 90 ReadCard("Samples", &fSamples, 'U', File); 91 ReadCard("MinDiskSpaceMB", &fMinDiskSpaceMB, 'U', File); 92 ReadCard("MaxFileSizeMB", &fMaxFileSizeMB, 'I', File); 93 ReadCard("CCPort", &fCCPort, 'I', File); 94 ReadCard("FirstVMESlot", &fFirstVMESlot, 'I', File); 95 ReadCard("LastVMESlot", &fLastVMESlot, 'I', File); 96 ReadCard("HVFeedbackConfig", fHVFeedbackConfig, 's', File); 89 ConfigOK &= ReadCard("LogFile", fLogFile, 's', File); 90 ConfigOK &= ReadCard("SlowDataPath", fSlowDataPath, 's', File); 91 ConfigOK &= ReadCard("MaxLogLines", &fMaxLogLines, 'U', File); 92 ConfigOK &= ReadCard("RawDataPath", fRawDataPath, 's', File); 93 ConfigOK &= ReadCard("FirstSample", &fFirstSample, 'I', File); 94 ConfigOK &= ReadCard("Samples", &fSamples, 'U', File); 95 ConfigOK &= ReadCard("MinDiskSpaceMB", &fMinDiskSpaceMB, 'U', File); 96 ConfigOK &= ReadCard("MaxFileSizeMB", &fMaxFileSizeMB, 'I', File); 97 ConfigOK &= ReadCard("CCPort", &fCCPort, 'I', File); 98 ConfigOK &= ReadCard("FirstVMESlot", &fFirstVMESlot, 'I', File); 99 ConfigOK &= ReadCard("LastVMESlot", &fLastVMESlot, 'I', File); 100 ConfigOK &= ReadCard("HVFeedbackConfig", fHVFeedbackConfig, 's', File); 101 ConfigOK &= ReadCard("DefaultFrequency", &fDefaultFrequency , 'd', File); 97 102 fclose(File); 103 if (!ConfigOK) return; 98 104 } 99 105 if (fFirstSample < 0 || fFirstSample > kNumberOfBins || fSamples > kNumberOfBins) { … … 108 114 if (system(ShellCmd) != 0) printf("Warning: Could not truncate log file '%s' to %u lines\n", fLogFile, fMaxLogLines); 109 115 110 // Open log file 116 // Open log file and log configuration 111 117 if ((Logfile = fopen(fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", fLogFile); 112 118 PrintMessage(MsgToLog,"********** Logging started **********\n"); 113 114 // Print configuration 115 cmd_config(); 119 PrintConfig(MsgToLog); 116 120 117 121 // Create DRS instance and perform initial scan … … 151 155 152 156 // Create instance of slow data class for DAQ 153 char Filename[MAX_PATH]; 154 snprintf(Filename,sizeof(Filename),"%s/SlowData/", fRawDataPath); 155 SlowDataClass = new SlowData("DAQ", Filename); 157 SlowDataClass = new SlowData("DAQ", fSlowDataPath); 156 158 if(SlowDataClass->ErrorCode != 0) { 157 159 PrintMessage("Warning: Could not open DAQ slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode)); 158 160 } 161 SlowDataClass->NewEntry("Runinfo-Info", "Run information written after completion or termination of run (Status can be OK or Error): Runnumber Status Runtype Events Files Description "); 159 162 } 160 163 … … 170 173 delete[] WaveForm; delete[] TriggerCell; 171 174 172 PrintMessage(MsgToLog,"********** Logging ended **********\n\n");173 175 if(Logfile) { 174 176 if(!fclose(Logfile)) printf("Closing logfile\n"); … … 224 226 // Print DAQ configuration 225 227 void DAQReadout::cmd_config() { 226 PrintMessage("LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n" 227 "FirstSample: %d\tSamples: %u\n" 228 "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n" 229 "FirstVMESlot: %d\t\tLastVMESlot: %d\n" 230 "HVFeedbackConfig: %s\n", 231 fLogFile,fMaxLogLines,fRawDataPath,fFirstSample,fSamples,fMinDiskSpaceMB, 232 fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fHVFeedbackConfig); 228 PrintConfig(CmdFromSocket ? MsgToSocket : MsgToConsole); 233 229 } 234 230 … … 241 237 return; 242 238 } 243 if (!IsDRSFreqSet()) return; 239 if (!IsDRSFreqSet()) { 240 PrintMessage("Setting default frequency\n"); 241 SetDRSFrequency(fDefaultFrequency, false); 242 CalibrationRead = false; 243 } 244 244 245 if (!CalibrationRead && !ReadCalibration()) { 245 246 PrintMessage("Cannot start run if response calibration not read.\n"); … … 445 446 // Do internal calibration 446 447 void DAQReadout::cmd_calib() { 447 if (NParam==4 && atof(Param[1]) && atof(Param[2])) 448 CalibrateDRS((char *) Param[3],atof(Param[1]),atof(Param[2])); 449 else if (NParam==3 && atof(Param[1]) && atof(Param[2])) 450 CalibrateDRS(NULL,atof(Param[1]),atof(Param[2])); 451 else PrintUsage(); 448 char str[MAX_COM_SIZE]; 449 450 if (NParam!=3 || !atof(Param[1]) || !atof(Param[2])) { 451 PrintUsage(); 452 return; 453 } 454 455 getcwd(str, sizeof(str)); 456 strcat(str,"/calib"); 457 PrintMessage("Writing calibration data to directory '%s'\n",str); 458 459 for (int i=FirstBoard; i<=LastBoard; i++) { 460 drs->GetBoard(i)->Init(); 461 drs->GetBoard(i)->SetFrequency(atof(Param[2])); 462 drs->GetBoard(i)->SoftTrigger(); 463 464 PrintMessage("Creating calibration of board %d (%d)\n", i, drs->GetBoard(i)->GetCMCSerialNumber()); 465 466 drs->GetBoard(i)->EnableTcal(1); 467 PrintMessage("Tcal enabled\n"); 468 469 if (drs->GetBoard(i)->GetChipVersion() == 3) drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,21,0,20,0,0,0,0,0); 470 else drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,atof(Param[1]),0); 471 drs->GetBoard(i)->SetCalibrationDirectory(str); 472 473 for (int j=0; j<2; j++) { 474 drs->GetBoard(i)->GetResponseCalibration()->ResetCalibration(); 475 PrintMessage("Calibration reset done.\n"); 476 477 while (!drs->GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {} 478 PrintMessage("Record calibration points done.\n"); 479 while (!drs->GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {} 480 PrintMessage("Calibration points fitted.\n"); 481 while (!drs->GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {} 482 PrintMessage("Offset calibration done.\n"); 483 484 if (!drs->GetBoard(i)->GetResponseCalibration()->WriteCalibration(j)) break; 485 } 486 drs->GetBoard(i)->Init(); // Reset linear range -0.2 ... 0.8 V 487 } // Loop over boards 452 488 } 453 489 … … 650 686 // Print feedback configuration 651 687 void DAQReadout::cmd_fconfig() { 652 HVFB->PrintConfig( );688 HVFB->PrintConfig(CmdFromSocket ? MsgToSocket : MsgToConsole); 653 689 } 654 690 … … 799 835 } 800 836 801 // Do internal calibration802 void DAQReadout::CalibrateDRS(char *dir, double trigfreq, double calibfreq) {803 804 int i,j;805 char str[MAX_COM_SIZE];806 DIR *pdir;807 808 if (NumBoards) {809 if(dir!=NULL) {810 if ((pdir=opendir(str))==0){811 PrintMessage("Error: target directory \"%s\" does not exist!\n",str);812 return;813 }814 closedir(pdir);815 snprintf(str,sizeof(str),"%s",dir);816 PrintMessage("Target: \"%s\"\n",str);817 }818 else {819 getcwd(str, sizeof(str));820 strcat(str,"/calib");821 PrintMessage("Taking default target: \"%s/\"\n",str);822 }823 824 for (i=FirstBoard; i<=LastBoard; i++) {825 drs->GetBoard(i)->Init();826 drs->GetBoard(i)->SetFrequency(calibfreq);827 drs->GetBoard(i)->SoftTrigger();828 829 PrintMessage("Creating calibration of board %d\n", drs->GetBoard(i)->GetCMCSerialNumber());830 831 drs->GetBoard(i)->EnableTcal(1);832 PrintMessage("Tcal enabled");833 834 if (drs->GetBoard(i)->GetChipVersion() == 3)835 drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,21,0,20,0,0,0,0,0);836 else837 drs->GetBoard(i)->GetResponseCalibration()->SetCalibrationParameters(1,36,110,20,19,40,15,trigfreq,0);838 839 drs->GetBoard(i)->SetCalibrationDirectory(str);840 PrintMessage("Storage directory \"%s\"\n",str);841 842 for (j=0;j<2;j++) {843 drs->GetBoard(i)->GetResponseCalibration()->ResetCalibration();844 PrintMessage("Calibration reset done.\n");845 846 while (!drs->GetBoard(i)->GetResponseCalibration()->RecordCalibrationPoints(j)) {}847 PrintMessage("Record calibration points done.\n");848 while (!drs->GetBoard(i)->GetResponseCalibration()->FitCalibrationPoints(j)) {}849 PrintMessage("Calibration points fitted.\n");850 while (!drs->GetBoard(i)->GetResponseCalibration()->OffsetCalibration(j)) {}851 PrintMessage("Offset calibration done.\n");852 853 if (!drs->GetBoard(i)->GetResponseCalibration()->WriteCalibration(j))854 break;855 }856 drs->GetBoard(i)->Init(); // Reset linear range -0.2 ... 0.8 V857 } // Loop over boards858 }859 else PrintMessage("No DRS boards available\n");860 }861 862 837 // Check if DRS is sampling 863 838 bool DAQReadout::IsDRSBusy() { … … 871 846 bool DAQReadout::IsDRSFreqSet() { 872 847 873 for (int i=FirstBoard; i<=LastBoard;i++)848 for (int i=FirstBoard; i<=LastBoard; i++) 874 849 if (DRSFreq[i]==0) { 875 850 PrintMessage("DRS sampling frequency of board %d not set!\n",i); … … 992 967 } 993 968 994 // Write event header 995 bool DAQReadout::WriteEventHeader() { 996 969 // Write event 970 bool DAQReadout::WriteEvent() { 971 972 // Event header 997 973 struct timeval Time; 998 974 … … 1000 976 1001 977 EHeader->EventNumber = NumEvents; 1002 EHeader->TriggerType = (daq_runtype == data) ? 1 : 0;978 EHeader->TriggerType = daq_runtype==data ? 0 : 1; 1003 979 EHeader->Second = Time.tv_sec; 1004 980 EHeader->Microsecond = Time.tv_usec; … … 1010 986 return false; 1011 987 } 1012 return true; 1013 } 1014 1015 // Write event data (It is required that at least three chunks can be written with writev(), therefore 1016 // IOV_MAX>=3 is checked at startup 1017 bool DAQReadout::WriteEventData() { 1018 988 989 // Event data (It is required that at least three chunks can be written with writev(), therefore 990 // IOV_MAX>=3 is checked at startup 991 1019 992 unsigned int Start, Count = 0; 1020 993 ssize_t WriteResult, Size = 0; … … 1022 995 1023 996 // First chunk: trigger cells 1024 DataPart[Count].iov_base = TriggerCell + FirstBoard*kNumberOfChips;997 DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*kNumberOfChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) ! 1025 998 DataPart[Count++].iov_len = RHeader->NBoards * kNumberOfChips * sizeof(int); 1026 999 Size += DataPart[Count-1].iov_len; … … 1054 1027 } // Chips 1055 1028 } // Boards 1029 1056 1030 return true; 1031 } 1032 1033 // Print configuration to target 1034 void DAQReadout::PrintConfig(int Target) { 1035 PrintMessage(Target, "LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n" 1036 "DefaultFrequency: %.2f\tFirstSample: %d\tSamples: %u\n" 1037 "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n" 1038 "FirstVMESlot: %d\t\tLastVMESlot: %d\n" 1039 "SlowDataPath: %s\tHVFeedbackConfig: %s\n", 1040 fLogFile,fMaxLogLines,fRawDataPath,fDefaultFrequency,fFirstSample,fSamples,fMinDiskSpaceMB, 1041 fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fSlowDataPath,fHVFeedbackConfig); 1057 1042 } 1058 1043 … … 1238 1223 else if (m->daq_runtype == pedestal) m->StopDRS(); // ..or for software trigger 1239 1224 1240 EventsInFile++; m->NumEvents++;1241 WriteError |= !m->WriteEventHeader();1242 1243 1225 // Read event data via VME or generate test data (for one board if no boards available) 1244 1226 if (m->daq_runtype != test) { … … 1252 1234 } 1253 1235 1254 // Write data to disk and update file size 1255 WriteError |= !m->WriteEventData(); 1236 // Write event to disk and update file size 1237 EventsInFile++; m->NumEvents++; 1238 WriteError |= !m->WriteEvent(); 1256 1239 1257 1240 if((FileSize = lseek(m->Rawfile, 0, SEEK_CUR)) == -1) { … … 1273 1256 } while((m->NumEvents<m->NumEventsRequested || m->NumEventsRequested==0) && !m->Stop && !WriteError); 1274 1257 1275 // Print run summary to slow data file and to screen1276 1258 m->StopDRS(); 1277 if(!WriteError) { 1278 m->PrintMessage("\rRun #%d (%s) %s, %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents); 1279 m->SlowDataClass->NewEntry("Runinfo"); 1280 m->SlowDataClass->AddToEntry("%d %s %s %d %d", m->RunNumber, daq_runtype_str[m->daq_runtype], m->RHeader->Description, m->NumEvents, m->FileNumber); 1281 if(m->SlowDataClass->ErrorCode != 0) { 1282 m->PrintMessage("Error, could not write DAQ data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode)); 1283 } 1284 1285 } 1259 1260 // Print run summary to screen 1261 if(!WriteError) m->PrintMessage("\rRun #%d (%s) %s, %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents); 1286 1262 else m->PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],m->NumEvents); 1263 1264 // Write run summary to slow data file 1265 m->SlowDataClass->NewEntry("Runinfo"); 1266 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); 1267 if(m->SlowDataClass->ErrorCode != 0) { 1268 m->PrintMessage("Error, could not write DAQ data to file (%s), file closed\n", strerror(m->SlowDataClass->ErrorCode)); 1269 } 1287 1270 1288 1271 // Print run statistics -
drsdaq/DAQReadout.h
r68 r92 54 54 // Configuration data 55 55 char fLogFile[MAX_PATH]; 56 char fSlowDataPath[MAX_PATH]; 56 57 unsigned int fMaxLogLines; 57 58 char fRawDataPath[MAX_PATH]; … … 64 65 int fFirstVMESlot; 65 66 char fHVFeedbackConfig[MAX_PATH]; 67 double fDefaultFrequency; 66 68 67 69 // Status variables … … 85 87 char FileName[MAX_PATH]; 86 88 char Prompt[MAX_COM_SIZE]; 87 89 bool ConfigOK; 90 88 91 // Public functions 89 92 DAQReadout(const char*); … … 114 117 bool IsDRSFreqSet(); 115 118 void SetDRSFrequency(double, bool); 116 void CalibrateDRS(char*, double, double);117 119 void SetDOMINOMode(int); 118 120 void SetDOMINOReadMode(int); … … 123 125 bool IsCalibrationRead(); 124 126 void ReadCalibratedDRSData(); 127 void PrintConfig(int); 125 128 void PrintMessage(int, const char*, ...); 126 129 void PrintMessage(const char*, ...); … … 129 132 bool WriteRunHeader(); 130 133 bool UpdateRunHeader(unsigned int, bool); 131 bool WriteEventHeader(); 132 bool WriteEventData(); 134 bool WriteEvent(); 133 135 }; 134 136 -
drsdaq/HVFeedback.cc
r89 r92 24 24 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) { 25 25 struct sockaddr_in SocketAddress; 26 char Filename[MAX_PATH];27 26 28 27 m = DAQClass; … … 30 29 31 30 // Create instance of slow data class for feedback 32 snprintf(Filename,sizeof(Filename),"%s/SlowData/", m->fRawDataPath); 33 SlowDataClass = new SlowData("HVFB", Filename); 31 SlowDataClass = new SlowData("HVFB", m->fSlowDataPath); 34 32 if (SlowDataClass->ErrorCode != 0) { 35 33 m->PrintMessage("Warning: Could not open feedback slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode)); 36 34 } 35 SlowDataClass->NewEntry("Average-Info", "Feedback regulation occurred: Board Chip Channel Average Sigma Correction-Value"); 36 SlowDataClass->NewEntry("Target-Info", "New Target values acquired: Board Chip Channel Target Sigma"); 37 SlowDataClass->NewEntry("Response-Info", "New response measurement: Board Chip Channel Response"); 37 38 38 39 // Initialise with zero content … … 65 66 fclose(File); 66 67 } 67 PrintConfig( );68 PrintConfig(MsgToLog); 68 69 69 70 // Initial state … … 373 374 // Print feedback configuration 374 375 // 375 void HVFeedback::PrintConfig( ) {376 m->PrintMessage( "LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"376 void HVFeedback::PrintConfig(int Target) { 377 m->PrintMessage(Target, "LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n" 377 378 "LedTrigSample: %d\tLedTrigThreshold: %.2f\n" 378 379 "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n" -
drsdaq/HVFeedback.h
r36 r92 64 64 void ClearAverages(); 65 65 bool WriteHVCommand(const char *, ...); 66 void PrintConfig( );66 void PrintConfig(int); 67 67 }; 68 68 -
drsdaq/History.txt
r86 r92 41 41 18/6/2009 Run date is now calculated with a change to the next date on 13:00 UTC. 42 42 9/7/2009 SlowData class is now independet of PrintMessage() method, thus more 43 universal 43 universal 44 14/7/2009 Fixed assignment of trigger type in event header (now 0 is hardware 45 trigger, 1 software trigger). Fixed pointer-arithmetic for trigger cell 46 writing if first board written to disk is not physically first board. 47 28/7/2009 Added configuration parameters SlowDataPath and DefaultFrequency. All 48 configuration parameters are now mandatory: if one is not found, the 49 program terminates. -
drsdaq/SlowData.cc
r87 r92 3 3 SlowData.cc 4 4 5 Class handling the writing of slow data. String to be written in the5 Class handling the writing of slow data. Strings to be written in the 6 6 slow data file are checked that they do not contain control characters. 7 8 1. Call constructor with desired identification and directory 9 for slow data file. The public ErrorCode variable will be zero 10 if successful, otherwise contain the relevant errno. 11 2. Use NewEntry() to start a new entry with given variable name. A text 12 as second argument is optional. 13 3. If text should be added to an open entry, use AddToEntry(). It can 14 process printf()-style formatting. 15 4. The slow data file will be closed upon destruction of the instance. 7 16 8 17 Oliver Grimm … … 45 54 // Add a new entry to slow data file 46 55 // 47 bool SlowData::NewEntry(const char *Variable ) {56 bool SlowData::NewEntry(const char *Variable, const char *Text) { 48 57 49 58 time_t RawTime; … … 57 66 NewEntryCalled = AddToEntry("\n%s %s %d %d %d %d %d %d %d %lu ", Issuer, Variable, TM->tm_year+1900,TM->tm_mon+1,TM->tm_mday,TM->tm_hour,TM->tm_min,TM->tm_sec, Time.tv_usec/1000, Time.tv_sec); 58 67 InternalCall = false; 68 if(Text != NULL && NewEntryCalled == true) NewEntryCalled = AddToEntry("%s", Text); 69 59 70 return NewEntryCalled; 60 71 } … … 65 76 bool SlowData::AddToEntry(const char *Format, ...) { 66 77 67 char Textbuffer[MAX_ COM_SIZE];78 char Textbuffer[MAX_ENTRY_SIZE]; 68 79 va_list ArgumentPointer; 69 80 -
drsdaq/SlowData.h
r87 r92 12 12 13 13 #define MAX_PATH 256 14 #define MAX_ COM_SIZE 1000014 #define MAX_ENTRY_SIZE 10000 15 15 16 16 class SlowData { … … 26 26 27 27 int ErrorCode; // Set to errno if an error occured, zero otherwise 28 bool NewEntry(const char* );28 bool NewEntry(const char*, const char* = NULL); 29 29 bool AddToEntry(const char*, ...); 30 30 }; -
drsdaq/drsdaq.cpp
r63 r92 85 85 signal(SIGHUP, &CrashHandler); 86 86 87 // Construct main instance 87 // Construct main instance and create mutex for thread synchronization 88 88 DAQReadout dreadout(argc==3 ? argv[2] : DEFAULT_CONFIG); 89 90 // Create threads and mutex for thread synchronization91 89 if (pthread_mutex_init(&dreadout.control_mutex, NULL) != 0) { 92 90 perror("pthread_mutex_init failed"); 93 91 throw; 94 92 } 95 if ((pthread_create(&thread_ConsoleCommand, NULL, (void * (*)(void *)) ConsoleCommand,(void *) &dreadout)) != 0) { 96 perror("pthread_create failed with console thread"); 97 throw; 98 } 99 if ((pthread_create(&thread_CCCommand, NULL, (void * (*)(void *)) CCCommand,(void *) &dreadout)) != 0) { 100 perror("pthread_create failed with socket thread"); 101 dreadout.SocketThread = NULL; 102 } 103 else dreadout.SocketThread = &thread_CCCommand; // Thread should be accessible for sending signals 104 105 // Wait for threads to quit 106 pthread_join(thread_ConsoleCommand, NULL); 107 if(dreadout.SocketThread != NULL) pthread_join(thread_CCCommand, NULL); 108 93 94 if (dreadout.ConfigOK) { // Normal program execution only if configuration was complete 95 // Create threads 96 if (pthread_mutex_init(&dreadout.control_mutex, NULL) != 0) { 97 perror("pthread_mutex_init failed"); 98 throw; 99 } 100 if ((pthread_create(&thread_ConsoleCommand, NULL, (void * (*)(void *)) ConsoleCommand,(void *) &dreadout)) != 0) { 101 perror("pthread_create failed with console thread"); 102 throw; 103 } 104 if ((pthread_create(&thread_CCCommand, NULL, (void * (*)(void *)) CCCommand,(void *) &dreadout)) != 0) { 105 perror("pthread_create failed with socket thread"); 106 dreadout.SocketThread = NULL; 107 } 108 else dreadout.SocketThread = &thread_CCCommand; // Thread should be accessible for sending signals 109 110 // Wait for threads to quit 111 pthread_join(thread_ConsoleCommand, NULL); 112 if(dreadout.SocketThread != NULL) pthread_join(thread_CCCommand, NULL); 113 } 114 else printf("Error: Configuration parameter missing in %s, terminating.\n", argc==3 ? argv[2] : DEFAULT_CONFIG); 115 109 116 // Destruct mutex and main instance 110 117 pthread_mutex_destroy (&dreadout.control_mutex); … … 135 142 136 143 while (!m->Exit) { 144 145 // Assemble prompt 137 146 if (m->NumBoards == 0) snprintf(m->Prompt,sizeof(m->Prompt),"\rDAQ> "); 138 147 else if (m->FirstBoard == m->LastBoard) snprintf(m->Prompt,sizeof(m->Prompt),"\rDAQ|B%d> ",m->FirstBoard); 139 148 else snprintf(m->Prompt,sizeof(m->Prompt),"\rDAQ|B%d-%d> ",m->FirstBoard,m->LastBoard); 140 149 150 // Read Command 141 151 Command = readline(m->Prompt); 142 152 if (Command==NULL) { … … 144 154 continue; 145 155 } 146 147 156 if(strlen(Command)>0) add_history(Command); 148 157 158 // Log command 149 159 strftime(Buf,MAX_COM_SIZE, "%d/%m/%y %X", localtime(&(Time=time(NULL)))); 150 160 m->PrintMessage(MsgToLog, "CONSOLE(%s)> %s\n", Buf, Command); … … 199 209 SocketAddress.sin_port = htons((unsigned short) m->fCCPort); 200 210 SocketAddress.sin_addr.s_addr = INADDR_ANY; 211 201 212 if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) 202 213 { … … 223 234 m->Socket = ConnectionSocket; 224 235 225 while (!m->Exit) { // Looping as long as client exists 236 // Looping as long as client exists and program not terminated 237 while (!m->Exit) { 238 239 // Try to read command from socket 226 240 memset(Command,0,sizeof(Command)); 227 241 ReadResult = read(ConnectionSocket, Command, MAX_COM_SIZE); … … 233 247 if (Command[strlen(Command)-1]=='\n') Command[strlen(Command)-1]='\0'; // Remove trailing newline 234 248 249 // Log command 235 250 strftime(Buf, MAX_COM_SIZE, "%d/%m/%y %X", localtime(&(Time=time(NULL)))); 236 251 m->PrintMessage(MsgToConsole|MsgToLog, "SOCKET(%s)> %s\n", Buf, Command); … … 238 253 // Process command 239 254 pthread_mutex_lock(&m->control_mutex); 240 m->CmdFromSocket = true; 255 m->CmdFromSocket = true; 241 256 m->CommandControl(Command); 242 m->CmdFromSocket = false; 257 m->CmdFromSocket = false; 243 258 pthread_mutex_unlock(&m->control_mutex); 244 259 } 260 245 261 m->Socket = -1; 246 262 m->PrintMessage("Disconnected from client.\n");
Note:
See TracChangeset
for help on using the changeset viewer.