AutosarOS
ScheduleTables.c
Go to the documentation of this file.
1 
14 #include "ScheduleTables.h"
15 #include "Counter.h"
16 #include "Task.h"
17 #include "Events.h"
18 
19 #include "OCB.h"
20 #include "OS.h"
21 
22 #include "assert.h"
23 
24 #include <util/atomic.h>
25 
26 /************************************************************************/
27 /* STATIC FUNCTIONS */
28 /************************************************************************/
36 static void ScheduleTable_handleExpiryPoint(const volatile struct scheduleTableExpiryPoint_s* expiryPoint)
37 {
38  /* Handle task activations */
39  for (uint8_t i = 0; i < expiryPoint->numTaskActions; i++) {
40  Task_ActivateTask(expiryPoint->taskActionList[i].task);
41  }
42 
43  /* Handle events */
44  for (uint8_t i = 0; i < expiryPoint->numEventActions; i++) {
45  Events_SetEvent(expiryPoint->eventActionList[i].task, expiryPoint->eventActionList[i].event);
46  }
47 }
48 
62 static void ScheduleTable_handleScheduleTableStart(ScheduleTableType scheduleTableID)
63 {
65  ScheduleTable_Cfg[scheduleTableID]->currentTick = 0;
66 
67  /* Handle first expiry point if it has zero offset */
68  if (ScheduleTable_Cfg[scheduleTableID]->expiryPointList[0].offset == 0) {
69  bool savedBlock = blockScheduling;
70  blockScheduling = true;
71  ScheduleTable_handleExpiryPoint(&ScheduleTable_Cfg[scheduleTableID]->expiryPointList[0]);
72  blockScheduling = savedBlock;
73  }
74 }
75 
76 /************************************************************************/
77 /* EXTERN FUNCTIONS */
78 /************************************************************************/
80 {
81  OS_SET_ERROR_INFO2(OSServiceId_StartScheduleTableRel, &scheduleTableID, sizeof(scheduleTableID), &offset,
82  sizeof(offset));
83 
84  if (OS_EXTENDED && scheduleTableID >= INVALID_SCHEDULETABLE) {
86 
87  return E_OS_ID;
88  }
89 
90  if (OS_EXTENDED && (offset == 0
91  || offset > Counter_Cfg[ScheduleTable_Cfg[scheduleTableID]->counter]->maxallowedvalue -
92  ScheduleTable_Cfg[scheduleTableID]->expiryPointList[0].offset)) {
94 
95  return E_OS_VALUE;
96  }
97 
98  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
99  if (ScheduleTable_Cfg[scheduleTableID]->currentState != SCHEDULETABLE_STOPPED) {
101 
102  return E_OS_STATE;
103  }
104 
105  if (ScheduleTable_Cfg[scheduleTableID]->counter == SYSTEM_COUNTER) {
106  needSysTickEval += 1;
107  }
108 
109  ScheduleTable_Cfg[scheduleTableID]->currentTick = 0 - offset;
111  }
112 
113  return E_OK;
114 }
115 
117 {
118  OS_SET_ERROR_INFO2(OSServiceId_StartScheduleTableAbs, &scheduleTableID, sizeof(scheduleTableID), &start,
119  sizeof(start));
120 
121  if (OS_EXTENDED && scheduleTableID >= INVALID_SCHEDULETABLE) {
123 
124  return E_OS_ID;
125  }
126 
127  if (OS_EXTENDED && start > Counter_Cfg[ScheduleTable_Cfg[scheduleTableID]->counter]->maxallowedvalue) {
129 
130  return E_OS_VALUE;
131  }
132 
133  TickType currentTick;
134  Counter_GetCounterValue(ScheduleTable_Cfg[scheduleTableID]->counter, &currentTick);
135 
136  if (start > currentTick) {
137  start -= currentTick;
138  } else if (start < currentTick) {
139  start += (Counter_Cfg[ScheduleTable_Cfg[scheduleTableID]->counter]->maxallowedvalue - currentTick) + 1;
140  } else {
141  start = Counter_Cfg[ScheduleTable_Cfg[scheduleTableID]->counter]->maxallowedvalue;
142  }
143 
144  return ScheduleTable_StartScheduleTableRel(scheduleTableID, start);
145 }
146 
148 {
149  OS_SET_ERROR_INFO1(OSServiceId_StopScheduleTable, &scheduleTableID, sizeof(scheduleTableID));
150 
151  if (OS_EXTENDED && scheduleTableID >= INVALID_SCHEDULETABLE) {
153 
154  return E_OS_ID;
155  }
156 
157  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
158  if (ScheduleTable_Cfg[scheduleTableID]->currentState == SCHEDULETABLE_STOPPED) {
160 
161  return E_OS_NOFUNC;
162  }
163 
164  if (ScheduleTable_Cfg[scheduleTableID]->counter == SYSTEM_COUNTER) {
165  needSysTickEval -= 1;
166  }
167 
169  }
170 
171  return E_OK;
172 }
173 
175  ScheduleTableType scheduleTableID_to)
176 {
177  OS_SET_ERROR_INFO2(OSServiceId_NextScheduleTable, &scheduleTableID_from, sizeof(scheduleTableID_from),
178  &scheduleTableID_to, sizeof(scheduleTableID_to));
179 
180  if (OS_EXTENDED && (scheduleTableID_from >= INVALID_SCHEDULETABLE || scheduleTableID_to >= INVALID_SCHEDULETABLE)) {
182 
183  return E_OS_ID;
184  }
185 
186  if (OS_EXTENDED
187  && (ScheduleTable_Cfg[scheduleTableID_from]->counter != ScheduleTable_Cfg[scheduleTableID_to]->counter)) {
189 
190  return E_OS_ID;
191  }
192 
193  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
194  if (ScheduleTable_Cfg[scheduleTableID_from]->currentState == SCHEDULETABLE_STOPPED
195  || ScheduleTable_Cfg[scheduleTableID_from]->currentState == SCHEDULETABLE_NEXT) {
197 
198  return E_OS_NOFUNC;
199  }
200 
201  if (ScheduleTable_Cfg[scheduleTableID_to]->currentState != SCHEDULETABLE_STOPPED) {
203 
204  return E_OS_STATE;
205  }
206 
207  if (ScheduleTable_Cfg[scheduleTableID_from]->next != INVALID_SCHEDULETABLE) {
209  }
210 
211  ScheduleTable_Cfg[scheduleTableID_from]->next = scheduleTableID_to;
212  ScheduleTable_Cfg[scheduleTableID_to]->currentState = SCHEDULETABLE_NEXT;
213  }
214 
215  return E_OK;
216 }
217 
219  ScheduleTableStatusRefType scheduleStatus)
220 {
221  OS_SET_ERROR_INFO2(OSServiceId_GetScheduleTableStatus, &scheduleTableID, sizeof(scheduleTableID), &scheduleStatus,
222  sizeof(scheduleStatus));
223 
224  if (OS_EXTENDED && scheduleTableID >= INVALID_SCHEDULETABLE) {
226 
227  return E_OS_ID;
228  }
229 
230  if (OS_EXTENDED && scheduleStatus == NULL) {
232 
233  return E_OS_PARAM_POINTER;
234  }
235 
236  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
237  *scheduleStatus = ScheduleTable_Cfg[scheduleTableID]->currentState;
238  }
239 
240  /* Return SCHEDULETABLE_PRE_RUNNING as SCHEDULETABLE_RUNNING to conform to AUTOSAR standard */
241  if (*scheduleStatus == SCHEDULETABLE_PRE_RUNNING) {
242  *scheduleStatus = SCHEDULETABLE_RUNNING;
243  }
244 
245  return E_OK;
246 }
247 
249 {
250  for (uint8_t i = 0; i < SCHEDULETABLE_COUNT; i++) {
251  if (ScheduleTable_Cfg[i]->counter != counter) {
252  // Only evaluate schedule table if the associated counter was changed
253  continue;
254  }
255 
256  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
257  if (ScheduleTable_Cfg[i]->currentState != SCHEDULETABLE_RUNNING
258  && ScheduleTable_Cfg[i]->currentState != SCHEDULETABLE_PRE_RUNNING) {
259  continue;
260  }
261 
263 
264  if (ScheduleTable_Cfg[i]->currentState == SCHEDULETABLE_PRE_RUNNING) {
265  if (ScheduleTable_Cfg[i]->currentTick == 0) {
266  // Counter wrapped => schedule table is now actually running
268  } else {
269  // Skip schedule table if not actually running yet
270  continue;
271  }
272  }
273 
274  uint8_t expiryPoint;
275  for (expiryPoint = 0; expiryPoint < ScheduleTable_Cfg[i]->numExpiryPoints; expiryPoint++) {
276  if (ScheduleTable_Cfg[i]->expiryPointList[expiryPoint].offset == ScheduleTable_Cfg[i]->currentTick) {
277  ScheduleTable_handleExpiryPoint(&ScheduleTable_Cfg[i]->expiryPointList[expiryPoint]);
278 
279  // Increment counter for end of table handling below
280  expiryPoint += 1;
281 
282  // Only one expiry point per offset per schedule table allowed
283  break;
284  } else if (ScheduleTable_Cfg[i]->expiryPointList[expiryPoint].offset
285  > ScheduleTable_Cfg[i]->currentTick) {
286  // Reached upcoming expiry points
287  break;
288  }
289  }
290 
291  /* Handle end of schedule table */
292  if (expiryPoint == ScheduleTable_Cfg[i]->numExpiryPoints) {
293  if (ScheduleTable_Cfg[i]->finalDelay == 0
294  || ScheduleTable_Cfg[i]->finalDelay == ScheduleTable_Cfg[i]->currentTick -
295  ScheduleTable_Cfg[i]->expiryPointList[expiryPoint - 1].offset) {
296  if (ScheduleTable_Cfg[i]->cyclic && ScheduleTable_Cfg[i]->next == INVALID_SCHEDULETABLE) {
297  // Schedule table is cyclic and no other schedule table has been queued => restart it
298  ScheduleTable_handleScheduleTableStart(i);
299  } else {
300  /* Stop schedule table */
302 
303  if (ScheduleTable_Cfg[i]->counter == SYSTEM_COUNTER) {
304  needSysTickEval -= 1;
305  }
306 
307  /* Check if another schedule table is queued */
308  if (ScheduleTable_Cfg[i]->next != INVALID_SCHEDULETABLE) {
309  if (i < ScheduleTable_Cfg[i]->next
310  && ScheduleTable_Cfg[ScheduleTable_Cfg[i]->next]->counter == counter) {
311 
312  /* Start queued schedule table (will be handled within this tick evaluation) */
313  if (ScheduleTable_Cfg[ScheduleTable_Cfg[i]->next]->counter == SYSTEM_COUNTER) {
314  needSysTickEval += 1;
315  }
316 
319  } else {
320  /* Start queued schedule table and handle initial expiry point if necessary */
321  if (ScheduleTable_Cfg[ScheduleTable_Cfg[i]->next]->counter == SYSTEM_COUNTER) {
322  needSysTickEval += 1;
323  }
324 
325  ScheduleTable_handleScheduleTableStart(ScheduleTable_Cfg[i]->next);
326  }
327 
328  // Reset queued schedule table field
329  ScheduleTable_Cfg[i]->next = INVALID_SCHEDULETABLE;
330  }
331  }
332  }
333  }
334  }
335  }
336 }
337 
339 {
340  ScheduleTable_handleTick(SYSTEM_COUNTER);
341 }
342 
343 extern void ScheduleTable_startup(void)
344 {
345  if (SCHEDULETABLE_COUNT > 0) {
346  assert(SCHEDULETABLE_COUNT <= UINT8_MAX);
347 
348  for (uint8_t i = 0; i < SCHEDULETABLE_COUNT; i++) {
349  /* Start all schedule tables configured as autostart */
350  if (ScheduleTable_Cfg[i]->autoStart == true) {
351  if (ScheduleTable_Cfg[i]->counter == SYSTEM_COUNTER) {
352  needSysTickEval += 1;
353  }
354 
355  ScheduleTable_handleScheduleTableStart(i);
356  }
357  }
358  }
359 }
StatusType
enum StatusType_e StatusType
Type for status.
blockScheduling
volatile uint8_t blockScheduling
Block scheduling.
Definition: OCB.c:27
ScheduleTables.h
Schedule tables management.
OS.h
Operating system control.
E_OS_NOFUNC
@ E_OS_NOFUNC
Definition: Types.h:45
TickType
uint64_t TickType
Data type of counter values.
Definition: CounterTypes.h:21
scheduleTableExpiryPoint_s
Structure for expiry point.
Definition: ScheduleTableTypes.h:60
Task.h
Task management.
ScheduleTable_Cfg
struct scheduleTable_s * ScheduleTable_Cfg[]
Current schedule table control blocks.
assert.h
Assert macros and functions.
ScheduleTable_NextScheduleTable
StatusType ScheduleTable_NextScheduleTable(ScheduleTableType scheduleTableID_from, ScheduleTableType scheduleTableID_to)
Queue schedule table.
Definition: ScheduleTables.c:174
OSServiceId_NextScheduleTable
@ OSServiceId_NextScheduleTable
Definition: ErrorTypes.h:56
CounterType
enum counters_e CounterType
Type for counter reference.
Definition: CounterTypes.h:33
scheduleTableExpiryPoint_s::taskActionList
const struct scheduleTableExpiryActionTask_s * taskActionList
List of task activation actions (may be NULL if numTaskActions equals zero)
Definition: ScheduleTableTypes.h:63
E_OK
@ E_OK
Definition: Types.h:40
ScheduleTable_StartScheduleTableAbs
StatusType ScheduleTable_StartScheduleTableAbs(ScheduleTableType scheduleTableID, TickType start)
Start schedule table from absolute start.
Definition: ScheduleTables.c:116
Events_SetEvent
StatusType Events_SetEvent(TaskType TaskID, EventMaskType events)
Set events.
Definition: Events.c:22
OS_SET_ERROR_INFO1
#define OS_SET_ERROR_INFO1(serviceId, paramPtr1, size1)
Set error info with up to one parameter.
Definition: ErrorTypes.h:220
needSysTickEval
volatile uint8_t needSysTickEval
SysTick must be evaluated during timer interrupt.
Definition: OCB.c:30
ScheduleTableType
enum scheduleTables_e ScheduleTableType
Type for schedule table reference.
Definition: ScheduleTableTypes.h:25
Events.h
Event management.
ScheduleTable_StopScheduleTable
StatusType ScheduleTable_StopScheduleTable(ScheduleTableType scheduleTableID)
Stop schedule table.
Definition: ScheduleTables.c:147
OSServiceId_StopScheduleTable
@ OSServiceId_StopScheduleTable
Definition: ErrorTypes.h:55
OSServiceId_GetScheduleTableStatus
@ OSServiceId_GetScheduleTableStatus
Definition: ErrorTypes.h:57
scheduleTableExpiryPoint_s::numTaskActions
const uint8_t numTaskActions
Length of taskActionList.
Definition: ScheduleTableTypes.h:62
counter_s::maxallowedvalue
const TickType maxallowedvalue
Maximum allowed value of counter.
Definition: CounterTypes.h:47
SCHEDULETABLE_STOPPED
@ SCHEDULETABLE_STOPPED
Schedule table is stopped.
Definition: ScheduleTableTypes.h:31
scheduleTableExpiryActionEvent_s::event
const EventMaskType event
Mask of events to set.
Definition: ScheduleTableTypes.h:54
SCHEDULETABLE_NEXT
@ SCHEDULETABLE_NEXT
Schedule table is queued after another table.
Definition: ScheduleTableTypes.h:32
assert
#define assert(expression)
Definition: assert.h:37
ScheduleTable_startup
void ScheduleTable_startup(void)
Startup function for schedule table management.
Definition: ScheduleTables.c:343
Task_ActivateTask
StatusType Task_ActivateTask(TaskType TaskID)
Activate a task.
Definition: Task.c:21
OSServiceId_StartScheduleTableAbs
@ OSServiceId_StartScheduleTableAbs
Definition: ErrorTypes.h:54
ScheduleTable_StartScheduleTableRel
StatusType ScheduleTable_StartScheduleTableRel(ScheduleTableType scheduleTableID, TickType offset)
Start schedule table from relative offset.
Definition: ScheduleTables.c:79
ScheduleTable_GetScheduleTableStatus
StatusType ScheduleTable_GetScheduleTableStatus(ScheduleTableType scheduleTableID, ScheduleTableStatusRefType scheduleStatus)
Get schedule table status.
Definition: ScheduleTables.c:218
scheduleTableExpiryPoint_s::numEventActions
const uint8_t numEventActions
Length of eventActionList.
Definition: ScheduleTableTypes.h:65
OS_EXTENDED
#define OS_EXTENDED
Definition: OCB.h:156
scheduleTable_s::counter
const CounterType counter
Counter driving the schedule table.
Definition: ScheduleTableTypes.h:78
resource_s::next
struct resource_s * next
Pointer to next resource in resource queue.
Definition: ResourceTypes.h:32
E_OS_STATE
@ E_OS_STATE
Definition: Types.h:47
E_OS_ID
@ E_OS_ID
Definition: Types.h:43
scheduleTable_s::currentState
volatile ScheduleTableStatusType currentState
Current state of the schedule table.
Definition: ScheduleTableTypes.h:83
Counter_GetCounterValue
StatusType Counter_GetCounterValue(CounterType counterID, TickRefType value)
Read current counter value.
Definition: Counter.c:51
scheduleTableExpiryActionEvent_s::task
const TaskType task
ID of task to set events for.
Definition: ScheduleTableTypes.h:53
scheduleTable_s::numExpiryPoints
const uint8_t numExpiryPoints
Length of expiryPointList.
Definition: ScheduleTableTypes.h:76
Counter.h
Counter management.
Counter_Cfg
volatile struct counter_s * Counter_Cfg[]
Current counter control blocks.
OS_SET_ERROR_INFO2
#define OS_SET_ERROR_INFO2(serviceId, paramPtr1, size1, paramPtr2, size2)
Set error info with up to two parameters.
Definition: ErrorTypes.h:234
scheduleTable_s::next
volatile ScheduleTableType next
Schedule table queued after the current one.
Definition: ScheduleTableTypes.h:84
ScheduleTable_handleSysTick
void ScheduleTable_handleSysTick(void)
Handle system tick.
Definition: ScheduleTables.c:338
E_OS_PARAM_POINTER
@ E_OS_PARAM_POINTER
Definition: Types.h:50
OCB.h
Operating System Control Block.
ScheduleTable_handleTick
void ScheduleTable_handleTick(CounterType counter)
Handle tick.
Definition: ScheduleTables.c:248
scheduleTableExpiryPoint_s::eventActionList
const struct scheduleTableExpiryActionEvent_s * eventActionList
List of event activation actions (may be NULL if numEventActions equals zero)
Definition: ScheduleTableTypes.h:66
OS_CALL_ERROR_HOOK
#define OS_CALL_ERROR_HOOK(error)
Call error hook if configured.
Definition: ErrorTypes.h:93
OSServiceId_StartScheduleTableRel
@ OSServiceId_StartScheduleTableRel
Definition: ErrorTypes.h:53
ScheduleTableStatusRefType
ScheduleTableStatusType * ScheduleTableStatusRefType
Type of status reference.
Definition: ScheduleTableTypes.h:40
SCHEDULETABLE_RUNNING
@ SCHEDULETABLE_RUNNING
Schedule table is running.
Definition: ScheduleTableTypes.h:34
E_OS_VALUE
@ E_OS_VALUE
Definition: Types.h:48
scheduleTable_s::currentTick
volatile TickType currentTick
Current tick of the schedule table.
Definition: ScheduleTableTypes.h:82
SCHEDULETABLE_PRE_RUNNING
@ SCHEDULETABLE_PRE_RUNNING
Schedule table is running but not yet executing until the tick reaches zero.
Definition: ScheduleTableTypes.h:33
scheduleTableExpiryActionTask_s::task
const TaskType task
ID of task to activate.
Definition: ScheduleTableTypes.h:46