-
Notifications
You must be signed in to change notification settings - Fork 0
/
tt_tasks-v2.c
160 lines (134 loc) · 3.1 KB
/
tt_tasks-v2.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
#include <stdint.h>
#include "tt_tasks.h"
__attribute__((always_inline))
static inline void __enable_irq(void)
{
__asm volatile ("cpsie i" : : : "memory");
}
__attribute__((always_inline))
static inline void __disable_irq(void)
{
__asm volatile ("cpsid i" : : : "memory");
}
static uint32_t task_tickcounter = 0;
typedef struct {
void (*task)(void); // pointer to function
uint32_t period; // period, i.e. time between activations
uint32_t delay; // time to next activation
} TaskInfo;
/// Default value for Task Info Table
#ifndef TASK_MAXCNT
#define TASK_MAXCNT 10
#endif
// Forward definition of Task_Delete
uint32_t Task_Delete(uint32_t );
/// Task info table
static TaskInfo taskinfo[TASK_MAXCNT];
/**
* @brief Task Init
* @note Initialization of TTE Kernel
*/
uint32_t
Task_Init(void) {
int i;
for(i=0;i<TASK_MAXCNT;i++) {
Task_Delete(i);
}
return 0;
}
/**
* @brief Task Add
*
* @note Add task to Kernel
* @note delay can be used to serialize task activation and avoid clustering
* in a certain time
*/
uint32_t
Task_Add( void (*task)(void), uint32_t period, uint32_t delay ) {
int taskno = 0;
while( (taskno<TASK_MAXCNT) && taskinfo[taskno].task ) taskno++;
if( taskno == TASK_MAXCNT ) return 1;
taskinfo[taskno].task = task;
taskinfo[taskno].period = period;
return taskno;
}
/**
* @brief Task Delete
*
* @note Remove task from Kernel
* @note Use with caution because it modifies the scheduling calculation
*/
uint32_t
Task_Delete(uint32_t taskno) {
taskinfo[taskno].task = 0;
taskinfo[taskno].period = 0;
return 0;
}
/**
* @brief Task Dispatch
*
* @note Run tasks if they are ready
* @note Must be called in main loop
*/
uint32_t
Task_Dispatch(void) {
int i;
TaskInfo *p;
uint32_t dispatch;
__disable_irq();
if( task_tickcounter > 0 ) {
task_tickcounter--;
dispatch = 1;
}
__enable_irq();
while( dispatch ) {
for(i=0;i<TASK_MAXCNT;i++) {
p = &taskinfo[i];
if( p->task ) {
if( p->delay == 0 ) {
p->task(); // call task function
if( p->period == 0 ) { // one time tasks are dangerous
Task_Delete(i);
} else {
p->delay = p->period;
}
} else {
p->delay--;
}
}
}
__disable_irq();
if( task_tickcounter > 0 ) {
task_tickcounter--;
dispatch = 1;
} else {
dispatch = 0;
}
__enable_irq();
}
return 0;
}
/**
* @brief Task Update
*
* @note Must be called only in Timer Interrupt Routine
* @note Almost nothing happens here
*
*/
void
Task_Update(void) {
task_tickcounter++;
return;
}
/**
* @brief Task Modify Period
*
* @note CAUTION!!! It can modify all timing calculation
*
*/
uint32_t
Task_ModifyPeriod(uint32_t taskno, uint32_t newperiod) {
uint32_t t = taskinfo[taskno].period;
taskinfo[taskno].period = newperiod;
return t;
}