-
Notifications
You must be signed in to change notification settings - Fork 0
/
MiniProject4Test.c
476 lines (450 loc) · 15.4 KB
/
MiniProject4Test.c
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
// Lab2Test.c
// Runs on LM4F120/TM4C123
// You may use, edit, run or distribute this file
// You are free to change the syntax/organization of this file
// Jonathan W. Valvano 2/20/17, [email protected]
// Modified by Sile Shu 10/4/17, [email protected]
// Modified by Mustafa Hotaki 8/1/2018, [email protected]
#include <stdint.h>
#include "OS.h"
#include "tm4c123gh6pm.h"
#include "LCD.h"
#include <string.h>
#include "UART.h"
#include "PLL.h"
#include "PORTE.h"
#define JITTERSIZE 64
#define PERIOD TIME_500US // DAS 2kHz sampling period in system time units
unsigned long NumCreated; // Number of foreground threads created
long MaxJitter; // largest time jitter between interrupts in usec
unsigned long const JitterSize=JITTERSIZE;
unsigned long JitterHistogram[JITTERSIZE]={0,};
unsigned long MaxDiff;
unsigned long StartTime, StopTime;
//******************* Measurement of context switch time**********
// Run this to measure the time it takes to perform a task switch
// UART0 not needed
// SYSTICK interrupts, period established by OS_Launch
// first timer not needed
// second timer not needed
// SW1 not needed,
// SW2 not needed
void Thread8(void){ // only thread running
while(1){
PE0 ^= 0x01; // debugging profile
}
}
int Testmain0(void){ // Testmain7
PortE_Init();
OS_Init(); // initialize, disable interrupts
NumCreated = 0 ;
NumCreated += OS_AddThread(&Thread8,128,2);
OS_Launch(TIME_1MS/10); // 100us, doesn't return, interrupts enabled in here
return 0; // this never executes
}
//*******************Initial TEST**********
// run this with
// no UART interrupts
// no SYSTICK interrupts
// no timer interrupts
// no switch interrupts
// no ADC serial port or LCD output
// no calls to semaphores
unsigned long Count1; // number of times thread1 loops
unsigned long Count2; // number of times thread2 loops
unsigned long Count3; // number of times thread3 loops
unsigned long Count4; // number of times thread4 loops
unsigned long Count5; // number of times thread5 loops
void Thread1(void){
Count1 = 0;
for(;;){
PE0 ^= 0x01; // heartbeat
Count1++;
OS_Suspend(); // cooperative multitasking
}
}
void Thread2(void){
Count2 = 0;
for(;;){
PE1 ^= 0x02; // heartbeat
Count2++;
OS_Suspend(); // cooperative multitasking
}
}
void Thread3(void){
Count3 = 0;
for(;;){
PE2 ^= 0x04; // heartbeat
Count3++;
OS_Suspend(); // cooperative multitasking
}
}
int main(void){ // Testmain1
OS_Init(); // initialize, disable interrupts
PortE_Init(); // profile user threads
NumCreated = 0 ;
NumCreated += OS_AddThread(&Thread1,128,1);
NumCreated += OS_AddThread(&Thread2,128,2);
NumCreated += OS_AddThread(&Thread3,128,3);
// Count1 Count2 Count3 should be equal or off by one at all times
OS_Launch(TIME_2MS); // doesn't return, interrupts enabled in here
return 0; // this never executes
}
//*******************Second TEST**********
// Once the initalize test runs, test this
// no UART interrupts
// SYSTICK interrupts, with or without period established by OS_Launch
// no timer interrupts
// no switch interrupts
// no ADC serial port or LCD output
// no calls to semaphores
void Thread1b(void){
Count1 = 0;
for(;;){
PE0 ^= 0x01; // heartbeat
Count1++;
}
}
void Thread2b(void){
Count2 = 0;
for(;;){
PE1 ^= 0x02; // heartbeat
Count2++;
}
}
void Thread3b(void){
Count3 = 0;
for(;;){
PE2 ^= 0x04; // heartbeat
Count3++;
}
}
int Testmain2(void){ // Testmain2
OS_Init(); // initialize, disable interrupts
PortE_Init(); // profile user threads
NumCreated = 0 ;
NumCreated += OS_AddThread(&Thread1b,128,1);
NumCreated += OS_AddThread(&Thread2b,128,2);
NumCreated += OS_AddThread(&Thread3b,128,3);
// Count1 Count2 Count3 should be equal on average
// counts are larger than testmain1
OS_Launch(TIME_2MS); // doesn't return, interrupts enabled in here
return 0; // this never executes
}
//*******************Third TEST**********
// Once the second test runs, test this (Lab 2 part 2)
// no UART1 interrupts
// SYSTICK interrupts, with or without period established by OS_Launch
// Timer interrupts, with or without period established by OS_AddPeriodicThread
// PortF GPIO interrupts, active low
// no ADC serial port or LCD output
// tests the spinlock semaphores, tests Sleep and Kill
Sema4Type Readyc; // set in background
int Lost;
void BackgroundThread1c(void){ // called at 1000 Hz
Count1++;
OS_Signal(&Readyc);
}
void Thread5c(void){
for(;;){
OS_Wait(&Readyc);
Count5++; // Count2 + Count5 should equal Count1
Lost = Count1-Count5-Count2;
}
}
void Thread2c(void){
OS_InitSemaphore(&Readyc,0);
Count1 = 0; // number of times signal is called
Count2 = 0;
Count5 = 0; // Count2 + Count5 should equal Count1
NumCreated += OS_AddThread(&Thread5c,128,3);
OS_AddPeriodicThread(&BackgroundThread1c,TIME_1MS,0);
for(;;){
OS_Wait(&Readyc);
Count2++; // Count2 + Count5 should equal Count1
}
}
void Thread3c(void){
Count3 = 0;
for(;;){
Count3++;
}
}
void Thread4c(void){ int i;
for(i=0;i<64;i++){
Count4++;
OS_Sleep(10);
}
OS_Kill();
Count4 = 0;
}
void BackgroundThread5c(void){ // called when Select button pushed
NumCreated += OS_AddThread(&Thread4c,128,3);
}
int Testmain3(void){ // Testmain3
Count4 = 0;
OS_Init(); // initialize, disable interrupts
// Count2 + Count5 should equal Count1
NumCreated = 0 ;
OS_AddSW1Task(&BackgroundThread5c,2);
NumCreated += OS_AddThread(&Thread2c,128,2);
NumCreated += OS_AddThread(&Thread3c,128,3);
NumCreated += OS_AddThread(&Thread4c,128,3);
OS_Launch(TIME_2MS); // doesn't return, interrupts enabled in here
return 0; // this never executes
}
//*******************Fourth TEST**********
// Once the third test runs, run this example (Lab 2 part 2)
// Count1 should exactly equal Count2
// Count3 should be very large
// Count4 increases by 640 every time select is pressed
// NumCreated increase by 1 every time select is pressed
// no UART interrupts
// SYSTICK interrupts, with or without period established by OS_Launch
// Timer interrupts, with or without period established by OS_AddPeriodicThread
// Select switch interrupts, active low
// no ADC serial port or LCD output
// tests the spinlock semaphores, tests Sleep and Kill
Sema4Type Readyd; // set in background
void BackgroundThread1d(void){ // called at 1000 Hz
static int i=0;
i++;
if(i==50){
i = 0; //every 50 ms
Count1++;
OS_bSignal(&Readyd);
}
}
void Thread2d(void){
OS_InitSemaphore(&Readyd,0);
Count1 = 0;
Count2 = 0;
for(;;){
OS_bWait(&Readyd);
Count2++;
}
}
void Thread3d(void){
Count3 = 0;
for(;;){
Count3++;
}
}
void Thread4d(void){ int i;
for(i=0;i<640;i++){
Count4++;
OS_Sleep(1);
}
OS_Kill();
}
void BackgroundThread5d(void){ // called when Select button pushed
NumCreated += OS_AddThread(&Thread4d,128,3);
}
int Testmain4(void){ // Testmain4
Count4 = 0;
OS_Init(); // initialize, disable interrupts
NumCreated = 0 ;
OS_AddPeriodicThread(&BackgroundThread1d,PERIOD,0);
OS_AddSW1Task(&BackgroundThread5d,2);
NumCreated += OS_AddThread(&Thread2d,128,2);
NumCreated += OS_AddThread(&Thread3d,128,3);
NumCreated += OS_AddThread(&Thread4d,128,3);
OS_Launch(TIME_2MS); // doesn't return, interrupts enabled in here
return 0; // this never executes
}
//******************* Lab 3 Preparation 2**********
// Modify this so it runs with your RTOS (i.e., fix the time units to match your OS)
// run this with
// UART0, 115200 baud rate, used to output results
// SYSTICK interrupts, period established by OS_Launch
// first timer interrupts, period established by first call to OS_AddPeriodicThread
// second timer interrupts, period established by second call to OS_AddPeriodicThread
// SW1 no interrupts
// SW2 no interrupts
unsigned long CountA; // number of times Task A called
unsigned long CountB; // number of times Task B called
unsigned long Count1; // number of times thread1 loops
//*******PseudoWork*************
// simple time delay, simulates user program doing real work
// Input: amount of work in 100ns units (free free to change units
// Output: none
void PseudoWork(unsigned short work){
unsigned short startTime;
startTime = OS_Time(); // time in 1ms units
while(OS_TimeDifference(startTime,OS_Time()) <= work){}
}
void Thread6(void){ // foreground thread
Count1 = 0;
for(;;){
Count1++;
PE0 ^= 0x01; // debugging toggle bit 0
}
}
unsigned static long LastTime; // time at previous ADC sample
unsigned long thisTime; // time at current ADC sample
long jitter; // time between measured and expected, in us
unsigned long diff;
void Jitter(void) {
unsigned long myId = OS_Id();
BSP_LCD_Message(1,2,0,"Jitter 0.1us=",MaxJitter);
BSP_LCD_Message(1,3,0,"Difference =",MaxDiff);
BSP_LCD_Message(1,4,0,"StartTime =",StartTime);
BSP_LCD_Message(1,5,0,"StopTime =",StopTime);
//OS_Kill(); // done, OS does not return from a Kill
}
void Thread7(void){ // foreground thread
UART_OutString("\n\rAdvanced Embedded Systems, Lab 3 Preparation\n\r");
OS_Sleep(5000); // 10 seconds
Jitter(); // print jitter information
UART_OutString("\n\r\n\r");
OS_Kill();
}
#define workA 500 // {5,50,500 us} work in Task A
#define counts1us 10 // number of OS_Time counts per 1us
void TaskA(void){ // called every {1000, 2990us} in background
static long Count = 0;
PE1 = 0x02; // debugging profile
CountA++;
thisTime = OS_Time(); // current time, 12.5 ns
PseudoWork(workA*counts1us); // do work (100ns time resolution)
Count++; // calculation finished
if(Count>1){ // ignore timing of first interrupt
diff = OS_TimeDifference(LastTime,thisTime);
StartTime = LastTime;
StopTime = thisTime;
MaxDiff = diff;
if(diff>PERIOD){
jitter = (diff-TIME_1MS+4)/8; // in 0.1 usec
}else{
jitter = (TIME_1MS-diff+4)/8; // in 0.1 usec
}
if(jitter > MaxJitter){
MaxJitter = jitter; // in usec
MaxDiff = diff;
StartTime = LastTime;
StopTime = thisTime;
} // jitter should be 0
if(jitter >= JitterSize){
jitter = JITTERSIZE-1;
}
JitterHistogram[jitter]++;
}
PE1 = 0x00; // debugging profile
}
#define workB 250 // 250 us work in Task B
void TaskB(void){ // called every pB in background
PE2 = 0x04; // debugging profile
CountB++;
PseudoWork(workB*counts1us); // do work (100ns time resolution)
PE2 = 0x00; // debugging profile
}
int Testmain5(void){ // Testmain5 Lab 3
PortE_Init();
UART_Init();
BSP_LCD_OutputInit();
OS_Init(); // initialize, disable interrupts
NumCreated = 0 ;
NumCreated += OS_AddThread(&Thread6,128,2);
NumCreated += OS_AddThread(&Thread7,128,1);
OS_AddPeriodicThread(&TaskA,TIME_1MS,0); // 1 ms, higher priority
OS_AddPeriodicThread(&TaskB,2*TIME_1MS,1); // 2 ms, lower priority
OS_Launch(TIME_2MS); // 2ms, doesn't return, interrupts enabled in here
return 0; // this never executes
}
//******************* Mini Project 4 Preparation **********
// Modify this so it runs with your RTOS used to test blocking semaphores
// run this with
// UART0, 115200 baud rate, used to output results
// SYSTICK interrupts, period established by OS_Launch
// first timer interrupts, period established by first call to OS_AddPeriodicThread
// second timer interrupts, period established by second call to OS_AddPeriodicThread
// SW1 no interrupts,
// SW2 no interrupts
Sema4Type s; // test of this counting semaphore
unsigned long SignalCount1; // number of times s is signaled
unsigned long SignalCount2; // number of times s is signaled
unsigned long SignalCount3; // number of times s is signaled
unsigned long WaitCount1; // number of times s is successfully waited on
unsigned long WaitCount2; // number of times s is successfully waited on
unsigned long WaitCount3; // number of times s is successfully waited on
#define MAXCOUNT 20000
void OutputThread(void){ // foreground thread
UART_OutString("\n\rECE 4501/6501, Lab 3 Preparation\n\r");
while(SignalCount1+SignalCount2+SignalCount3<100*MAXCOUNT){
OS_Sleep(1000); // 1 second
UART_OutString(".");
}
UART_OutString(" done\n\r");
UART_OutString("Signalled="); UART_OutUDec(SignalCount1+SignalCount2+SignalCount3);
UART_OutString(", Waited="); UART_OutUDec(WaitCount1+WaitCount2+WaitCount3);
UART_OutString("\n\r");
OS_Kill();
}
void Wait1(void){ // foreground thread
for(;;){
OS_Wait(&s); // three threads waiting
WaitCount1++;
}
}
void Wait2(void){ // foreground thread
for(;;){
OS_Wait(&s); // three threads waiting
WaitCount2++;
}
}
void Wait3(void){ // foreground thread
for(;;){
OS_Wait(&s); // three threads waiting
WaitCount3++;
}
}
void Signal1(void){ // called every 799us in background
if(SignalCount1<MAXCOUNT){
OS_Signal(&s);
SignalCount1++;
}
}
// edit this so it changes the periodic rate
void Signal2(void){ // called every 1111us in background
if(SignalCount2<MAXCOUNT){
OS_Signal(&s);
SignalCount2++;
}
}
void Signal3(void){ // foreground
while(SignalCount3<98*MAXCOUNT){
OS_Signal(&s);
SignalCount3++;
}
OS_Kill();
}
long add(const long n, const long m){
static long result;
result = m+n;
return result;
}
int Testmain6(void){ // Testmain6 Lab 3
volatile unsigned long delay;
OS_Init(); // initialize, disable interrupts
UART_Init();
delay = add(3,4);
PortE_Init();
SignalCount1 = 0; // number of times s is signaled
SignalCount2 = 0; // number of times s is signaled
SignalCount3 = 0; // number of times s is signaled
WaitCount1 = 0; // number of times s is successfully waited on
WaitCount2 = 0; // number of times s is successfully waited on
WaitCount3 = 0; // number of times s is successfully waited on
OS_InitSemaphore(&s,0); // this is the test semaphore
OS_AddPeriodicThread(&Signal1,(799*TIME_1MS)/1000,0); // 0.799 ms, higher priority
OS_AddPeriodicThread(&Signal2,(1111*TIME_1MS)/1000,1); // 1.111 ms, lower priority
NumCreated = 0 ;
NumCreated += OS_AddThread(&Thread6,128,6); // idle thread to keep from crashing
NumCreated += OS_AddThread(&OutputThread,128,2); // results output thread
NumCreated += OS_AddThread(&Signal3,128,2); // signalling thread
NumCreated += OS_AddThread(&Wait1,128,2); // waiting thread
NumCreated += OS_AddThread(&Wait2,128,2); // waiting thread
NumCreated += OS_AddThread(&Wait3,128,2); // waiting thread
OS_Launch(TIME_1MS); // 1ms, doesn't return, interrupts enabled in here
return 0; // this never executes
}