Xmega IEC60730 Class B Library
1.0
All
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
classb_interrupt_monitor.c
Go to the documentation of this file.
1
/* This file has been prepared for Doxygen automatic documentation generation.*/
2
/**
3
* \file
4
*
5
* \brief
6
* This file contains functions for monitoring the frequency of execution of
7
* registered interrupts.
8
*
9
* \par Application note:
10
* AVR1610: Guide to IEC60730 Class B compliance with XMEGA
11
*
12
* \par Documentation
13
* For comprehensive code documentation, supported compilers, compiler
14
* settings and supported devices see readme.html
15
*
16
* \author
17
* Atmel Corporation: http://www.atmel.com \n
18
* Support email: avr@atmel.com
19
*
20
* Copyright (C) 2012 Atmel Corporation. All rights reserved.
21
*
22
* \page License
23
*
24
* Redistribution and use in source and binary forms, with or without
25
* modification, are permitted provided that the following conditions are met:
26
*
27
* 1. Redistributions of source code must retain the above copyright notice,
28
* this list of conditions and the following disclaimer.
29
*
30
* 2. Redistributions in binary form must reproduce the above copyright notice,
31
* this list of conditions and the following disclaimer in the documentation
32
* and/or other materials provided with the distribution.
33
*
34
* 3. The name of Atmel may not be used to endorse or promote products derived
35
* from this software without specific prior written permission.
36
*
37
* 4. This software may only be redistributed and used in connection with an
38
* Atmel AVR product.
39
*
40
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
41
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
43
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
44
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
47
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
50
* DAMAGE.
51
*/
52
53
54
#include "
classb_interrupt_monitor.h
"
55
56
//! \brief Array of data structures for the interrupts that should be monitored
57
struct
intmon_interrupt
monitored_interrupts
[
N_INTERRUPTS
];
58
59
60
/** \brief Registers an interrupt.
61
*
62
* This function registers the information that the monitor needs in order to
63
* check an interrupt. It should be called from the main application. Interrupts
64
* must be declared in \ref classb_int_identifiers in the configuration file.
65
* Note that by default the interrupt is not active for monitoring, i.e. the
66
* state is \c OFF.
67
*
68
* \param identifier Interrupt identifier. Use symbol declared in \ref classb_int_identifiers
69
* \param reference Number of expected executions for the interrupt within an RTC period:
70
* <tt>F_INT (Hz) * CLASSB_RTC_INT_PERIOD / CLASSB_RTC_FREQ (Hz) </tt>
71
* \param tolerance The allowed deviation (%) with respect to interrupt_counter for the interrupt counter.
72
* \callergraph
73
*/
74
void
classb_intmon_reg_int
(
enum
classb_int_identifiers
identifier, uint16_t reference, uint8_t tolerance)
75
{
76
77
monitored_interrupts
[identifier].n = reference;
78
monitored_interrupts
[identifier].c = 0;
79
monitored_interrupts
[identifier].l = (reference * tolerance) / 100;
80
monitored_interrupts
[identifier].s = OFF;
81
82
}
83
84
/*! \brief Increases the interrupt counter of the specified interrupt.
85
*
86
* This is called from the interrupt routine and it will increases the counter
87
* if the interrupt is \c ON.
88
*
89
* \param identifier Interrupt identifier. Use symbol declared in \ref classb_int_identifiers
90
*
91
* \callergraph
92
*/
93
void
classb_intmon_increase
(
enum
classb_int_identifiers
identifier )
94
{
95
96
if
(
monitored_interrupts
[identifier].s == ON)
97
monitored_interrupts
[identifier].c++;
98
99
}
100
101
/*! \brief Set a state for the specified interrupt.
102
*
103
* This function should be called from the main application to enable or disable monitoring this interrupt.
104
* The application can only set the state to ENABLE or DISABLE, otherwise the error handler will be called.
105
* i.e. only the monitor can set \c ON and \c OFF states. Further, if \ref CLASSB_STRICT is defined, it is not allowed
106
* to enable an interrupt in the \c ON state, or disable an interrupt in the \c OFF state.
107
*
108
* \param identifier Interrupt identifier. Use symbol declared in \ref classb_int_identifiers.
109
* \param state Interrupt state. Use symbol declared in \ref classb_int_states.
110
*
111
* \callergraph
112
*/
113
void
classb_intmon_set_state
(
enum
classb_int_identifiers
identifier,
enum
classb_int_states
state )
114
{
115
116
switch
(state)
117
{
118
case
ENABLE
:
119
#ifdef CLASSB_STRICT
120
if
(
monitored_interrupts
[identifier].s != OFF)
121
{
122
CLASSB_ERROR_HANDLER_INTERRUPT
();
123
break
;
124
}
125
#endif
126
break
;
127
128
case
DISABLE
:
129
#ifdef CLASSB_STRICT
130
if
(
monitored_interrupts
[identifier].s != ON)
131
{
132
CLASSB_ERROR_HANDLER_INTERRUPT
();
133
break
;
134
}
135
#endif
136
break
;
137
default
:
138
CLASSB_ERROR_HANDLER_INTERRUPT
();
139
}
140
141
// Set the new state only if CLASSB_CONDITION1_INTERRUPT is true.
142
if
(
CLASSB_CONDITION1_INTERRUPT
)
143
monitored_interrupts
[identifier].s = state;
144
145
}
146
147
148
149
//! \internal\brief Returns the absolute value of the difference between two numbers.
150
static
inline
uint16_t abs_diff(uint16_t a, uint16_t b)
151
{
152
return
(a > b)?(a - b):(b - a);
153
}
154
155
/*! \brief The interrupt monitor.
156
*
157
* For each registered interrupt, this function compares the counter with
158
* the expected value. There is an error if the difference is greater
159
* than the limit or if the interrupt is disabled and the counter is different
160
* than zero. If \ref CLASSB_CONDITION2_INTERRUPT is true, the monitor will stop
161
* immediately, i.e. the remaining interrupts are not checked.
162
*
163
* \note This should be called back from the RTC interrupt. See \ref rtc_driver.
164
*
165
* \callergraph
166
*/
167
void
classb_intmon_callback
()
168
{
169
170
for
(uint8_t i = 0; i <
N_INTERRUPTS
; i++ )
171
{
172
173
switch
(
monitored_interrupts
[i].s)
174
{
175
case
ON:
176
// Check whether the counter is within the allowed range
177
if
( (uint16_t) abs_diff(
monitored_interrupts
[i].c,
monitored_interrupts
[i].n) >
monitored_interrupts
[i].l) {
178
CLASSB_ERROR_HANDLER_INTERRUPT
();
179
break
;
180
}
181
// Reset counter
182
monitored_interrupts
[i].c = 0;
183
break
;
184
case
OFF:
185
// The counter is only increased when the state is ON.
186
if
(
monitored_interrupts
[i].c)
187
CLASSB_ERROR_HANDLER_INTERRUPT
();
188
break
;
189
case
ENABLE
:
190
// Change state
191
monitored_interrupts
[i].s = ON;
192
break
;
193
case
DISABLE
:
194
// Change state and reset the counter
195
monitored_interrupts
[i].s = OFF;
196
monitored_interrupts
[i].c = 0;
197
break
;
198
default
:
199
CLASSB_ERROR_HANDLER_INTERRUPT
();
200
}
201
202
// If CLASSB_CONDITION2_INTERRUPT is true, there is no need to check the other interrupts.
203
if
(
CLASSB_CONDITION2_INTERRUPT
)
204
break
;
205
}
206
}
tests
interrupts
classb_interrupt_monitor.c
Generated by
1.8.1