blob: 41357eb77a654609b4ce7342fd8d84c63baa11f2 (
plain)
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
|
/*
* $HeadURL: https://svn.fzd.de/repo/concast/FWF_Projects/FWKE/hw_sp605/bsp_zpuahb/software/schedule.c $
* $Date$
* $Author$
* $Revision$
*/
#include <types.h>
#include "schedule.h"
#define MAXTIMERS 10
#define T_FREE 254 // > MAXTIMERS
#define T_LAST 255
typedef struct{
uint8_t next; // next in list or end mark
t_res delta; // delta to previous entry
funcp func;
} t_ctrl_struct;
t_ctrl_struct t_ctrl_lst[MAXTIMERS];
t_res t_delay; // count down until next service
uint8_t t_first; // point to first entry
void scheduler_task_check(void)
{
t_ctrl_struct *p; // for faster access
--t_delay;
while( t_delay == 0 ){ // serve if delay = 0
if( t_first == T_LAST ) // no function to serve
break;
p = &t_ctrl_lst[t_first];
t_first = p->next; // point to next
p->next = T_FREE; // mark free
t_delay = t_ctrl_lst[t_first].delta; // next delay delta
p->func(); // execute function
}
}
uint8_t scheduler_task_add( funcp func, t_res delay )
{
uint8_t n;
uint8_t i; // index
uint8_t ipre; // previous index
t_res d1; // last delta delay
t_ctrl_struct *p; // for faster access
for( n = 0;; ){
p = &t_ctrl_lst[n];
if( p->next == T_FREE )
break;
n++;
if( n == MAXTIMERS )
return 1; // error, list full
}
i = t_first;
d1 = t_delay;
while( i != T_LAST ){ // check until end
if( d1 >= delay ){ // last >= new
t_ctrl_lst[i].delta = d1 - delay; // correct following entry
break;
}else{
delay -= d1; // remaining delay
ipre = i; // previous entry
i = t_ctrl_lst[i].next; // index of next entry
d1 = t_ctrl_lst[i].delta; // next delay delta
}
} // insert new entry
p->next = i; // following entry
p->delta = delay; // store remaining delay
p->func = func;
if( i == t_first ){ // insert at first
t_first = n;
t_delay = delay;
}else{
t_ctrl_lst[ipre].next = n; // previous entry
}
return 0; // successful
}
uint8_t scheduler_task_remove( funcp func )
{
uint8_t ipre; // previous index
uint8_t irem; // index to be removed
uint8_t ifol = t_first; // following index
t_ctrl_struct *p; // for faster access
do{
if( ifol == T_LAST )
return 1; // not found
ipre = irem;
irem = ifol;
p = &t_ctrl_lst[irem];
ifol = p->next; // get next
}while( p->func != func ); // found it
p->next = T_FREE; // mark it as free
if( irem == t_first ){
t_first = ifol; // serve next entry
t_delay += t_ctrl_lst[ifol].delta; // correct current delta
}else{
t_ctrl_lst[ipre].next = ifol; // skip index
if( ifol != T_LAST ) // correct following delta
t_ctrl_lst[ifol].delta += p->delta;
}
return 0; // successful
}
void scheduler_init(void)
{
uint8_t i;
for( i = MAXTIMERS; i; i-- )
t_ctrl_lst[i-1].next = T_FREE; // mark all free
t_first = T_LAST; // set no timer served
}
uint32_t scheduler_tasklist( void)
{
uint8_t i;
for( i = MAXTIMERS; i; i-- )
{
if ( t_ctrl_lst[i-1].next != T_FREE)
{
putint( i);
putstr(": func: ");
puthex( 32, t_ctrl_lst[i-1].func);
putchar('\n');
}
}
return 0;
}
|