/** * \file camera_test.c * \brief Test camera.[ch] state machine. * * \Author Ferdi Franceschini February 2013 */ #include #include #include #include "camera.h" void print_state(state_t s) { char *cl, *cm, *dr; cm = SCM_NAMES[s.cm]; cl = SCL_NAMES[s.cl]; dr = SDR_NAMES[s.dr]; printf("%s,%s,%s", cm, cl, dr); } void print_event(event_t E) { char *ca, *cm, *cd, *dr, *cl; ca = event_names[E.ca]; cm = event_names[E.cm]; cd = event_names[E.cd]; dr = event_names[E.dr]; cl = event_names[E.cl]; printf("%s,%s,%s,%s,%s", ca, cm, cd, dr, cl); } event_t output(state_t Sc, enum event_codes Ei) { int i; trans_t tr; event_t Eo; for (i=0; tr=TRANS_TABLE[i], tr.Sc.dr!= END_TABLE; i++) { if (Ei==tr.Ei && INSYS(Sc,tr.Sc)) { EVset(&Eo,tr.Eo); } } return Eo; } int test_camrep2sym(void) { int i, cm_sym, time_rem, time_tot; enum event_codes ca_sym; char *camrep[] = { "StartTime Remaining= 3907 ms, Total Time=3686 ms,", "Open ShutrTime Remaining= 539454 ms, Total Time=3686 ms,", "Acq ImageTime Remaining= 109 ms, Total Time=3686 ms,", "Close ShutrTime Remaining= 218 ms, Total Time=3686 ms,", "Read ImageTime Remaining= 328 ms, Total Time=3686 ms,", "Read ImageTime Remaining= 328 ms, Total Time=3686 ms,", "Read ImageTime Remaining= 328 ms, Total Time=3686 ms,", "Idle", NULL }; fprintf(stderr, "TEST_CAMREP2SYM:DESCRIPTION: Parse camera status messages and convert them to camera events and camera model events\n"); fprintf(stderr, "TEST_CAMREP2SYM:DESCRIPTION: Output format = 'status message' => camera_symbol => camera_model_symbol\n"); fprintf(stderr, "TEST_CAMREP2SYM:OUTPUT:START\n"); for (i=0; camrep[i] != NULL; i++) { if ( cam_parse_status(camrep[i], &ca_sym, &time_rem, &time_tot) == -1) exit(1); else { cm_sym = camera_model(ca_sym); if (ECA_IDLE==ca_sym) printf("'%s' => %s => %s\n", camrep[i], event_names[ca_sym], event_names[cm_sym]); else printf("'%s' => %s => %s: time remaining = %d, total time = %d\n", camrep[i], event_names[ca_sym], event_names[cm_sym], time_rem, time_tot); } } fprintf(stderr, "TEST_CAMREP2SYM:OUTPUT:END\n\n"); return 1; } int test_trans_fn(void) { int i; event_t Eo={0,0,0,0,0}; state_t Sc = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE}; int input[] = { ECM_IDLE, ECD_TK_SHOT, ECM_IDLE, ECM_IDLE, ECM_ACQ, ECD_TK_SHOT, ECM_PROC, ECD_TK_SHOT, ECM_PROC, ECM_IDLE, ECM_ACQ, ECM_PROC, ECM_IDLE, 0 }; fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: Test the state transitions. Each line of ouput has three fields.\n"); fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: Output pattern ~= Ein Scurr Eout\n"); fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: You can follow the transitions by reading down the Scurr column\n"); fprintf(stderr, "TEST_TRANS_FN:OUTPUT:START\n"); printf("INPUT,\tCURR SCM,CURR SCL,CURR SDR,\tCA OUT,CM OUT,CD OUT,DR OUT\n"); for (i=0; input[i]; i++) { EVclr(&Eo); printf("%s,\t",event_names[input[i]]); print_state(Sc); cam_trans_fn(Sc, input[i], &Sc, &Eo); printf(",\t"); print_event(Eo); printf("\n"); if (Eo.cl) { /* TODO Handle feedback in the general case where there may be multiple events in Eo to feed back into the transition function */ printf("%s,\t",event_names[Eo.cl]); print_state(Sc); cam_trans_fn(Sc, Eo.cl, &Sc, &Eo); printf(",\t"); print_event(Eo); printf("\n"); } } fprintf(stderr, "TEST_TRANS_FN:OUTPUT:END\n"); return 1; } int camdriv_out(void *me, event_t Eo) { int *self = me; *self=0; /* shudduppa your warnings */ if (Eo.ca) { printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.ca], event_signatures[Eo.ca]); } if (Eo.cm) { printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cm], event_signatures[Eo.cm]); } if (Eo.cd) { printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cd], event_signatures[Eo.cd]); } if (Eo.dr) { printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.dr], event_signatures[Eo.dr]); } if (Eo.cl) { printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cl], event_signatures[Eo.cl]); } return -1; } int test_camdriv_event_io(void) { int Ein=ECD_TK_SHOT; int self; camsm_t cdinfo = { .Sc = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE}, .Eo = {.ca=0}, .multi = 0, .output_fn = camdriv_out, }; fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:DESCRIPTION: Test State machine output_fn callback\n"); fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:DESCRIPTION: Output pattern ~= Ein:Scurr:Eo:output message\n"); fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:OUPUT:START\n"); printf("input: %s :", event_names[Ein]); print_state(cdinfo.Sc); printf("\n"); camdriv_input(&self, &cdinfo, Ein); Ein = ECM_IDLE; printf("input: %s :", event_names[Ein]); cdinfo.Sc.cl=SCL_TK_SHOT; print_state(cdinfo.Sc); printf("\n"); camdriv_input(&self, &cdinfo, Ein); fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:OUPUT:END\n"); return 1; } char *tests[] = {"camrep2sym", "trans_fn", "camdriv_input"}; void usage(char *name) { int i; printf("Usage: %s [n]\n",name); printf("default: run all tests\n"); printf("n is an int whose bits indicate which tests will be executed as follows\n"); for (i=0; i<3; i++) printf("n=%d; %s\n",1 << i, tests[i]); printf("\n"); } int main(int argc, char *argv[]) { int ret, test=0, tflag=7; if (argc == 1) test = tflag; else if (strstr(argv[1], "help")) { usage(argv[0]); return 0; } else test = atoi(argv[1]); if ((test < 1) || (test > tflag)) { printf("ERROR: Argument must be a positive integer between 1 and %d inclusive\n", tflag); usage(argv[0]); return 1; } if (test & 1) ret = test_camrep2sym(); if (test & 2) ret = test_trans_fn(); if (test & 4) ret = test_camdriv_event_io(); if (ret) return 0; else return 1; }