/* helloSendData.c */ #include #include "pscomm.h" #ifdef PS_RT_LINUX # include "/usr/src/rtlinux-2.2/drivers/mbuff/mbuff.h" #endif #ifndef PS_RT_LINUX # include # include #endif volatile char * shm1, *shm2, *shmControl; #ifndef PS_RT_LINUX int shm1id, shm2id, shmcid; #endif static struct TimeTable tt; // initialization procedure int ps_init(void) { #ifndef PS_RT_LINUX int shmflg; fprintf(stdout,"LINUX PACKET SENDER INIT\n"); // Create shm segment shmflg = IPC_CREAT | 511; shm1id = shmget(SHM1_KEY, sizeof(tt), shmflg); shm2id = shmget(SHM2_KEY, sizeof(tt), shmflg); shmcid = shmget(SHMC_KEY, 1024, shmflg); if ((shm1id < 0) || (shm2id < 0) || (shmcid < 0)) return -1; // attach shm shm1 = shmat(shm1id, NULL, 0); shm2 = shmat(shm2id, NULL, 0); shmControl = shmat(shmcid, NULL, 0); // try to prevent swapping - works only for super-user shmctl(shm1id, SHM_LOCK, 0); shmctl(shm2id, SHM_LOCK, 0); shmctl(shmcid, SHM_LOCK, 0); #endif #ifdef PS_RT_LINUX // if RT-Linux fprintf(stdout,"RT-LINUX PACKET SENDER INIT\n"); // Shared memory alloc shm1 = (volatile char*) mbuff_alloc("tt1",sizeof(tt)); shm2 = (volatile char*) mbuff_alloc("tt2",sizeof(tt)); if( shm1 == NULL || shm2 == NULL ) { //fprintf(stderr,"mbuff_alloc failed\n"); return -1; } shmControl = (volatile char*) mbuff_alloc("control",1024); if( shmControl == NULL) { //fprintf(stderr,"mbuff_alloc failed\n"); return -1; } #endif return 0; } int ps_getptrs(volatile char **shm1p, volatile char **shm2p, volatile char **shmControlp) { shm1p[0] = shm1; shm2p[0] = shm2; shmControlp[0] = shmControl; if ( shm1 == NULL || shm2 == NULL || shmControl == NULL) return -1; return 0; } // sends one time table to the packet sender int ps_send(struct TimeTable *ttptr) { int ret = 0; int sent = 0; while( sent != 1) { // Wait for control info if (shmControl[0] == ACK) usleep(9000); if (shmControl[0] == URG_REQ_1 ) { // Sent DATA was late // the sending process had to wait for the reading of new timing information //fprintf(stderr,"Late 1\n"); shmControl[0] = REQ_1; // Something should be done to avoid this if possible ret = 1; } if (shmControl[0] == URG_REQ_2 ) { // Sent DATA was late // the sending process had to wait for the reading of new timing information //fprintf(stderr,"Late 2\n"); shmControl[0] = REQ_2; // Something should be done to avoid this if possible ret = 1; } if ( shmControl[0] == REQ_1 ) { sent++; // Send data memcpy((void *)shm1,ttptr,sizeof(tt)); fprintf(stderr,"%i bytes written\n", sizeof(tt)); shmControl[0] = ACK; } else if ( shmControl[0] == REQ_2 ) { sent++; // Send data memcpy((void *)shm2,ttptr,sizeof(tt)); fprintf(stderr,"%i bytes written\n", sizeof(tt)); shmControl[0] = ACK; } else if ( shmControl[0] != ACK ) { fprintf(stderr,"%c - Unexpected control info\n", shmControl[0]); ret = -1; sent = 1; } } return ret; } // cleanup int ps_cleanup(void) { #ifndef PS_RT_LINUX struct shmid_ds shmid_ds_buf; // detach sgm shmdt((char*)shm1); shmdt((char*)shm2); shmdt((char*)shmControl); // check shm status shmctl(shm1id, IPC_STAT, &shmid_ds_buf); if (shmid_ds_buf.shm_nattch == 0) { // destroy shm segment shmctl(shm1id, IPC_RMID, 0); } // check shm status shmctl(shm2id, IPC_STAT, &shmid_ds_buf); if (shmid_ds_buf.shm_nattch == 0) { // destroy shm segment shmctl(shm2id, IPC_RMID, 0); } // check shm status shmctl(shmcid, IPC_STAT, &shmid_ds_buf); if (shmid_ds_buf.shm_nattch == 0) { // destroy shm segment shmctl(shmcid, IPC_RMID, 0); } #endif #ifdef PS_RT_LINUX // if RT-Linux // Free shared memory mbuff_free("tt1",(void*)shm1); mbuff_free("tt2",(void*)shm2); mbuff_free("control",(void*)shmControl); #endif return 0; }