/* load shared memory from backup */ int ipc_load(_IPC_DAT *ipc_ptr) { int rtn; FILE *ipc_bkup; ipc_bkup = fopen(_IPC_FILE_BACKUP_NAME,"r+"); if(ipc_bkup == NULL){ // file not found return 1; } ipc_sem_lock(semid, &sb); // wait for a lock on shared memory rtn = fread(ipc_ptr, sizeof(*ipc_ptr), 1, ipc_bkup); if(rtn != 1){ printf("\n*** error reading ipc backup data\n fread returned %i\r\n",rtn); perror(_TRACE_FILE_NAME); ipc_sem_free(semid, &sb); // free lock on shared memory return 1; } else ipc_sem_free(semid, &sb); // free lock on shared memory #if defined (_ATRACE) || defined (_PTRACE) trace(_TRACE_FILE_NAME, "\nipc", 0, NULL, "backup ipc file written to shared memory\n", 0); #endif return 0; }
int ipc_save(_IPC_DAT *ipc_ptr) { FILE *ipc_bkup; // int write_rtn; ipc_bkup = fopen(_IPC_FILE_BACKUP_NAME,"w"); if(ipc_bkup == NULL){ // file not found perror(_IPC_FILE_BACKUP_NAME); return 1; } ipc_sem_lock(semid, &sb); // wait for a lock on shared memory if(fwrite(ipc_ptr, 1, sizeof(*ipc_ptr), ipc_bkup) != sizeof(*ipc_ptr)){ printf("\n*** error saving ipc backup data file\r\n"); perror(_IPC_FILE_BACKUP_NAME); ipc_sem_free(semid, &sb); // free lock on shared memory fclose(ipc_bkup); return 1; } else ipc_sem_free(semid, &sb); // free lock on shared memory #if defined (_ATRACE) || defined (_PTRACE) trace(_TRACE_FILE_NAME, "\nipc", 0, NULL, "ipc data written to backup file\n", 0); #endif fclose(ipc_bkup); return 0; }
int ioctl_sem_lock(struct ipc_driver *drv, unsigned long arg) { int error = 0; struct ipc_lock_t ipc_param; if(copy_from_user(&ipc_param, (void *)arg, sizeof(struct ipc_lock_t))) { err_msg(err_trace, "%s(): Error in copy_from_user()\n", __FUNCTION__); error = -EFAULT; goto do_exit; } error = ipc_sem_lock( drv, &ipc_param ); if(error < 0) { err_msg(err_trace, "%s(): Error in ipc_sem_down()\n", __FUNCTION__); goto do_exit; } do_exit: return error; }
int main(void) { int i; // char *ppp; /************************ initializations ****************************/ /* set up file mapped shared memory for inter process communication */ ipc_sem_init(); // setup semaphores semid = ipc_sem_id(skey); // set semaphor id /* set up shared memory */ ipc_sem_lock(semid, &sb); // wait for a lock on shared memory fd = ipc_open(ipc_file, ipc_size()); // create/open ipc file data = ipc_map(fd, ipc_size()); // map file to memory ipc_ptr = data; // overlay data with _IPC_DAT data structure ipc_sem_free(semid, &sb); // free lock on shared memory /* setup control block pointers */ cmd_fsm_cb.ipc_ptr = ipc_ptr; // set pointer to shared memory cmd_fsm_cb.sys_ptr = &(ipc_ptr->sys_data); // set pointer to system data in shared memory cmd_fsm_cb.ssch_ptr = &ipc_ptr->sys_data.sys_sch; // set pointer to active shecule in shared memory cmd_fsm_cb.wsch_ptr = &cmd_fsm_cb.w_sch; // set pointer to working schedule /* check system versions */ if (sys_comp(&(ipc_ptr->sys_data.config))) { printf("*** the system configuration in shared memory and in the application are different\n update shared memory? (y)|(n) > "); if (getchar() == 'y') { ipc_ptr->sys_data.config.major_version = _MAJOR_VERSION_system; ipc_ptr->sys_data.config.minor_version = _MINOR_VERSION_system; ipc_ptr->sys_data.config.minor_revision = _MINOR_REVISION_system; ipc_ptr->sys_data.config.channels = _NUMBER_OF_CHANNELS; ipc_ptr->sys_data.config.sensors = _NUMBER_OF_SENSORS; ipc_ptr->sys_data.config.commands = _CMD_TOKENS; ipc_ptr->sys_data.config.states = _CMD_STATES; c = fgetc(stdin); // get rid of trailing CR } else { c = fgetc(stdin); // get rid of trailing CR printf("*** application terminated\n"); exit(1); } } /* load working schedule from system schedule */ ipc_sem_lock(semid, &sb); // wait for a lock on shared memory cmd_fsm_cb.w_sch = ipc_ptr->sys_data.sys_sch; ipc_sem_free(semid, &sb); // free lock on shared memory /* initialize working sensor name and description */ cmd_fsm_cb.w_sen_dat.group[0] = '\0'; cmd_fsm_cb.w_sen_dat.description[0] = '\0'; cmd_fsm_cb.w_sen_dat.description[1] = '\0'; /* initialize state machines */ cmd_fsm_reset(&cmd_fsm_cb); // initialize the command processor fsm char_fsm_reset(); // initialize the character fsm char_state = 0; /* initialize input buffer */ memset(work_buffer, '\0', sizeof(work_buffer)); work_buffer_ptr = work_buffer; start_buff = work_buffer; input_ptr = work_buffer; end_buff = (char *)((int)start_buff + _INPUT_BUFFER_SIZE); escape = false; /* initialize ring buffer & indexs*/ for (i = 0; i < _CMD_BUFFER_DEPTH; i++) memset(&ring_buffer[i][0], '\0', _INPUT_BUFFER_SIZE); rb_in_idx = 0; rb_out_idx = 0; /* set up unbuffered io */ fflush(stdout); system("stty -echo"); //turn off terminal echo system("/bin/stty raw"); // use system call to make terminal send all keystrokes directly to stdin int flags = fcntl(STDOUT_FILENO, F_GETFL); fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK); escape = false; /* initialize user interface */ printf("Pcon %d.%d.%d starting\n\r", _MAJOR_VERSION_Pcon, _MINOR_VERSION_Pcon, _MINOR_REVISION_Pcon); printf("\nSystem configuration\r\n"); printf(" Git tag - %s\r\n", _TAG); printf(" Inter Process Commucination support %d.%d.%d\n\r", _MAJOR_VERSION_ipc, _MINOR_VERSION_ipc, _MINOR_REVISION_ipc); printf(" Dcon version %d.%d.%d\n\r", _MAJOR_VERSION_Dcon, _MINOR_VERSION_Dcon, _MINOR_REVISION_Dcon); printf(" Scon version %d.%d.%d\n\r", _MAJOR_VERSION_Scon, _MINOR_VERSION_Scon, _MINOR_REVISION_Scon); printf(" Pcon version %d.%d.%d\n\r", _MAJOR_VERSION_Pcon, _MINOR_VERSION_Pcon, _MINOR_REVISION_Pcon); printf(" char_fsm version %d.%d.%d\n\r", _MAJOR_VERSION_char_fsm, _MINOR_VERSION_char_fsm, _MINOR_REVISION_char_fsm); printf(" cmd_fsm version %d.%d.%d\n\n\r", _MAJOR_VERSION_cmd_fsm, _MINOR_VERSION_cmd_fsm, _MINOR_REVISION_cmd_fsm); printf("initializations complete\r\n\nenter ? for a list of commands\r\n\n"); /* set initial prompt */ strcpy(cmd_fsm_cb.prompt_buffer, "Pcon enter a command"); /************************************************************/ /**************** start main processing loop ****************/ /************************************************************/ while (1) { while (pop_cmd_q(cmd_fsm_cb.token)) // check the token queue { cmd_fsm(&cmd_fsm_cb); // cycle cmd fsm until queue is empty prompted = false; } if (prompted == false) // display prompt if necessary { prompted = true; prompt(cmd_fsm_cb.state); } c = fgetc(stdin); // read the keyboard switch (c) { /* NOCR */ case _NO_CHAR: break; /* ESC */ case _ESC: c = fgetc(stdin); // skip to next character c = fgetc(stdin); // skip to next character switch (c) { /* up arrow */ case 'A': if (rb_out_idx > 0) rb_out_idx--; else rb_out_idx = rb_in_idx - 1; if (rb_out_idx >= rb_in_idx) rb_out_idx = 0; arrow_reprompt(); continue; break; /* down arrow */case 'B': rb_out_idx++; if (rb_out_idx >= rb_in_idx) rb_out_idx = 0; arrow_reprompt(); continue; break; /* right arrow */case 'C': if (input_ptr < work_buffer_ptr) { input_ptr++; printf("\033[1C"); // move cursor right } continue; break; /* left arrow */case 'D': if (input_ptr > start_buff) { input_ptr--; printf("\033[1D"); // move cursor left } continue; break; /* ESC */ default: escape = true; while (pop_cmd_q(cmd_fsm_cb.token)); // empty command queue memset(work_buffer, '\0', sizeof(work_buffer)); // clean out work buffer memset(previous_work_buffer, '\0', sizeof(work_buffer)); // clean out previous command buffer work_buffer_ptr = work_buffer; // set pointer to start of buffer input_ptr = work_buffer; // set pointer to start of buffer char_fsm_reset(); // initialize the character fsm cmd_fsm_reset(&cmd_fsm_cb); // initialize the command processor fsm char_state = 0; prompted = false; // force a prompt printf("\n\rcommand processor reset\n\r"); strcpy(cmd_fsm_cb.prompt_buffer, "enter a command"); continue; break; } /* CR */ case _CR: if (work_buffer_ptr != start_buff) // skip null input lines { if (strcmp(work_buffer, previous_work_buffer) != 0) // remove duplicates { strcpy(&ring_buffer[rb_in_idx++][0], work_buffer); if (rb_in_idx > _CMD_BUFFER_DEPTH - 1) rb_in_idx = 0; rb_out_idx = rb_in_idx; memset(previous_work_buffer, '\0', sizeof(work_buffer)); strcpy(previous_work_buffer, work_buffer); } } printf("\n\r"); // move cursor to next line *work_buffer_ptr++ = _CR; // load the CR into the work buffer *work_buffer_ptr++ = '\0'; // load the NULL into the work buffer work_buffer_ptr = work_buffer; // reset pointer char_fsm_reset(); // reset char_fsm while (*work_buffer_ptr != '\0') // send characters to char_fsm { char_fsm(char_type(*work_buffer_ptr), &char_state, work_buffer_ptr); work_buffer_ptr++; } work_buffer_ptr = work_buffer; // reset pointer input_ptr = work_buffer_ptr; // reset pointer memset(work_buffer, '\0', sizeof(work_buffer)); memset(screen_buf, '\0', sizeof(screen_buf)); memset(&ring_buffer[rb_in_idx][0], '\0', _INPUT_BUFFER_SIZE); break; /* DEL */ case _DEL: if (input_ptr == start_buff) break; if (input_ptr == work_buffer_ptr) { // no arrow keys in play *work_buffer_ptr-- = '\0'; *work_buffer_ptr = '\0'; input_ptr = work_buffer_ptr; printf("\r"); del_prompt(cmd_fsm_cb.state); // display user prompt printf("%s", work_buffer); // print work_buffer printf("\033[K"); // Erase to end of line prompted = true; } else { mv = work_buffer_ptr - input_ptr; input_ptr--; hptr = input_ptr; while (input_ptr < work_buffer_ptr) // shift buffer left { *input_ptr = *(input_ptr + 1); input_ptr++; } input_ptr = hptr; *work_buffer_ptr-- = '\0'; *work_buffer_ptr = '\0'; printf("\r"); printf("\033[K"); // Erase to end of line del_prompt(cmd_fsm_cb.state); printf("%s", work_buffer); while (mv > 0) { printf("\033[1D"); // move cursor left mv--; } } break; /* OTHER */ default: if (work_buffer_ptr <= end_buff) // room to add character ? { if (input_ptr == work_buffer_ptr) // cursor is at the end of the input buffer { *work_buffer_ptr++ = c; input_ptr = work_buffer_ptr; printf("%c", c); } else // cursor is not at the end of the input buffer { move_ptr = work_buffer_ptr++; move_ptr++; *move_ptr-- = '\0'; while (move_ptr > input_ptr) { *move_ptr = *(move_ptr - 1); move_ptr--; } *input_ptr++ = c; mv = work_buffer_ptr - input_ptr; printf("\r"); printf("\033[K"); // Erase to end of line prompt(cmd_fsm_cb.state); printf("%s", work_buffer); while (mv > 0) { printf("\033[1D"); // move cursor left mv--; } } } } /* do suff while waiting or the keyboard */ } system("/bin/stty cooked"); //switch to buffered iput system("/bin/stty echo"); //turn on terminal echo printf("\f\n***normal termination - but should not happen\n\n"); return 0; }
int test_ipc_sem(enum ipc_sem_type type, void* arg) { ipc_sem sem = NULL; pid_t p = -1; struct tm* timeinfo = NULL; time_t timeo; char buf[256]; if(!ipc_sem_is_supported(type)) { fprintf(stderr, "Semaphore type %d not supported!\n", type); return -1; } sem = ipc_sem_new(type, arg, O_CREAT, 0700, 1); if(!sem) { perror("ipc_sem_new"); return -1; } p = fork(); if(p == -1) { perror("fork"); ipc_sem_free(&sem, 1); return -1; } else if(p > 0) { int status = -1; /* father */ sleep(1); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[FATHER] Try to lock semaphore\n", buf); ipc_sem_lock(sem); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[FATHER] Semaphore locked\n", buf); ipc_sem_unlock(sem); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[FATHER] Semaphore unlocked\n", buf); /* wait son termination */ wait(&status); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[FATHER] Son terminated\n", buf); fprintf(stdout, "Test OK!\n"); } else { /* son */ time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[SON] Try to lock semaphore\n", buf); ipc_sem_lock(sem); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[SON] Semaphore locked\n", buf); sleep(3); ipc_sem_unlock(sem); time(&timeo); timeinfo = localtime(&timeo); sprintf(buf, "[%d %d %d %d:%d:%d]", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); fprintf(stdout, "%s[SON] Semaphore unlocked\n", buf); } ipc_sem_free(&sem, 1); return 0; }