Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_scheduler.c
1 #include <bc_scheduler.h>
2 #include <bc_system.h>
3 #include <bc_error.h>
4 
5 static struct
6 {
7  struct
8  {
9  bc_tick_t tick_execution;
10  void (*task)(void *);
11  void *param;
12 
13  } pool[BC_SCHEDULER_MAX_TASKS];
14 
15  bc_tick_t tick_spin;
16  bc_scheduler_task_id_t current_task_id;
17  bc_scheduler_task_id_t max_task_id;
18  int sleep_bypass_semaphore;
19 
20 } _bc_scheduler;
21 
22 void application_error(bc_error_t code);
23 
25 {
26  memset(&_bc_scheduler, 0, sizeof(_bc_scheduler));
27 }
28 
29 void bc_scheduler_run(void)
30 {
31  static bc_scheduler_task_id_t *task_id = &_bc_scheduler.current_task_id;
32 
33  while (true)
34  {
35  _bc_scheduler.tick_spin = bc_tick_get();
36 
37  for (*task_id = 0; *task_id <= _bc_scheduler.max_task_id; (*task_id)++)
38  {
39  if (_bc_scheduler.pool[*task_id].task != NULL)
40  {
41  if (_bc_scheduler.tick_spin >= _bc_scheduler.pool[*task_id].tick_execution)
42  {
43  _bc_scheduler.pool[*task_id].tick_execution = BC_TICK_INFINITY;
44 
45  _bc_scheduler.pool[*task_id].task(_bc_scheduler.pool[*task_id].param);
46  }
47  }
48  }
49  if (_bc_scheduler.sleep_bypass_semaphore == 0)
50  {
51  bc_system_sleep();
52  }
53  }
54 }
55 
56 bc_scheduler_task_id_t bc_scheduler_register(void (*task)(void *), void *param, bc_tick_t tick)
57 {
59  {
60  if (_bc_scheduler.pool[i].task == NULL)
61  {
62  _bc_scheduler.pool[i].tick_execution = tick;
63  _bc_scheduler.pool[i].task = task;
64  _bc_scheduler.pool[i].param = param;
65 
66  if (_bc_scheduler.max_task_id < i)
67  {
68  _bc_scheduler.max_task_id = i;
69  }
70 
71  return i;
72  }
73  }
74 
75  application_error(BC_ERROR_NOT_ENOUGH_TASKS);
76 
77  return 0;
78 }
79 
81 {
82  _bc_scheduler.pool[task_id].task = NULL;
83 
84  if (_bc_scheduler.max_task_id == task_id)
85  {
86  do
87  {
88  if (_bc_scheduler.max_task_id == 0)
89  {
90  break;
91  }
92 
93  _bc_scheduler.max_task_id--;
94 
95  } while (_bc_scheduler.pool[_bc_scheduler.max_task_id].task == NULL);
96  }
97 }
98 
100 {
101  return _bc_scheduler.current_task_id;
102 }
103 
105 {
106  return _bc_scheduler.tick_spin;
107 }
108 
110 {
111  _bc_scheduler.sleep_bypass_semaphore++;
112 }
113 
115 {
116  _bc_scheduler.sleep_bypass_semaphore--;
117 }
118 
120 {
121  _bc_scheduler.pool[task_id].tick_execution = 0;
122 }
123 
125 {
126  _bc_scheduler.pool[task_id].tick_execution = tick;
127 }
128 
130 {
131  _bc_scheduler.pool[task_id].tick_execution = _bc_scheduler.tick_spin + tick;
132 }
133 
135 {
136  _bc_scheduler.pool[task_id].tick_execution = bc_tick_get() + tick;
137 }
138 
140 {
141  _bc_scheduler.pool[_bc_scheduler.current_task_id].tick_execution = 0;
142 }
143 
145 {
146  _bc_scheduler.pool[_bc_scheduler.current_task_id].tick_execution = tick;
147 }
148 
150 {
151  _bc_scheduler.pool[_bc_scheduler.current_task_id].tick_execution = _bc_scheduler.tick_spin + tick;
152 }
153 
155 {
156  _bc_scheduler.pool[_bc_scheduler.current_task_id].tick_execution = bc_tick_get() + tick;
157 }
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
void bc_scheduler_plan_absolute(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to absolute tick.
Definition: bc_scheduler.c:124
bc_tick_t bc_scheduler_get_spin_tick(void)
Get current tick of spin in which task has been run.
Definition: bc_scheduler.c:104
void bc_scheduler_run(void)
Run task scheduler (this call never ends)
Definition: bc_scheduler.c:29
bc_scheduler_task_id_t bc_scheduler_register(void(*task)(void *), void *param, bc_tick_t tick)
Register task in scheduler.
Definition: bc_scheduler.c:56
void bc_scheduler_plan_now(bc_scheduler_task_id_t task_id)
Schedule specified task for immediate execution.
Definition: bc_scheduler.c:119
void bc_scheduler_plan_current_absolute(bc_tick_t tick)
Schedule current task to absolute tick.
Definition: bc_scheduler.c:144
void bc_scheduler_disable_sleep(void)
Disable sleep mode, implemented as semaphore.
Definition: bc_scheduler.c:109
bc_tick_t bc_tick_get(void)
Get absolute timestamp since start of program.
Definition: bc_tick.c:7
void bc_scheduler_enable_sleep(void)
Enable sleep mode, implemented as semaphore.
Definition: bc_scheduler.c:114
void bc_scheduler_plan_current_relative(bc_tick_t tick)
Schedule current task to tick relative from current spin.
Definition: bc_scheduler.c:149
#define BC_SCHEDULER_MAX_TASKS
Maximum number of tasks.
Definition: bc_scheduler.h:13
size_t bc_scheduler_task_id_t
Task ID assigned by scheduler.
Definition: bc_scheduler.h:18
void bc_scheduler_plan_relative(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to tick relative from current spin.
Definition: bc_scheduler.c:129
bc_scheduler_task_id_t bc_scheduler_get_current_task_id(void)
Get task ID of currently executing task.
Definition: bc_scheduler.c:99
void bc_scheduler_plan_from_now(bc_scheduler_task_id_t task_id, bc_tick_t tick)
Schedule specified task to tick relative from now.
Definition: bc_scheduler.c:134
void bc_scheduler_init(void)
Initialize task scheduler.
Definition: bc_scheduler.c:24
void bc_scheduler_plan_current_from_now(bc_tick_t tick)
Schedule current task to tick relative from now.
Definition: bc_scheduler.c:154
#define BC_TICK_INFINITY
Maximum timestamp value.
Definition: bc_tick.h:12
void bc_scheduler_plan_current_now(void)
Schedule current task for immediate execution.
Definition: bc_scheduler.c:139
void bc_scheduler_unregister(bc_scheduler_task_id_t task_id)
Unregister specified task.
Definition: bc_scheduler.c:80