1 /****************************************************************************** |
|
2 * |
|
3 * msr_jitter.c |
|
4 * |
|
5 * Autor: Wilhelm Hagemeister |
|
6 * |
|
7 * (C) Copyright IgH 2002 |
|
8 * Ingenieurgemeinschaft IgH |
|
9 * Heinz-Bäcker Str. 34 |
|
10 * D-45356 Essen |
|
11 * Tel.: +49 201/61 99 31 |
|
12 * Fax.: +49 201/61 98 36 |
|
13 * E-mail: hm@igh-essen.com |
|
14 * |
|
15 * $Id$ |
|
16 * |
|
17 *****************************************************************************/ |
|
18 |
|
19 #ifndef __KERNEL__ |
|
20 # define __KERNEL__ |
|
21 #endif |
|
22 #ifndef MODULE |
|
23 # define MODULE |
|
24 #endif |
|
25 |
|
26 #include <linux/config.h> |
|
27 #include <linux/module.h> |
|
28 #include <linux/sched.h> |
|
29 #include <linux/kernel.h> |
|
30 #include <asm/msr.h> /* maschine-specific registers */ |
|
31 #include <linux/param.h> /* fuer HZ */ |
|
32 |
|
33 #include <msr_reg.h> |
|
34 #include "msr_jitter.h" |
|
35 |
|
36 /*--includes-----------------------------------------------------------------*/ |
|
37 |
|
38 /*--external functions-------------------------------------------------------*/ |
|
39 |
|
40 /*--external data------------------------------------------------------------*/ |
|
41 |
|
42 /*--public data--------------------------------------------------------------*/ |
|
43 |
|
44 /*--local data---------------------------------------------------------------*/ |
|
45 |
|
46 #define NUMCLASSES 16 |
|
47 |
|
48 static int jittime[NUMCLASSES]={0,1,2,5,10,20,50,100,200,500, |
|
49 1000,2000,5000,10000,20000,50000}; //in usec |
|
50 static int jitcount[NUMCLASSES]; |
|
51 static double jitpercent[NUMCLASSES]; |
|
52 static unsigned int tcount = 1; |
|
53 |
|
54 static void msr_jit_read(void) |
|
55 { |
|
56 int i; |
|
57 for(i=0;i<NUMCLASSES;i++) { |
|
58 if(tcount >100) { |
|
59 jitpercent[i] = jitcount[i]*100.0/tcount; |
|
60 } |
|
61 } |
|
62 } |
|
63 |
|
64 void msr_jitter_init(void) |
|
65 { |
|
66 msr_reg_int_list("/Taskinfo/Jitter/Classes","usec", |
|
67 &jittime[0],MSR_R,NUMCLASSES,NULL,NULL,NULL); |
|
68 msr_reg_int_list("/Taskinfo/Jitter/Count","", |
|
69 &jitcount[0],MSR_R,NUMCLASSES,NULL,NULL,NULL); |
|
70 msr_reg_dbl_list("/Taskinfo/Jitter/percent","%", |
|
71 &jitpercent[0],MSR_R,NUMCLASSES,NULL,NULL,&msr_jit_read); |
|
72 } |
|
73 |
|
74 /****************************************************************************** |
|
75 * |
|
76 * Function: msr_jitter_run |
|
77 * |
|
78 * Beschreibung: |
|
79 * |
|
80 * |
|
81 * Parameter: Zeiger auf msr_data |
|
82 * |
|
83 * Rückgabe: |
|
84 * |
|
85 * Status: exp |
|
86 * |
|
87 *****************************************************************************/ |
|
88 |
|
89 void msr_jitter_run(unsigned int hz) { |
|
90 |
|
91 int i,hit; |
|
92 static int firstrun = 1; |
|
93 static unsigned long k,j = 0; |
|
94 unsigned int dt,jitter; |
|
95 |
|
96 |
|
97 rdtscl(k); |
|
98 |
|
99 tcount++; |
|
100 |
|
101 //Zeitabstand zwischen zwei Interrupts in usec |
|
102 |
|
103 dt = ((unsigned long)(100000/HZ)*((unsigned long)(k-j))) |
|
104 /(current_cpu_data.loops_per_jiffy/10); |
|
105 |
|
106 jitter = (unsigned int)abs((int)dt-(int)1000000/hz); |
|
107 //jitter errechnet zum Sollabtastrate |
|
108 |
|
109 //in die Klassen einsortieren |
|
110 if(!firstrun) { //das erste mal nicht einsortieren |
|
111 hit = 0; |
|
112 for(i=0;i<NUMCLASSES-1;i++) { |
|
113 if(jitter>=jittime[i] && jitter<jittime[i+1]) { |
|
114 jitcount[i]++; |
|
115 hit = 1; |
|
116 break; |
|
117 } |
|
118 } |
|
119 if(hit == 0) //grŽöŽßer als der letzte |
|
120 jitcount[NUMCLASSES-1]++; |
|
121 |
|
122 } |
|
123 else |
|
124 firstrun = 0; |
|
125 |
|
126 j = k; |
|
127 |
|
128 |
|
129 } |
|