int main(int argc, char **argv) { // Setup setup_config(argc,argv); setup_state(); setup_sigs(); // Objects logger.setup(); server.setup(); sensor.setup(); heater.setup(); // Thread if(pthread_create( &serverThread, NULL, serverPoll, NULL) != 0) logger.fail("Server thread creation failure"); float chosenSetPoint; int sensorResult = 0; clock_t nextLoop; conf.update = 1000/conf.update; timeTick(); nextLoop = state.time + conf.update; logger.info("Starting up Coffeed"); while(state.run) { // Time update timeTick(); if(state.time >= nextLoop) { // Get sensor data sensorResult = sensor.update(); // If active choose set point if(state.active) { if(state.brewmode == TRUE) chosenSetPoint = conf.brewPoint; else chosenSetPoint = conf.steamPoint; // Sensor fault if(!sensorResult) { logger.fail("Sensor read failure"); state.active = FALSE; heater.off(); } // Tuning mode else if(state.tuning != FALSE) { // Begin if(state.tuning == 2) { state.tuning = TRUE; heater.setPower(50); aTune.cancel(); //aTune.setNoiseBand(1); //aTune.setOutputStep(50); //aTune.setLookbackSec(20); //aTune.setControlType(1); logger.info("Autotuning BEGIN %f %f %f",conf.pgain,conf.igain,conf.dgain); } // While (1) we want to tune + (2) update is not done else if(state.tuning == TRUE && aTune.update() == FALSE) { logger.info("tuning"); } // Tuning complete because state.tuning = TRUE but aTune == TRUE else { logger.info("tuning successful am I right?"); // Done conf.pgain = aTune.getKp(); conf.igain = aTune.getKi(); conf.dgain = aTune.getKd(); logger.info("Autotuning FINISH %f %f %f",conf.pgain,conf.igain,conf.dgain); state.tuning = FALSE; } } // Regular control else { // PID result state.pidResult = pid.result(chosenSetPoint, state.tempPoint); // Set Heater Duty heater.setPower( state.pidResult ); // Log logger.debug("PID Result %d temperature %f setP %f brewP %f steamP %f", state.pidResult, state.tempPoint, chosenSetPoint, conf.brewPoint, conf.steamPoint); } } // Inactive system else { // Tuning can't happen in a inactive system if(state.tuning != FALSE) { state.tuning = FALSE; aTune.cancel(); } if(state.brewmode) state.brewmode = TRUE; chosenSetPoint = 0; heater.off(); } // Get Heater Duty // This should be centralized to the heater state.power = heater.getPower(); // Schedule the next loop after the whole operation nextLoop = state.time + conf.update; } else { // Sleep until we need you usleep(1000 * (nextLoop - state.time)); } } logger.info("Shutting down Coffeed"); }
void do_child() { int rv; /* function return value */ int sig; /* current signal */ int cnt; p_p.result = TPASS; /* set up signal handlers for the signals */ if (setup_sigs(p_p.mesg) < 0) { p_p.result = TBROK; } else { /* all set up to catch signals, now hold them */ for (cnt = 0, sig = 1; sig < NUMSIGS; sig++) { if ((sig == 41) && !CRAYT3E && !SGI) { sig = 42; /* skip over SIGPEFAILURE for non-CRAYT3E systems */ } if ((sig != SIGCLD) && (sig != SIGKILL) && (sig != SIGALRM) && (sig != SIGSTOP) #ifdef SIGNOBDM && (sig != SIGNOBDM) #endif && (sig != SIGCANCEL) && (sig != SIGTIMER) ) { cnt++; TEST(sighold(sig)); rv = TEST_RETURN; if (rv != 0) { /* THEY say sighold ALWAYS returns 0 */ p_p.result = TFAIL; (void)sprintf(p_p.mesg, "sighold(%d) failed, rv:%d, errno:%d", sig, rv, errno); break; } } } if (STD_TIMING_ON) { p_p.rtimes = tblock; } if (p_p.result == TPASS) { sprintf(p_p.mesg, "Sighold called without error for %d of %d signals", cnt, NUMSIGS - 1); } } /* * write to parent (if not READY, parent will BROK) and * wait for parent to send signals. The timeout clock is set so * that we will not wait forever - if sighold() did its job, we * will not receive the signals. If sighold() blew it we will * catch a signal and the interrupt handler will exit(1). */ #if debug printf("child: %d writing to parent fd:%d\n", getpid(), CHILDSWRITEFD); #endif if (write_pipe(CHILDSWRITEFD) < 0 || p_p.result != TPASS) { exit(2); } /* * Read pipe from parent, that will tell us that all signals were sent */ if (read_pipe(CHILDSREADFD) != 0) { p_p.result = TBROK; strcpy(p_p.mesg, "read() pipe failed"); } else if (signals_received[0] == '\0') { p_p.result = TPASS; strcpy(p_p.mesg, "No signals trapped after being sent by parent"); } else { p_p.result = TFAIL; sprintf(p_p.mesg, "signals received: %s", signals_received); } if (write_pipe(CHILDSWRITEFD) < 0) { exit(2); } /* exit back to parent */ if (p_p.result == TPASS) exit(0); else exit(1); }
static int setup_env(void) { int noshr; int mpok = (g_opts.mode == mp); size_t siz = sizeof(struct shr_s); fputc('\n', stderr); #ifndef h_mingw /* setup signal handlers, initially block them */ if (setup_sigs(sigs_ign, SIG_IGN) < 0) return -1; if (setup_sigs(sigs_hnd, &sh_terminate) < 0) return -1; setup_sigmask(SIG_UNBLOCK, 0); #endif /* main shared chunk of memory with buffer, semaphores and so on */ if ((noshr = shmw_ctor(&g_chunk, "/yancat-main", &siz, 0, 0, 1)) < 0) return -1; mpok = mpok && !noshr; g_shm = (struct shr_s *)shmw_ptr(&g_chunk); memset(g_shm, 0, siz); /* * buffer object located in the above chunk; buffer itself allocates * main and bounce areas (if applicable) */ if ((noshr = buf_ctor(&g_shm->buf, g_opts.bsiz, g_opts.rblk, g_opts.wblk, g_opts.hpage)) < 0) { fprintf (stderr, "setup_env(): buffer initialization failed.\n"); goto out1; } g_buf = &g_shm->buf; if (buf_setextra(g_buf, g_opts.rline, g_opts.wline, g_opts.rcrc, g_opts.wcrc, g_opts.rsp, g_opts.wsp) < 0) goto out2; mpok = mpok && !noshr; /* update g_opts.mode to reflect the above) */ g_opts.mode = mpok ? mp : (g_opts.mode == mt ? mt : sp); #ifndef h_mingw if (g_opts.mode != sp) { if (mtxw_ctor(&g_shm->vars, "/yancat-vars", g_opts.mode == mp) < 0) goto out2; g_vars = &g_shm->vars; if (semw_ctor(&g_shm->nospace, "/yancat-nospace", g_opts.mode == mp, 0) < 0) goto out3; g_nospace = &g_shm->nospace; if (semw_ctor(&g_shm->nodata, "/yancat-nodata", g_opts.mode == mp, 0) < 0) goto out4; g_nodata = &g_shm->nodata; } #endif buf_report_init(g_buf); return 0; #ifndef h_mingw out4: semw_dtor(g_nospace); out3: mtxw_dtor(g_vars); #endif out2: buf_dtor(g_buf); out1: shmw_dtor(&g_chunk); return -1; }
/**************************************************************************** * child() : hold signals, notify parent and wait for parent to send signals. * If none were caught (sighold worked), release the signals one at a time * and wait for them to be caught. Send results back to parent * for processing. ***************************************************************************/ static void child() { int rv; /* return value from sighold() and sigrelse() */ int sig; /* signal value */ int exit_val; /* exit value to send to parent */ char note[MAXMESG]; /* message buffer for pipe */ char *str; phase = 1; /* tell handler that we do not want to catch signals */ /* set note to READY and if an error occurs, overwrite it */ (void)strcpy(note, READY); /* set alarm in case something hangs */ if (set_timeout() < 0) { /* an error occured - put mesg in note and send it back to parent */ (void)strcpy(note, mesg); } else if (setup_sigs() < 0) { /* an error occured - put mesg in note and send it back to parent */ (void)strcpy(note, mesg); } else { /* all set up to catch signals, now hold them */ for (sig = 1; sig < NUMSIGS; sig++) { if (choose_sig(sig)) { if ((rv = sighold(sig)) != 0) { /* THEY say sighold ALWAYS returns 0 */ (void)sprintf(note, "sighold did not return 0. rv:%d", rv); break; } } } } /* * send note to parent (if not READY, parent will BROK) and * wait for parent to send signals. The timeout clock is set so * that we will not wait forever - if sighold() did its job, we * will not receive the signals. If sighold() blew it we will * catch a signal and the interrupt handler will exit with a * value of SIG_CAUGHT. */ if (write_pipe(pipe_fd[1], note) < 0) { /* * write_pipe() failed. Set exit value to WRITE_BROK to let * parent know what happened */ clear_timeout(); exit(WRITE_BROK); } /* * if we get to this point, all signals have been held and the * timer has expired. Now what we want to do is release each * signal and see if we catch it. If we catch all signals, * sigrelse passed, else it failed. */ phase = 2; /* let handler know we are now expecting signals */ #if DEBUG > 0 printf("child: PHASE II\n"); #endif /* assume success and overwrite exit_val if an error occurs */ exit_val = EXIT_OK; #if DEBUG > 0 printf("child: pid=%d waiting for parent's ready...\n", getpid()); #endif /* * wait for parent to tell us that sigals were all sent */ /* wait for "ready" message from parent */ if ((str = read_pipe(pipe_fd2[0])) == NULL) { /* read_pipe() failed. */ printf(" child: read_pipe failed\n"); exit(TBROK); } if (strcmp(str, READY) != 0) { /* parent/pipe problem */ printf("child: didn't proper ready message\n"); exit(TBROK); } for (sig = 1; sig < NUMSIGS; sig++) { if (choose_sig(sig)) { /* all set up, release and catch a signal */ sig_caught = FALSE; /* handler sets it to TRUE when caught */ #if DEBUG > 1 printf("child: releasing sig %d...\n", sig); #endif if ((rv = sigrelse(sig)) != 0) { /* THEY say sigrelse ALWAYS returns 0 */ (void)sprintf(note, "sigrelse did not return 0. rv:%d", rv); exit_val = TBROK; break; } /* give signal handler some time to process signal */ wait_a_while (); } } /* endfor */ /* * If we are error free so far... * check the sig_array array for one occurence of * each of the catchable signals. If this is true, * then PASS, otherwise FAIL. */ if (exit_val == EXIT_OK) { (void)memcpy(note, (char *)sig_array, sizeof(sig_array)); } /* send note to parent and exit */ if (write_pipe(pipe_fd[1], note) < 0) { /* * write_pipe() failed. Set exit value to WRITE_BROK to let * parent know what happened */ exit(WRITE_BROK); } exit(exit_val); } /* end of child */