AutosarOS
Alarm.c
Go to the documentation of this file.
1 
14 #include "Alarm.h"
15 #include "OS_API.h"
16 #include "assert.h"
17 
18 #include <util/atomic.h>
19 #include <string.h>
20 
21 /************************************************************************/
22 /* STATIC FUNCTIONS */
23 /************************************************************************/
32 static void Alarm_handleAlarmExpiration(AlarmType alarmID);
33 
34 /************************************************************************/
35 /* EXTERN FUNCTIONS */
36 /************************************************************************/
38 {
39  OS_SET_ERROR_INFO2(OSServiceId_GetAlarmBase, &alarmID, sizeof(alarmID), &info, sizeof(info));
40 
41  if (OS_EXTENDED && alarmID >= INVALID_ALARM) {
43 
44  return E_OS_ID;
45  }
46 
47  if (OS_EXTENDED && info == NULL) {
49 
50  return E_OS_PARAM_POINTER;
51  }
52 
53  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
54  memcpy((void*) info, (void*) Alarm_Cfg[alarmID]->alarmBase, sizeof(AlarmBaseType));
55  }
56 
57  return E_OK;
58 }
59 
61 {
62  OS_SET_ERROR_INFO2(OSServiceId_GetAlarm, &alarmID, sizeof(alarmID), &tick, sizeof(tick));
63 
64  if (OS_EXTENDED && alarmID >= INVALID_ALARM) {
66 
67  return E_OS_ID;
68  }
69 
70  if (OS_EXTENDED && tick == NULL) {
72 
73  return E_OS_PARAM_POINTER;
74  }
75 
76  TickType currentTick = 0;
77 
78  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
79  if (!Alarm_Cfg[alarmID]->running) {
81 
82  return E_OS_NOFUNC;
83  }
84 
85  *tick = Alarm_Cfg[alarmID]->expiration;
86 
87  if (Alarm_Cfg[alarmID]->alarmBase == Counter_Cfg[SYSTEM_COUNTER]) {
88  currentTick = sysTick;
89  } else {
90  currentTick = Alarm_Cfg[alarmID]->alarmBase->value;
91  }
92  }
93 
94  if (*tick >= currentTick) {
95  *tick = *tick - currentTick;
96  } else {
97  *tick = Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue - currentTick + *tick + 1;
98  }
99 
100  return E_OK;
101 }
102 
103 extern StatusType Alarm_SetRelAlarm(AlarmType alarmID, TickType increment, TickType cycle)
104 {
105  OS_SET_ERROR_INFO3(OSServiceId_SetRelAlarm, &alarmID, sizeof(alarmID), &increment, sizeof(increment), &cycle,
106  sizeof(cycle));
107 
108  if (OS_EXTENDED && alarmID >= INVALID_ALARM) {
110 
111  return E_OS_ID;
112  }
113 
114  if (increment == 0 || increment > Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue) {
116 
117  return E_OS_VALUE;
118  }
119 
120  TickType tick = 0;
121 
122  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
123  if (Alarm_Cfg[alarmID]->alarmBase == Counter_Cfg[SYSTEM_COUNTER]) {
124  tick = sysTick;
125  } else {
126  tick = Alarm_Cfg[alarmID]->alarmBase->value;
127  }
128  }
129 
130  tick += increment;
131 
132  if (tick > Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue) {
133  tick -= Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue + 1;
134  }
135 
136  return Alarm_SetAbsAlarm(alarmID, tick, cycle);
137 }
138 
140 {
141  OS_SET_ERROR_INFO3(OSServiceId_SetRelAlarm, &alarmID, sizeof(alarmID), &start, sizeof(start), &cycle,
142  sizeof(cycle));
143 
144  if (OS_EXTENDED && alarmID >= INVALID_ALARM) {
146 
147  return E_OS_ID;
148  }
149 
150  if (OS_EXTENDED && start > Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue) {
151  // Requested increment outside of allowed range
153 
154  return E_OS_VALUE;
155  }
156 
157  if (OS_EXTENDED && (cycle != 0 && (cycle < Alarm_Cfg[alarmID]->alarmBase->mincycle
158  || cycle > Alarm_Cfg[alarmID]->alarmBase->maxallowedvalue))) {
159  // Requested cycle outside of allowed range
161 
162  return E_OS_VALUE;
163  }
164 
165  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
166  if (Alarm_Cfg[alarmID]->running) {
168 
169  return E_OS_STATE;
170  }
171 
172  if (Alarm_Cfg[alarmID]->alarmBase == Counter_Cfg[SYSTEM_COUNTER]) {
173  needSysTickEval += 1;
174  }
175 
176  Alarm_Cfg[alarmID]->expiration = start;
177  Alarm_Cfg[alarmID]->cycle = cycle;
178  Alarm_Cfg[alarmID]->running = true;
179  }
180 
181  return E_OK;
182 }
183 
185 {
186  OS_SET_ERROR_INFO1(OSServiceId_GetAlarm, &alarmID, sizeof(alarmID));
187 
188  if (OS_EXTENDED && alarmID >= INVALID_ALARM) {
190 
191  return E_OS_ID;
192  }
193 
194  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
195  if (!Alarm_Cfg[alarmID]->running) {
197 
198  return E_OS_NOFUNC;
199  }
200 
201  if (Alarm_Cfg[alarmID]->alarmBase == Counter_Cfg[SYSTEM_COUNTER]) {
202  needSysTickEval -= 1;
203  }
204 
205  Alarm_Cfg[alarmID]->running = false;
206  }
207 
208  return E_OK;
209 }
210 
211 extern void Alarm_evaluateAlarm(CounterType counter)
212 {
213  if (counter == SYSTEM_COUNTER) {
214  return;
215  }
216 
217  for (uint8_t i = 0; i < ALARM_COUNT; i++) {
218  bool expired = false;
219 
220  if (Alarm_Cfg[i]->alarmBase != Counter_Cfg[counter]) {
221  // Handle alarms for the changed counter only
222  continue;
223  }
224 
225  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
226  expired = Alarm_Cfg[i]->running && (Alarm_Cfg[i]->alarmBase->value == Alarm_Cfg[i]->expiration);
227  }
228 
229  if (expired) {
230  Alarm_handleAlarmExpiration(i);
231  }
232  }
233 }
234 
235 extern void Alarm_evaluateSysTickAlarm(void)
236 {
237  for (uint8_t i = 0; i < ALARM_COUNT; i++) {
238  bool expired = false;
239 
240  if (Alarm_Cfg[i]->alarmBase != Counter_Cfg[SYSTEM_COUNTER]) {
241  // Handle SysTick based alarm only
242  continue;
243  }
244 
245  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
246  expired = Alarm_Cfg[i]->running && (sysTick == Alarm_Cfg[i]->expiration);
247 
248  if (expired) {
249  needSysTickEval -= 1;
250  }
251  }
252 
253  if (expired) {
254  Alarm_handleAlarmExpiration(i);
255  }
256  }
257 }
258 
259 extern void Alarm_startup(void)
260 {
261  for (uint8_t i = 0; i < ALARM_COUNT; i++) {
262  if (Alarm_Cfg[i]->running && Alarm_Cfg[i]->alarmBase == Counter_Cfg[SYSTEM_COUNTER]) {
263  needSysTickEval += 1;
264  }
265  }
266 }
267 
268 static void Alarm_handleAlarmExpiration(AlarmType alarmID)
269 {
270  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
271  Alarm_Cfg[alarmID]->running = false;
272  }
273 
274  /* Perform configured action */
275  switch (Alarm_Cfg[alarmID]->actionType) {
276  case ALARM_ACTION_TASK:
277  Task_ActivateTask(Alarm_Cfg[alarmID]->action.task);
278  break;
279  case ALARM_ACTION_EVENT:
280  Events_SetEvent(Alarm_Cfg[alarmID]->action.task, Alarm_Cfg[alarmID]->event);
281  break;
283  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
284  // Run callback with interrupts disabled
285  Alarm_Cfg[alarmID]->action.callback();
286  }
287  break;
289  Counter_IncrementCounter(Alarm_Cfg[alarmID]->action.counter);
290  break;
291  default:
292  // We should not reach this part.
293  assert(false);
294  break;
295  }
296 
297  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
298  if (Alarm_Cfg[alarmID]->cycle != 0) {
299  // Alarm is cyclic -> set it again as relative alarm
300  Alarm_SetRelAlarm(alarmID, Alarm_Cfg[alarmID]->cycle, Alarm_Cfg[alarmID]->cycle);
301  }
302  }
303 }
alarm_s::running
bool running
Whether or not the alarm is currently running.
Definition: AlarmTypes.h:75
Alarm_GetAlarmBase
StatusType Alarm_GetAlarmBase(AlarmType alarmID, AlarmBaseRefType info)
Get alarm base.
Definition: Alarm.c:37
Alarm_SetAbsAlarm
StatusType Alarm_SetAbsAlarm(AlarmType alarmID, TickType start, TickType cycle)
Set absolute alarm.
Definition: Alarm.c:139
Alarm_evaluateSysTickAlarm
void Alarm_evaluateSysTickAlarm(void)
Evaluate alarm with SYSTEM_COUNTER.
Definition: Alarm.c:235
ALARM_ACTION_COUNTER
@ ALARM_ACTION_COUNTER
Alarm increments counter on expiration.
Definition: AlarmTypes.h:58
StatusType
enum StatusType_e StatusType
Type for status.
AlarmBaseType
volatile struct counter_s AlarmBaseType
Type for alarm base.
Definition: AlarmTypes.h:39
alarm_s::cycle
TickType cycle
Relative value used for cyclic alarm (zero for oneshot alarm)
Definition: AlarmTypes.h:78
alarm_s::counter
const CounterType counter
Counter to increment if type is ALARM_ACTION_COUNTER.
Definition: AlarmTypes.h:73
OSServiceId_GetAlarm
@ OSServiceId_GetAlarm
Definition: ErrorTypes.h:25
OSServiceId_GetAlarmBase
@ OSServiceId_GetAlarmBase
Definition: ErrorTypes.h:24
E_OS_NOFUNC
@ E_OS_NOFUNC
Definition: Types.h:45
Alarm_GetAlarm
StatusType Alarm_GetAlarm(AlarmType alarmID, TickRefType tick)
Get alarm.
Definition: Alarm.c:60
alarm_s::alarmBase
const AlarmBaseRefType alarmBase
Reference to counter used as alarm base.
Definition: AlarmTypes.h:65
alarm_s::task
const TaskType task
Task to activate if type is ALARM_ACTION_TASK or to set event for if type is ALARM_ACTION_EVENT.
Definition: AlarmTypes.h:70
TickType
uint64_t TickType
Data type of counter values.
Definition: CounterTypes.h:21
AlarmType
enum alarm_e AlarmType
Type for alarm reference.
Definition: AlarmTypes.h:49
alarm_s::expiration
TickType expiration
Absolute expiration value.
Definition: AlarmTypes.h:76
TickRefType
TickType * TickRefType
Reference to counter values.
Definition: CounterTypes.h:28
assert.h
Assert macros and functions.
CounterType
enum counters_e CounterType
Type for counter reference.
Definition: CounterTypes.h:33
sysTick
volatile uint32_t sysTick
Current system tick.
Definition: OCB.c:25
OSServiceId_SetRelAlarm
@ OSServiceId_SetRelAlarm
Definition: ErrorTypes.h:26
alarm_s::event
const EventMaskType event
Event to set if type is ALARM_ACTION_EVENT.
Definition: AlarmTypes.h:66
E_OK
@ E_OK
Definition: Types.h:40
Alarm_startup
void Alarm_startup(void)
Startup function for alarm management.
Definition: Alarm.c:259
Alarm_SetRelAlarm
StatusType Alarm_SetRelAlarm(AlarmType alarmID, TickType increment, TickType cycle)
Set relative alarm.
Definition: Alarm.c:103
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
Alarm.h
Alarm management.
needSysTickEval
volatile uint8_t needSysTickEval
SysTick must be evaluated during timer interrupt.
Definition: OCB.c:30
ALARM_ACTION_CALLBACK
@ ALARM_ACTION_CALLBACK
Alarm calls callback on expiration.
Definition: AlarmTypes.h:57
assert
#define assert(expression)
Definition: assert.h:37
ALARM_ACTION_TASK
@ ALARM_ACTION_TASK
Alarm activates task on expiration.
Definition: AlarmTypes.h:55
Task_ActivateTask
StatusType Task_ActivateTask(TaskType TaskID)
Activate a task.
Definition: Task.c:21
OS_API.h
Operating System API.
OS_EXTENDED
#define OS_EXTENDED
Definition: OCB.h:156
ALARM_COUNT
#define ALARM_COUNT
Count of alarm defined.
Definition: CfgGenMacros.h:402
Alarm_CancelAlarm
StatusType Alarm_CancelAlarm(AlarmType alarmID)
Cancel alarm.
Definition: Alarm.c:184
OS_SET_ERROR_INFO3
#define OS_SET_ERROR_INFO3(serviceId, paramPtr1, size1, paramPtr2, size2, paramPtr3, size3)
Set error info with up to three parameters.
Definition: ErrorTypes.h:250
Alarm_Cfg
volatile struct alarm_s * Alarm_Cfg[]
Current alarm control blocks.
Counter_IncrementCounter
StatusType Counter_IncrementCounter(CounterType counterID)
Increment counter.
Definition: Counter.c:21
E_OS_STATE
@ E_OS_STATE
Definition: Types.h:47
E_OS_ID
@ E_OS_ID
Definition: Types.h:43
Counter_Cfg
volatile struct counter_s * Counter_Cfg[]
Current counter control blocks.
alarm_s::action
const void * action
Untyped value to be used during configuration.
Definition: AlarmTypes.h:69
AlarmBaseRefType
AlarmBaseType * AlarmBaseRefType
Reference for alarm base.
Definition: AlarmTypes.h:44
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
E_OS_PARAM_POINTER
@ E_OS_PARAM_POINTER
Definition: Types.h:50
ALARM_ACTION_EVENT
@ ALARM_ACTION_EVENT
Alarm sets event on expiration.
Definition: AlarmTypes.h:56
OS_CALL_ERROR_HOOK
#define OS_CALL_ERROR_HOOK(error)
Call error hook if configured.
Definition: ErrorTypes.h:93
Alarm_evaluateAlarm
void Alarm_evaluateAlarm(CounterType counter)
Evaluate alarms with user generated counter.
Definition: Alarm.c:211
E_OS_VALUE
@ E_OS_VALUE
Definition: Types.h:48