1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#include <linux/module.h>
#include <linux/kernel.h>
#include <rtl_fifo.h>
#include <asm/rt_irq.h>
#include <asm/rt_time.h>
#include <rtl_sched.h>
#include <asm/io.h>
#include <linux/cons.h>
#include "common.h"
/* all of these parameters can be changed with insmod */
int latency_oneshot = 25;
int latency_periodic = 10;
int minimize_jitter = 0;
int skip = 10000;
int period = 500;
int periodic_mode = 0;
MODULE_PARM(minimize_jitter,"i");
MODULE_PARM(period,"i");
MODULE_PARM(skip,"i");
MODULE_PARM(periodic_mode,"i");
RT_TASK tsk;
RTIME min_diff;
RTIME max_diff;
RTIME expected;
void fun(int t) {
RTIME diff,now;
int i;
struct sample samp;
if (minimize_jitter) {
r_cli(); /* Be careful with this! The task won't be preempted by anything else. This is probably only appropriate for small high-priority tasks. */
}
while (1) {
min_diff = 100000; max_diff = -100000;
for (i = 0; i < skip; i++) {
now = rt_get_time();
if (minimize_jitter) {
if (now < expected) {
rt_delay (expected - now);
}
now = rt_get_time();
}
diff = now - expected;
if (diff < min_diff) {
min_diff = diff;
}
if (diff > max_diff) {
max_diff = diff;
}
expected += period;
rt_task_wait();
}
samp.min = min_diff;
samp.max = max_diff;
rtf_put(0, &samp, sizeof(samp));
}
}
int init_module(void)
{
RTIME advance;
RTIME t;
min_diff = 1000000000;
max_diff = -1000000000;
conpr ("Starting measurement module\n");
rtf_create(0, 4000);
rt_task_init(&tsk, fun, 1, 3000, 1);
if (periodic_mode) {
t = rtl_set_periodic_mode (period);
if (t == RT_TIME_END) {
conpr("Setting periodic mode failed\n");
periodic_mode = 0;
}
}
if (periodic_mode) {
expected = t + 2 * period;
advance = latency_periodic;
} else {
rtl_set_oneshot_mode();
expected = rt_get_time() + 2 * period;
advance = latency_oneshot;
}
if (minimize_jitter) {
rt_task_make_periodic(&tsk, expected - advance, period);
} else {
rt_task_make_periodic(&tsk, expected, period);
}
return 0;
}
void cleanup_module(void)
{
rt_task_delete(&tsk);
rtf_destroy(0);
}
|