diff options
author | Andy Green <andy.green@linaro.org> | 2012-10-11 17:47:29 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-10-11 17:47:29 +0800 |
commit | 020f93df6d6354a18e05a65707967ce53bba26e5 (patch) | |
tree | fab16c80d0ec12e8c330454bcb72738667d747bf /arm-probe | |
parent | 813f8f29a4f3322d2fc97ecf17c443e5ba66c29a (diff) |
issue libarmep results using shared mem from forked process
This decouples the AEP service and correction / trigger process from
the process that does something with the results. This allows an SMP
box to dedicate one core just for AEP service, with the other cores
free for whatever you're doing with the output. This allows scrolling
of stdout for 9 channels without causing AEP service underflow on this
laptop now.
The callback is also removed and the arm-probe code further simplified
with more handled in the library.
Signed-off-by: Andy Green <andy.green@linaro.org>
Diffstat (limited to 'arm-probe')
-rw-r--r-- | arm-probe/Makefile.am | 4 | ||||
-rw-r--r-- | arm-probe/arm-probe.c | 295 |
2 files changed, 103 insertions, 196 deletions
diff --git a/arm-probe/Makefile.am b/arm-probe/Makefile.am index 426ff71..1671740 100644 --- a/arm-probe/Makefile.am +++ b/arm-probe/Makefile.am @@ -1,6 +1,6 @@ bin_PROGRAMS=arm-probe arm_probe_SOURCES=arm-probe.c -arm_probe_CFLAGS=-fPIC -Wall -std=gnu99 -pedantic -arm_probe_LDFLAGS=-fPIC +arm_probe_CFLAGS=-fPIC -Wall -Werror -std=gnu99 -pedantic -pthread +arm_probe_LDFLAGS=-fPIC -pthread arm_probe_LDADD=-L../libarmep -larmep diff --git a/arm-probe/arm-probe.c b/arm-probe/arm-probe.c index 8c4077d..0b8453c 100644 --- a/arm-probe/arm-probe.c +++ b/arm-probe/arm-probe.c @@ -27,14 +27,8 @@ char stdinbuf[512]; char stdinline[512] = ""; int stdinpos = 0; int stdinlen = 0; -double do_average = 0; - -static void issue_samples(enum samples_actions sa, struct aep_channel *ch, - double voltage, double current); - struct aep_context aep_context = { - .samples = issue_samples, .config_filepath = "./config", .highest = -1, .decimate = 1, @@ -79,139 +73,8 @@ int get_stdin_line(char *buf, int maxlen) } } return -1; -} - -void add_pollfd(struct aep_context *aep_context, int fd, int events) -{ - aep_context->pollfds[aep_context->count_pollfds].fd = fd; - aep_context->pollfds[aep_context->count_pollfds].events = events; - aep_context->pollfds[aep_context->count_pollfds++].revents = 0; -} - -void remove_pollfd(struct aep_context *aep_context, int fd) -{ - int n; - - for (n = 0; n < aep_context->count_pollfds; n++) - if (aep_context->pollfds[n].fd == fd) { - while (n < aep_context->count_pollfds) { - aep_context->pollfds[n] = aep_context->pollfds[n + 1]; - n++; - } - aep_context->count_pollfds--; - } -} - - -/* - * this is the callback where the results appear - */ - -static void issue_samples(enum samples_actions sa, struct aep_channel *ch, - double voltage, double current) -{ - static int periodic; - static char titles[4096]; - static int pos; - - switch (sa) { - - case AEPSA_ADD_POLLFD: - add_pollfd(&aep_context, (int)voltage, (int)current); - break; - - case AEPSA_REMOVE_POLLFD: - remove_pollfd(&aep_context, (int)voltage); - break; - - case AEPSA_DATA_STARTING: - printf("#\n"); - pos = 0; - if (!stdinline[0]) - break; - printf("%s", stdinline); - get_stdin_line(stdinline, sizeof stdinline); - - break; - case AEPSA_DATA_STARTING_CHANNELS: - - printf("# %s\t%s\t%s\t%s\n", - ch->channel_name, ch->channel_name_pretty, ch->supply, ch->colour); - - if (just_power) - pos += sprintf(&titles[pos], " %s(W)", - ch->channel_name_pretty); - else - pos += sprintf(&titles[pos]," %s(V) %s(A) %s(W)", - ch->channel_name_pretty, - ch->channel_name_pretty, - ch->channel_name_pretty); - break; - - case AEPSA_DATA_STARTING_DONE: - printf("#\nsample"); - puts(titles); - break; - - case AEPSA_START_PRE: - periodic++; - if (periodic & 0x1ff) - break; - fprintf(stderr, "ARMED "); - break; - case AEPSA_SAMPLE_PRE: - if (periodic & 0x1ff) - break; - if (just_power) - fprintf(stderr, " %.5f", voltage * current); - else - fprintf(stderr, " %.2f %.4f %.5f", - voltage, current, voltage * current); - break; - case AEPSA_END_PRE: - if (periodic & 0x1ff) - break; - fprintf(stderr, "\n"); - break; - - case AEPSA_START: - periodic++; - if (stdinline[0]) { - printf("%s", stdinline); - if (get_stdin_line(stdinline, sizeof stdinline)) - stdinline[0] = '\0'; - } else - printf("%f", voltage); - if (periodic & 0x1ff) - break; - fprintf(stderr, "TRIGD "); - break; - case AEPSA_SAMPLE: - if (just_power) - printf(" %.5f", voltage * current); - else - printf(" %.2f %.4f %.5f", - voltage, current, voltage * current); - if (periodic & 0x1ff) - break; - if (just_power) - fprintf(stderr, " %.5f", voltage * current); - else - fprintf(stderr, " %.2f %.4f %.5f", - voltage, current, voltage * current); - break; - case AEPSA_END: - printf("\n"); - if (periodic & 0x1ff) - break; - fprintf(stderr, "\n"); - break; - } } - - - static struct option options[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, @@ -249,10 +112,11 @@ int main(int argc, char *argv[]) char hostname[200]; char date[200]; int n = 0; - struct aep_channel *ch; + int m, i; + int periodic = 0; double tt; - int m; - int i; + struct aep_result *aep_result; + int first = 1; loop = 1; @@ -265,7 +129,7 @@ int main(int argc, char *argv[]) continue; switch (n) { case 'a': - do_average = atof(optarg); + aep_context.do_average = atof(optarg); break; case 'z': fprintf(stderr, "\n\n *** Note: for autozero, you " @@ -415,6 +279,17 @@ int main(int argc, char *argv[]) } configure(&aep_context, NULL, "xx", aep_context.config_filepath, NULL); + + /* + * fork off the AEP service process + * runs in its own process to exploit SMP to dedicate one core for that + * what happens to samples is decoupled from capture process with large + * shared-memory buffer to allow for jitter + */ + + if (aep_init_and_fork(&aep_context) < 1) + return 0; /* child process exit */ + printf("# configuration: %s\n", aep_context.config_filepath); printf("# config_name: %s\n", aep_context.configuration_name); @@ -438,37 +313,86 @@ int main(int argc, char *argv[]) printf("#\n"); /* - * the main service loop + * service any AEP results */ - aep_context.poll_timeout_ms = 10; - init_interpolation(); - while (loop) { - n = poll(aep_context.pollfds, aep_context.count_pollfds, aep_context.poll_timeout_ms); - if (n < 0) - loop = 0; + aep_result = aep_wait_for_next_result(&aep_context); + if (!aep_result) { + if (aep_context.aep_shared->finished) + loop = 0; - for (n = 0; n < aep_context.count_pollfds; n++) - if (aep_context.pollfds[n].revents) - if (service_aeps(&aep_context, aep_context.pollfds[n].fd) < 0) - loop = 0; + continue; + } - if (service_aeps(&aep_context, -1) < 0) - loop = 0; + if (first) { + first = 0; + for (n = 0; n < aep_context.aep_shared->chans; n++) + printf("# %s\t%s\t%s\t%s\n", + aep_context.aep_shared->channel_name[n], + aep_context.aep_shared->channel_name_pretty[n], + aep_context.aep_shared->supply[n], + aep_context.aep_shared->colour[n]); + + printf("#\n#\ntime "); + for (n = 0; n < aep_context.aep_shared->chans; n++) + if (just_power) + printf(" %s(W)", aep_context.aep_shared->channel_name_pretty[n]); + else + printf(" %s(V) %s(A) %s(W)", + aep_context.aep_shared->channel_name_pretty[n], + aep_context.aep_shared->channel_name_pretty[n], + aep_context.aep_shared->channel_name_pretty[n]); + printf("\n"); + } + + periodic++; + if ((periodic & 0x1ff) == 0) { + if (aep_result->triggered) + fprintf(stderr, "TRIGD "); + else + fprintf(stderr, "ARMED "); + } + if (aep_result->triggered) + printf("%f ", aep_result->samtime); + for (i = 0; i < aep_result->chans * 2; i += 2) { + if (aep_result->triggered) { + if (just_power) + printf(" %.5f", aep_result->buf[i] * aep_result->buf[i + 1]); + else + printf(" %.2f %.4f %.5f", + aep_result->buf[i], aep_result->buf[i + 1], aep_result->buf[i] * aep_result->buf[i + 1]); + } + if (periodic & 0x1ff) + continue; + if (just_power) + fprintf(stderr, " %.5f", aep_result->buf[i] * aep_result->buf[i + 1]); + else + fprintf(stderr, " %.2f %.4f %.5f", + aep_result->buf[i], aep_result->buf[i + 1], aep_result->buf[i] * aep_result->buf[i + 1]); + } + if (aep_result->triggered) + printf("\n"); + + aep_free_result(&aep_context); + + if (periodic & 0x1ff) + continue; + fprintf(stderr, "\n"); } + aep_context.aep_shared->finished = 1; + /* * we are finished if we reach here... * append simple average to results if requested */ - if (aep_context.awaiting_capture == 0 && - aep_context.exit_after_capture && do_average) { + if (aep_context.do_average) { - tt = do_average; + tt = aep_context.do_average; for (m = 0; m < 2; m++) { @@ -479,21 +403,18 @@ int main(int argc, char *argv[]) } else printf("%f", tt); - for (n = 0; n <= aep_context.highest; n++) { - for (i = 0; i < CHANNELS_PER_PROBE; i++) { - ch = &aep_context.aeps[n].ch[i]; - if (just_power) - printf(" %.5f", ch->simple_avg[2] / ch->avg_count); - else - printf(" %.2f %.4f %.5f", - ch->simple_avg[0] / ch->avg_count, - ch->simple_avg[1] / ch->avg_count, - ch->simple_avg[2] / ch->avg_count); - } + for (n = 0; n <= aep_context.aep_shared->chans; n++) { + if (just_power) + printf(" %.5f", aep_context.aep_shared->averages[n][2]); + else + printf(" %.2f %.4f %.5f", + aep_context.aep_shared->averages[n][0], + aep_context.aep_shared->averages[n][1], + aep_context.aep_shared->averages[n][2]); } printf("\n"); - tt += do_average / 3; + tt += aep_context.do_average / 3; } } @@ -503,36 +424,22 @@ int main(int argc, char *argv[]) fprintf(stderr, "\n\n"); - for (m = 0; m <= aep_context.highest; m++) { - int i; + for (n = 0; n < aep_context.aep_shared->chans; n++) { - if (aep_context.aeps[m].fd <= 0) + if (aep_context.aep_shared->min[n][0] == 999) continue; - - for (i = 0; i < CHANNELS_PER_PROBE; i++) { - ch = &aep_context.aeps[m].ch[i]; - if (configure(&aep_context, &aep_context.aeps[m], - aep_context.aeps[m].dev_filepath, - aep_context.config_filepath, ch) < 0) - fprintf(stderr, "failed to update config\n"); - - if (ch->min[0] == 999) - continue; - - fprintf(stderr, "%12s: %4.2fV < %4.3fVavg < %4.2fV, " - "%6.4fA < %6.5fAavg < %6.4fA, " - "%9.6fW < %9.6fWavg < %9.6fW\n", - ch->channel_name, ch->min[0], - ch->simple_avg[0] / ch->avg_count, ch->max[0], - ch->min[1], - ch->simple_avg[1] / ch->avg_count, ch->max[1], - ch->min[2], - ch->simple_avg[2] / ch->avg_count, ch->max[2]); - } - probe_close(&aep_context.aeps[m]); + fprintf(stderr, "%12s: %4.2fV < %4.3fVavg < %4.2fV, " + "%6.4fA < %6.5fAavg < %6.4fA, " + "%9.6fW < %9.6fWavg < %9.6fW\n", + aep_context.aep_shared->channel_name[n], + aep_context.aep_shared->min[n][0], aep_context.aep_shared->averages[n][0], aep_context.aep_shared->max[n][0], + aep_context.aep_shared->min[n][1], aep_context.aep_shared->averages[n][1], aep_context.aep_shared->max[n][1], + aep_context.aep_shared->min[n][2], aep_context.aep_shared->averages[n][2], aep_context.aep_shared->max[n][2]); } + sem_close(aep_context.semaphore); + fprintf(stderr, "exited\n"); return 0; |