Firmware SDK
twr_scheduler.c
1 #include <twr_scheduler.h>
2 #include <twr_system.h>
3 #include <twr_error.h>
4 
5 static struct
6 {
7  struct
8  {
9  twr_tick_t tick_execution;
10  void (*task)(void *);
11  void *param;
12 
14 
15  twr_tick_t tick_spin;
16  twr_scheduler_task_id_t current_task_id;
17  twr_scheduler_task_id_t max_task_id;
18 
19 } _twr_scheduler;
20 
21 void application_idle();
22 void application_error(twr_error_t code);
23 
25 {
26  memset(&_twr_scheduler, 0, sizeof(_twr_scheduler));
27 }
28 
30 {
31  static twr_scheduler_task_id_t *task_id = &_twr_scheduler.current_task_id;
32 
33  while (true)
34  {
35  _twr_scheduler.tick_spin = twr_tick_get();
36 
37  for (*task_id = 0; *task_id <= _twr_scheduler.max_task_id; (*task_id)++)
38  {
39  if (_twr_scheduler.pool[*task_id].task != NULL)
40  {
41  if (_twr_scheduler.tick_spin >= _twr_scheduler.pool[*task_id].tick_execution)
42  {
43  _twr_scheduler.pool[*task_id].tick_execution = TWR_TICK_INFINITY;
44 
45  _twr_scheduler.pool[*task_id].task(_twr_scheduler.pool[*task_id].param);
46  }
47  }
48  }
49  application_idle();
50  }
51 }
52 
53 twr_scheduler_task_id_t twr_scheduler_register(void (*task)(void *), void *param, twr_tick_t tick)
54 {
56  {
57  if (_twr_scheduler.pool[i].task == NULL)
58  {
59  _twr_scheduler.pool[i].tick_execution = tick;
60  _twr_scheduler.pool[i].task = task;
61  _twr_scheduler.pool[i].param = param;
62 
63  if (_twr_scheduler.max_task_id < i)
64  {
65  _twr_scheduler.max_task_id = i;
66  }
67 
68  return i;
69  }
70  }
71 
72  application_error(TWR_ERROR_NOT_ENOUGH_TASKS);
73 
74  return 0;
75 }
76 
78 {
79  if (task_id >= TWR_SCHEDULER_MAX_TASKS)
80  {
81  application_error(TWR_ERROR_INVALID_PARAMETER);
82  }
83  _twr_scheduler.pool[task_id].task = NULL;
84 
85  if (_twr_scheduler.max_task_id == task_id)
86  {
87  do
88  {
89  if (_twr_scheduler.max_task_id == 0)
90  {
91  break;
92  }
93 
94  _twr_scheduler.max_task_id--;
95 
96  } while (_twr_scheduler.pool[_twr_scheduler.max_task_id].task == NULL);
97  }
98 }
99 
101 {
102  return _twr_scheduler.current_task_id;
103 }
104 
106 {
107  return _twr_scheduler.tick_spin;
108 }
109 
111 {
112  if (task_id >= TWR_SCHEDULER_MAX_TASKS)
113  {
114  application_error(TWR_ERROR_INVALID_PARAMETER);
115  }
116  _twr_scheduler.pool[task_id].tick_execution = 0;
117 }
118 
120 {
121  if (task_id >= TWR_SCHEDULER_MAX_TASKS || _twr_scheduler.pool[task_id].task == NULL)
122  {
123  application_error(TWR_ERROR_INVALID_PARAMETER);
124  }
125  _twr_scheduler.pool[task_id].tick_execution = tick;
126 }
127 
129 {
130  if (task_id >= TWR_SCHEDULER_MAX_TASKS || _twr_scheduler.pool[task_id].task == NULL)
131  {
132  application_error(TWR_ERROR_INVALID_PARAMETER);
133  }
134  _twr_scheduler.pool[task_id].tick_execution = _twr_scheduler.tick_spin + tick;
135 }
136 
138 {
139  if (task_id >= TWR_SCHEDULER_MAX_TASKS || _twr_scheduler.pool[task_id].task == NULL)
140  {
141  application_error(TWR_ERROR_INVALID_PARAMETER);
142  }
143  _twr_scheduler.pool[task_id].tick_execution = twr_tick_get() + tick;
144 }
145 
147 {
148  _twr_scheduler.pool[_twr_scheduler.current_task_id].tick_execution = 0;
149 }
150 
152 {
153  _twr_scheduler.pool[_twr_scheduler.current_task_id].tick_execution = tick;
154 }
155 
157 {
158  _twr_scheduler.pool[_twr_scheduler.current_task_id].tick_execution = _twr_scheduler.tick_spin + tick;
159 }
160 
162 {
163  _twr_scheduler.pool[_twr_scheduler.current_task_id].tick_execution = twr_tick_get() + tick;
164 }
void twr_scheduler_run(void)
Run task scheduler (this call never ends)
Definition: twr_scheduler.c:29
void twr_scheduler_plan_current_from_now(twr_tick_t tick)
Schedule current task to tick relative from now.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
void twr_scheduler_plan_current_absolute(twr_tick_t tick)
Schedule current task to absolute tick.
void twr_scheduler_plan_absolute(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to absolute tick.
void twr_scheduler_init(void)
Initialize task scheduler.
Definition: twr_scheduler.c:24
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
Definition: twr_scheduler.c:77
void twr_scheduler_plan_from_now(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from now.
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: twr_scheduler.h:22
void twr_scheduler_plan_now(twr_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
void twr_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
twr_tick_t twr_scheduler_get_spin_tick(void)
Get current tick of spin in which task has been run.
#define TWR_SCHEDULER_MAX_TASKS
Maximum number of tasks.
Definition: twr_scheduler.h:13
void twr_scheduler_plan_relative(twr_scheduler_task_id_t task_id, twr_tick_t tick)
Schedule specified task to tick relative from current spin.
twr_scheduler_task_id_t twr_scheduler_get_current_task_id(void)
Get task ID of currently executing task.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
Definition: twr_scheduler.c:53
#define TWR_TICK_INFINITY
Maximum timestamp value.
Definition: twr_tick.h:12
twr_tick_t twr_tick_get(void)
Get absolute timestamp since start of program.
Definition: twr_tick.c:7
uint64_t twr_tick_t
Timestamp data type.
Definition: twr_tick.h:16