2 ******************************************************************************
3 * @addtogroup OpenPilotSystem OpenPilot System
5 * @addtogroup OpenPilotLibraries OpenPilot System Libraries
6 * @brief OpenPilot System libraries are available to all OP modules.
9 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
10 * @brief Library for setting and clearing system alarms
11 * @see The GNU Public License (GPL) Version 3
13 *****************************************************************************/
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <openpilot.h>
31 #include <pios_struct_helper.h>
32 #include "inc/alarms.h"
35 #ifndef PIOS_ALARM_GRACETIME
36 // alarm cannot be turned off for at least 1000 milliseconds
37 // to prevent event system overload through flapping alarms
38 #define PIOS_ALARM_GRACETIME 1000
39 #endif // PIOS_ALARM_GRACETIME
44 static xSemaphoreHandle lock
;
45 static volatile uint16_t lastAlarmChange
[SYSTEMALARMS_ALARM_NUMELEM
] = { 0 }; // this deliberately overflows every 2^16 milliseconds to save memory
48 static int32_t hasSeverity(SystemAlarmsAlarmOptions severity
);
51 * Initialize the alarms library
53 int32_t AlarmsInitialize(void)
55 SystemAlarmsInitialize();
57 lock
= xSemaphoreCreateRecursiveMutex();
58 // do not change the default states of the alarms, let the init code generated by the uavobjectgenerator handle that
60 // AlarmsDefaultAll();
66 * @param alarm The system alarm to be modified
67 * @param severity The alarm severity
68 * @return 0 if success, -1 if an error
70 int32_t AlarmsSet(SystemAlarmsAlarmElem alarm
, SystemAlarmsAlarmOptions severity
)
72 SystemAlarmsAlarmData alarms
;
74 // Check that this is a valid alarm
75 if (alarm
>= SYSTEMALARMS_ALARM_NUMELEM
) {
80 xSemaphoreTakeRecursive(lock
, portMAX_DELAY
);
82 // Read alarm and update its severity only if it was changed
83 SystemAlarmsAlarmGet(&alarms
);
84 uint16_t flightTime
= (uint16_t)xTaskGetTickCount() * (uint16_t)portTICK_RATE_MS
; // this deliberately overflows every 2^16 milliseconds to save memory
85 if (((uint16_t)(flightTime
- lastAlarmChange
[alarm
]) > PIOS_ALARM_GRACETIME
&&
86 cast_struct_to_array(alarms
, alarms
.Actuator
)[alarm
] != severity
)
87 || cast_struct_to_array(alarms
, alarms
.Actuator
)[alarm
] < severity
) {
88 cast_struct_to_array(alarms
, alarms
.Actuator
)[alarm
] = severity
;
89 lastAlarmChange
[alarm
] = flightTime
;
90 SystemAlarmsAlarmSet(&alarms
);
94 xSemaphoreGiveRecursive(lock
);
99 * Set an Extended Alarm
100 * @param alarm The system alarm to be modified
101 * @param severity The alarm severity
102 * @param status The Extended alarm status field
103 * @param subStatus The Extended alarm substatus field
104 * @return 0 if success, -1 if an error
106 int32_t ExtendedAlarmsSet(SystemAlarmsAlarmElem alarm
,
107 SystemAlarmsAlarmOptions severity
,
108 SystemAlarmsExtendedAlarmStatusOptions status
,
111 SystemAlarmsData alarms
;
113 // Check that this is a valid alarm
114 if (alarm
>= SYSTEMALARMS_EXTENDEDALARMSTATUS_NUMELEM
) {
119 xSemaphoreTakeRecursive(lock
, portMAX_DELAY
);
121 // Read alarm and update its severity only if it was changed
122 SystemAlarmsGet(&alarms
);
123 uint16_t flightTime
= (uint16_t)xTaskGetTickCount() * (uint16_t)portTICK_RATE_MS
; // this deliberately overflows every 2^16 milliseconds to save memory
124 if (((uint16_t)(flightTime
- lastAlarmChange
[alarm
]) > PIOS_ALARM_GRACETIME
&&
125 cast_struct_to_array(alarms
.Alarm
, alarms
.Alarm
.Actuator
)[alarm
] != severity
)
126 || cast_struct_to_array(alarms
.Alarm
, alarms
.Alarm
.Actuator
)[alarm
] < severity
) {
127 cast_struct_to_array(alarms
.ExtendedAlarmStatus
, alarms
.ExtendedAlarmStatus
.BootFault
)[alarm
] = status
;
128 cast_struct_to_array(alarms
.ExtendedAlarmSubStatus
, alarms
.ExtendedAlarmStatus
.BootFault
)[alarm
] = subStatus
;
129 cast_struct_to_array(alarms
.Alarm
, alarms
.Alarm
.Actuator
)[alarm
] = severity
;
130 lastAlarmChange
[alarm
] = flightTime
;
131 SystemAlarmsSet(&alarms
);
135 xSemaphoreGiveRecursive(lock
);
141 * @param alarm The system alarm to be read
142 * @return Alarm severity
144 SystemAlarmsAlarmOptions
AlarmsGet(SystemAlarmsAlarmElem alarm
)
146 SystemAlarmsAlarmData alarms
;
148 // Check that this is a valid alarm
149 if (alarm
>= SYSTEMALARMS_ALARM_NUMELEM
) {
154 SystemAlarmsAlarmGet(&alarms
);
155 return cast_struct_to_array(alarms
, alarms
.Actuator
)[alarm
];
159 * Set an alarm to it's default value
160 * @param alarm The system alarm to be modified
161 * @return 0 if success, -1 if an error
163 int32_t AlarmsDefault(SystemAlarmsAlarmElem alarm
)
165 return AlarmsSet(alarm
, SYSTEMALARMS_ALARM_DEFAULT
);
171 void AlarmsDefaultAll()
173 for (uint32_t n
= 0; n
< SYSTEMALARMS_ALARM_NUMELEM
; ++n
) {
180 * @param alarm The system alarm to be modified
181 * @return 0 if success, -1 if an error
183 int32_t AlarmsClear(SystemAlarmsAlarmElem alarm
)
185 if (alarm
< SYSTEMALARMS_EXTENDEDALARMSTATUS_NUMELEM
) {
186 return ExtendedAlarmsSet(alarm
, SYSTEMALARMS_ALARM_OK
, SYSTEMALARMS_EXTENDEDALARMSTATUS_NONE
, 0);
188 return AlarmsSet(alarm
, SYSTEMALARMS_ALARM_OK
);
195 void AlarmsClearAll()
197 for (uint32_t n
= 0; n
< SYSTEMALARMS_ALARM_NUMELEM
; ++n
) {
203 * Check if there are any alarms with the given or higher severity
204 * @return 0 if no alarms are found, 1 if at least one alarm is found
206 int32_t AlarmsHasWarnings()
208 return hasSeverity(SYSTEMALARMS_ALARM_WARNING
);
212 * Check if there are any alarms with error or higher severity
213 * @return 0 if no alarms are found, 1 if at least one alarm is found
215 int32_t AlarmsHasErrors()
217 return hasSeverity(SYSTEMALARMS_ALARM_ERROR
);
222 * Check if there are any alarms with critical or higher severity
223 * @return 0 if no alarms are found, 1 if at least one alarm is found
225 int32_t AlarmsHasCritical()
227 return hasSeverity(SYSTEMALARMS_ALARM_CRITICAL
);
232 * Check if there are any alarms with the given or higher severity
233 * @return 0 if no alarms are found, 1 if at least one alarm is found
235 static int32_t hasSeverity(SystemAlarmsAlarmOptions severity
)
237 SystemAlarmsAlarmData alarms
;
240 xSemaphoreTakeRecursive(lock
, portMAX_DELAY
);
243 SystemAlarmsAlarmGet(&alarms
);
245 // Go through alarms and check if any are of the given severity or higher
246 for (uint32_t n
= 0; n
< SYSTEMALARMS_ALARM_NUMELEM
; ++n
) {
247 if (cast_struct_to_array(alarms
, alarms
.Actuator
)[n
] >= severity
) {
248 xSemaphoreGiveRecursive(lock
);
253 // If this point is reached then no alarms found
254 xSemaphoreGiveRecursive(lock
);
258 * Get the highest alarm severity
261 SystemAlarmsAlarmOptions
AlarmsGetHighestSeverity()
263 SystemAlarmsAlarmData alarmsData
;
264 SystemAlarmsAlarmOptions highest
= SYSTEMALARMS_ALARM_UNINITIALISED
;
267 xSemaphoreTakeRecursive(lock
, portMAX_DELAY
);
270 SystemAlarmsAlarmGet(&alarmsData
);
272 // Go through alarms and find the highest severity
274 while (n
< SYSTEMALARMS_ALARM_NUMELEM
&& highest
!= SYSTEMALARMS_ALARM_CRITICAL
) {
275 if (cast_struct_to_array(alarmsData
, alarmsData
.Actuator
)[n
] > highest
) {
276 highest
= cast_struct_to_array(alarmsData
, alarmsData
.Actuator
)[n
];
281 xSemaphoreGiveRecursive(lock
);