// // Mark Dalton October 2014 // // This program reads the scaler rates from the shared memory buffer, processes them in a way which is // detector system dependent and then publishes them to epics using a system call to caput. Each caput // call is run in a separate thread in order to minimze the impact of latency. The values are published // individually, summed in particular ways or writen to a waveform (array). Since his is particulr to // each detector, no attempt was made to make a general code and thus each roc runs a different executable. // The implementation is "quick and dirty" and is expected to be superseded by a more sophisticated // procedure in the future. // // Compile and run with the following: // // gcc shmem2epics_roctof3.c -I ../rcm/monitor/ -lpthread -o shmem2epics_roctof3.exe // ./shmem2epics_roctof3.exe // // #include #include #include #include #include //-------------------------------------------- #include "shmem_roc.h" static void shmem_get(); static int semid,shmid; static roc_shmem *shmem_ptr; void get_rates (); //-------------------------------------------- static const int NumSlots = 11; static const int StartSlot = 4; static const int EndSlot = 14; static const int NumChannels = 6; // Structure for epics data struct EpicsEvent{ char channelname[40]; int channelval; }; struct EpicsEvent EpicsEventArray[6]; // global aray of epics data void *CaputToEpics( void *argptr); // program to write epics data (run in a thread) // Structure for general system command char SystemCallStringArray[7][255]; // global array of strings to store system calls void *SystemCall( void *argptr); // program to preform a system call (run in a thread) //-------------------------------------------- int main() { shmem_get(); get_rates(); pthread_exit(NULL); } //----------------------------------------------------------------------------------- // get rates //----------------------------------------------------------------------------------- void get_rates () { int slot,ichan,epicschan; unsigned int update_f_old=0, update_d_old=0; // create a thread for each channel; pthread_t array_threads[4]; while(1) { //--------------------------------------------------------------------------------------------------- // DISCR rates //--------------------------------------------------------------------------------------------------- unsigned int update_d=shmem_ptr->discr_scalers.update; if ( update_d != update_d_old) { //---- char epicsname[255], epicsnamestem[255]; int ThreadStatus; // Write the waveforms (epics arrays) out sprintf(epicsname,"TOF:disc:scalers:N:rate_wf"); sprintf(SystemCallStringArray[0],"caput -a %s 44 ",epicsname); int counter; for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[0],"%s %i",SystemCallStringArray[0],shmem_ptr->discr_scalers.counters[4][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[0],"%s %i",SystemCallStringArray[0],shmem_ptr->discr_scalers.counters[5][counter]); } for (counter = 0; counter <12; counter++) { sprintf(SystemCallStringArray[0],"%s %i",SystemCallStringArray[0],shmem_ptr->discr_scalers.counters[6][counter]); } //printf("%s\n",SystemCallStringArray[0]); ThreadStatus = pthread_create(&array_threads[0], NULL, SystemCall, (void *) &SystemCallStringArray[0]); sprintf(epicsname,"TOF:disc:scalers:S:rate_wf"); sprintf(SystemCallStringArray[1],"caput -a %s 44 ",epicsname); for (counter = 12; counter <16; counter++) { sprintf(SystemCallStringArray[1],"%s %i",SystemCallStringArray[1],shmem_ptr->discr_scalers.counters[6][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[1],"%s %i",SystemCallStringArray[1],shmem_ptr->discr_scalers.counters[7][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[1],"%s %i",SystemCallStringArray[1],shmem_ptr->discr_scalers.counters[8][counter]); } for (counter = 0; counter <8; counter++) { sprintf(SystemCallStringArray[1],"%s %i",SystemCallStringArray[1],shmem_ptr->discr_scalers.counters[9][counter]); } //printf("%s\n",SystemCallStringArray[1]); ThreadStatus = pthread_create(&array_threads[1], NULL, SystemCall, (void *) &SystemCallStringArray[1]); sprintf(epicsname,"TOF:disc:scalers:T:rate_wf"); sprintf(SystemCallStringArray[2],"caput -a %s 44 ",epicsname); for (counter = 8; counter <16; counter++) { sprintf(SystemCallStringArray[2],"%s %i",SystemCallStringArray[2],shmem_ptr->discr_scalers.counters[9][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[2],"%s %i",SystemCallStringArray[2],shmem_ptr->discr_scalers.counters[10][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[2],"%s %i",SystemCallStringArray[2],shmem_ptr->discr_scalers.counters[11][counter]); } for (counter = 0; counter <4; counter++) { sprintf(SystemCallStringArray[2],"%s %i",SystemCallStringArray[2],shmem_ptr->discr_scalers.counters[12][counter]); } //printf("%s\n",SystemCallStringArray[2]); ThreadStatus = pthread_create(&array_threads[2], NULL, SystemCall, (void *) &SystemCallStringArray[2]); sprintf(epicsname,"TOF:disc:scalers:B:rate_wf"); sprintf(SystemCallStringArray[3],"caput -a %s 44 ",epicsname); for (counter = 4; counter <16; counter++) { sprintf(SystemCallStringArray[3],"%s %i",SystemCallStringArray[3],shmem_ptr->discr_scalers.counters[12][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[3],"%s %i",SystemCallStringArray[3],shmem_ptr->discr_scalers.counters[13][counter]); } for (counter = 0; counter <16; counter++) { sprintf(SystemCallStringArray[3],"%s %i",SystemCallStringArray[3],shmem_ptr->discr_scalers.counters[14][counter]); } //printf("%s\n",SystemCallStringArray[3]); ThreadStatus = pthread_create(&array_threads[3], NULL, SystemCall, (void *) &SystemCallStringArray[3]); pthread_join(array_threads[0],NULL); pthread_join(array_threads[1],NULL); pthread_join(array_threads[2],NULL); pthread_join(array_threads[3],NULL); //--------------------------------------------------------------------------------------------------- update_d_old=update_d; //printf("\n Update: %lu us. , UI=%d TT=%d \n",update_f,sizeof(unsigned int), sizeof(time_t)); } usleep(100); } } //----------------------------------------------------------------------------------- // Shared memory //----------------------------------------------------------------------------------- static void shmem_get() { if ( (semid=semget( SEM_ID1, 1, 0) ) < 0 ) { printf("shmem: can not get semaphore \n"); fflush(stdout); } if ( (shmid=shmget(SHM_ID1,sizeof(roc_shmem), 0))<0) { printf("==> shmem: shared memory 0x%x, size=%d get error=%d\n",SHM_ID1,sizeof(roc_shmem),shmid); fflush(stdout); exit(1); } if ( (shmem_ptr=(roc_shmem *) shmat (shmid, 0, 0))<0 ) { printf("==> shmem: shared memory attach error\n"); fflush(stdout); } printf("==> shmem: shared memory attached OK ptr=%p\n",shmem_ptr); fflush(stdout); //printf("===== wait semaphore ====== \n"); //fflush(stdout); //-- access to shmem -- //sem_wait(semid); // if (shmem_ptr) shmem_ptr->rol2_hist=1; //sem_post(semid); } //----------------------------------------------------------------------------------- // General system command //----------------------------------------------------------------------------------- void *SystemCall( void *argptr) { char *mySystemCallStringArray; mySystemCallStringArray = (char *) argptr; char command[255]; sprintf(command,"%s",mySystemCallStringArray); //printf(" %s\n",command); system(command); pthread_exit(NULL); } //----------------------------------------------------------------------------------- /* emacs * Local Variables: * mode:C++ * mode:font-lock * c-file-style: "stroustrup" * tab-width: 4 * End: */