ordonanceur.c
3.47 KB
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
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define NB_TICK 104 //1563
#define CPU_FREQ 16000000L
#define QUANTUM_ms 10
#define SAVE_CONTEXT() \
asm volatile ( \
"push r0 \n\t" \
"in r0, __SREG__ \n\t" \
"cli \n\t" \
"push r0 \n\t" \
"push r1 \n\t" \
"clr r1 \n\t" \
"push r2 \n\t" \
"push r3 \n\t" \
"push r4 \n\t" \
"push r5 \n\t" \
"push r6 \n\t" \
"push r7 \n\t" \
"push r8 \n\t" \
"push r9 \n\t" \
"push r10 \n\t" \
"push r11 \n\t" \
"push r12 \n\t" \
"push r13 \n\t" \
"push r14 \n\t" \
"push r15 \n\t" \
"push r16 \n\t" \
"push r17 \n\t" \
"push r18 \n\t" \
"push r19 \n\t" \
"push r20 \n\t" \
"push r21 \n\t" \
"push r22 \n\t" \
"push r23 \n\t" \
"push r24 \n\t" \
"push r25 \n\t" \
"push r26 \n\t" \
"push r27 \n\t" \
"push r28 \n\t" \
"push r29 \n\t" \
"push r30 \n\t" \
"push r31 \n\t" \
);
#define RESTORE_CONTEXT() \
asm volatile ( \
"pop r31 \n\t" \
"pop r30 \n\t" \
"pop r29 \n\t" \
"pop r28 \n\t" \
"pop r27 \n\t" \
"pop r26 \n\t" \
"pop r25 \n\t" \
"pop r24 \n\t" \
"pop r23 \n\t" \
"pop r22 \n\t" \
"pop r21 \n\t" \
"pop r20 \n\t" \
"pop r19 \n\t" \
"pop r18 \n\t" \
"pop r17 \n\t" \
"pop r16 \n\t" \
"pop r15 \n\t" \
"pop r14 \n\t" \
"pop r13 \n\t" \
"pop r12 \n\t" \
"pop r11 \n\t" \
"pop r10 \n\t" \
"pop r9 \n\t" \
"pop r8 \n\t" \
"pop r7 \n\t" \
"pop r6 \n\t" \
"pop r5 \n\t" \
"pop r4 \n\t" \
"pop r3 \n\t" \
"pop r2 \n\t" \
"pop r1 \n\t" \
"pop r0 \n\t" \
"out __SREG__, r0 \n\t" \
"pop r0 \n\t" \
);
/** Configure les ports */
void init_ports(){
//TODO DDRXs
}
/** ----- Liaison serie ----- */
void init_serial(int speed){
UBRR0 = CPU_FREQ/(((unsigned long int)speed)<<4)-1; //Set baud rate
UCSR0B = (1<<TXEN0 | 1<<RXEN0); //Enable transmitter & receiver
UCSR0C = (1<<UCSZ01 | 1<<UCSZ00); //Set 8 bits character and 1 stop bit
UCSR0A &= ~(1 << U2X0); //Set off UART baud doubler
}
void send_serial(unsigned char c){
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
}
unsigned char get_serial(void){
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}
/** ----- Taches ----- */
void task_print_a(void){
while(1){
send_serial('a');
_delay_ms(1000);
}
}
void task_print_b(void){
while(1){
send_serial('b');
_delay_ms(700);
}
}
/** ----- Ordonnancement ----- */
struct task{
uint16_t sp_vise;
};
uint8_t cpt = 0;
uint8_t premier_lancement = 0;
struct task print_a = {0x0300};
struct task print_b = {0x0500};
/** Démarre le timer pour l'ordonnancement */
void init_timer(){
TCCR1B |= _BV(WGM12); // CTC mode with value in OCR1A
TCCR1B |= _BV(CS12); // CS12 = 1; CS11 = 1; CS10 =1 => CLK/1024 prescaler
TCCR1B |= _BV(CS10);
OCR1A = NB_TICK;
TIMSK1 |= _BV(OCIE1A);
}
/** Changement de contexte */
ISR(TIMER1_COMPA_vect){
if(premier_lancement == 0){
premier_lancement++;
sei();
SP = print_a.sp_vise;
task_print_a();
}else if(premier_lancement == 1){
SAVE_CONTEXT();
print_a.sp_vise = SP;
premier_lancement++;
sei();
SP = print_b.sp_vise;
task_print_b();
}else{
if(cpt==0){
SAVE_CONTEXT();
print_b.sp_vise = SP;
SP = print_a.sp_vise;
RESTORE_CONTEXT();
cpt++;
}else if(cpt==1){
SAVE_CONTEXT();
print_a.sp_vise = SP;
SP = print_b.sp_vise;
RESTORE_CONTEXT();
cpt = 0;
}
}
sei();
}
int main(void){
// Initialisation
init_timer();
init_ports();
init_serial(9600);
sei();
while(1){}
return 0;
}