aboutsummaryrefslogtreecommitdiff
path: root/src/modules/systemlib/hardfault_log.h
blob: c64381b420053aeb49c4de4500c350f33e3655f9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/****************************************************************************
 *
 *   Copyright (C) 2015 PX4 Development Team. All rights reserved.
 *   Author: @author David Sidrane <david_s5@nscdg.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/
#pragma once
/****************************************************************************
 * Included Files
 ****************************************************************************/
#include <systemlib/px4_macros.h>
#include <stm32_bbsram.h>

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/
#define FREEZE_STR(s) #s
#define STRINGIFY(s) FREEZE_STR(s)
#define HARDFAULT_FILENO 3
#define HARDFAULT_PATH BBSRAM_PATH""STRINGIFY(HARDFAULT_FILENO)
#define HARDFAULT_REBOOT_FILENO 0
#define HARDFAULT_REBOOT_PATH BBSRAM_PATH""STRINGIFY(HARDFAULT_REBOOT_FILENO)


#define BBSRAM_SIZE_FN0 (sizeof(int))
#define BBSRAM_SIZE_FN1 384     /* greater then 2.5 times the size of vehicle_status_s */
#define BBSRAM_SIZE_FN2 384     /* greater then 2.5 times the size of vehicle_status_s */
#define BBSRAM_SIZE_FN3 -1

/* The following guides in the amount of the user and interrupt stack
 * data we can save. The amount of storage left will dictate the actual
 * number of entries of the user stack data saved. If it is too big
 * It will be truncated by the call to stm32_bbsram_savepanic
 */
#define BBSRAM_HEADER_SIZE 20 /* This is an assumption */
#define BBSRAM_USED ((4*BBSRAM_HEADER_SIZE)+(BBSRAM_SIZE_FN0+BBSRAM_SIZE_FN1+BBSRAM_SIZE_FN2))
#define BBSRAM_REAMINING (STM32_BBSRAM_SIZE-BBSRAM_USED)
#if CONFIG_ARCH_INTERRUPTSTACK <= 3
#  define BBSRAM_NUMBER_STACKS 1
#else
#  define BBSRAM_NUMBER_STACKS 2
#endif
#define BBSRAM_FIXED_ELEMENTS_SIZE (sizeof(info_s))
#define BBSRAM_LEFTOVER (BBSRAM_REAMINING-BBSRAM_FIXED_ELEMENTS_SIZE)

#define CONFIG_ISTACK_SIZE (BBSRAM_LEFTOVER/BBSRAM_NUMBER_STACKS/sizeof(stack_word_t))
#define CONFIG_USTACK_SIZE (BBSRAM_LEFTOVER/BBSRAM_NUMBER_STACKS/sizeof(stack_word_t))

/* The path to the Battery Backed up SRAM */
#define BBSRAM_PATH "/fs/bbr"
/* The sizes of the files to create (-1) use rest of BBSRAM memory */
#define BSRAM_FILE_SIZES { \
    BBSRAM_SIZE_FN0,   /* For Time stamp only */                  \
    BBSRAM_SIZE_FN1,   /* For Current Flight Parameters Copy A */ \
    BBSRAM_SIZE_FN2,   /* For Current Flight Parameters Copy B*/  \
    BBSRAM_SIZE_FN3,   /* For the Panic Log use rest of space */  \
    0                  /* End of table marker */                  \
}

/* For Assert keep this much of the file name*/
#define MAX_FILE_PATH_LENGTH 40


/* Fixed size strings
 * To change a format add the number of chars not represented by the format
 * Specifier to the xxxx_NUM definei.e %Y is YYYY so add 2 and %s is -2
 * Also xxxxTIME_FMT need to match in size. See CCASERT in hardfault_log.c
 */
#define LOG_PATH_BASE       "/fs/microsd/"
#define LOG_PATH_BASE_LEN    ((arraySize(LOG_PATH_BASE))-1)

#define LOG_NAME_FMT        "fault_%s.log"
#define LOG_NAME_NUM         (     -2    )
#define LOG_NAME_LEN         ((arraySize(LOG_NAME_FMT)-1) + LOG_NAME_NUM)

#define TIME_FMT             "%Y_%m_%d_%H_%M_%S"
#define TIME_FMT_NUM         (2+ 0+ 0+ 0+ 0+ 0)
#define TIME_FMT_LEN         (((arraySize(TIME_FMT)-1) + TIME_FMT_NUM))

#define LOG_PATH_LEN         ((LOG_PATH_BASE_LEN + LOG_NAME_LEN + TIME_FMT_LEN))

#define HEADER_TIME_FMT      "%Y-%m-%d-%H:%M:%S"
#define HEADER_TIME_FMT_NUM  (2+ 0+ 0+ 0+ 0+ 0)
#define HEADER_TIME_FMT_LEN  (((arraySize(HEADER_TIME_FMT)-1) + HEADER_TIME_FMT_NUM))

/* Select which format to use. On a terminal the details are at the bottom
 * and in a file they are at the top
 */
#define HARDFAULT_DISPLAY_FORMAT 1
#define HARDFAULT_FILE_FORMAT    0

/****************************************************************************
 * Public Types
 ****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
//{
#else
#define EXTERN extern
#endif

/* Used for stack frame storage */
typedef uint32_t stack_word_t;

/* Stack related data */

typedef struct {
  uint32_t sp;
  uint32_t top;
  uint32_t size;

} _stack_s;

typedef struct {
  _stack_s user;
#if CONFIG_ARCH_INTERRUPTSTACK > 3
  _stack_s interrupt;
#endif

} stack_t;

/* Not Used for reference only */

typedef struct
{
  uint32_t r0;
  uint32_t r1;
  uint32_t r2;
  uint32_t r3;
  uint32_t r4;
  uint32_t r5;
  uint32_t r6;
  uint32_t r7;
  uint32_t r8;
  uint32_t r9;
  uint32_t r10;
  uint32_t r11;
  uint32_t r12;
  uint32_t sp;
  uint32_t lr;
  uint32_t pc;
  uint32_t xpsr;
  uint32_t d0;
  uint32_t d1;
  uint32_t d2;
  uint32_t d3;
  uint32_t d4;
  uint32_t d5;
  uint32_t d6;
  uint32_t d7;
  uint32_t d8;
  uint32_t d9;
  uint32_t d10;
  uint32_t d11;
  uint32_t d12;
  uint32_t d13;
  uint32_t d14;
  uint32_t d15;
  uint32_t fpscr;
  uint32_t sp_main;
  uint32_t sp_process;
  uint32_t apsr;
  uint32_t ipsr;
  uint32_t epsr;
  uint32_t primask;
  uint32_t basepri;
  uint32_t faultmask;
  uint32_t control;
  uint32_t s0;
  uint32_t s1;
  uint32_t s2;
  uint32_t s3;
  uint32_t s4;
  uint32_t s5;
  uint32_t s6;
  uint32_t s7;
  uint32_t s8;
  uint32_t s9;
  uint32_t s10;
  uint32_t s11;
  uint32_t s12;
  uint32_t s13;
  uint32_t s14;
  uint32_t s15;
  uint32_t s16;
  uint32_t s17;
  uint32_t s18;
  uint32_t s19;
  uint32_t s20;
  uint32_t s21;
  uint32_t s22;
  uint32_t s23;
  uint32_t s24;
  uint32_t s25;
  uint32_t s26;
  uint32_t s27;
  uint32_t s28;
  uint32_t s29;
  uint32_t s30;
  uint32_t s31;
} proc_regs_s;


/* Flags to identify what is in the dump */
typedef enum {
  eRegsPresent          = 0x01,
  eUserStackPresent     = 0x02,
  eIntStackPresent      = 0x04,
  eInvalidUserStackPtr  = 0x20,
  eInvalidIntStackPrt   = 0x40,
} fault_flags_t;

typedef struct {
  fault_flags_t         flags;                  /* What is in the dump */
  uintptr_t             current_regs;           /* Used to validate the dump */
  int                   lineno;                 /* __LINE__ to up_assert */
  int                   pid;                    /* Process ID */
  uint32_t              regs[XCPTCONTEXT_REGS]; /* Interrupt register save
                                                 * area */
  stack_t               stacks;                 /* Stack info */
#if CONFIG_TASK_NAME_SIZE > 0
  char                  name[CONFIG_TASK_NAME_SIZE+1]; /* Task name (with NULL
                                                        * terminator) */
#endif
  char                  filename[MAX_FILE_PATH_LENGTH]; /* the Last of chars in
                                                      * __FILE__ to up_assert */
} info_s;

typedef struct {
  info_s    info;                       /* The info */
#if CONFIG_ARCH_INTERRUPTSTACK > 3      /* The amount of stack data is compile time
                                         * sized backed on what is left after the
                                         * other BBSRAM files are defined
                                         * The order is such that only the
                                         * ustack should be truncated
                                         */
  stack_word_t istack[CONFIG_USTACK_SIZE];
#endif
  stack_word_t ustack[CONFIG_ISTACK_SIZE];
} fullcontext_s;

/****************************************************************************
 * Name: hardfault_check_status
 *
 * Description:
 *      Check the status of the BBSRAM hard fault file which can be in
 *      one of two states Armed, Valid or Broken.
 *
 *      Armed - The file in the armed state is not accessible in the fs
 *              the act of unlinking it is what arms it.
 *
 *      Valid - The file in the armed state is not accessible in the fs
 *              the act of unlinking it is what arms it.
 *
 * Inputs:
 *   - caller:  A label to display in syslog output
 *
 *  Returned Value:
 *   -ENOENT    Armed - The file in the armed state
 *    OK        Valid - The file contains data from a fault that has not
 *                      been committed to disk (see write_hardfault).
 *   -  Any < 0 Broken - Should not happen
 *
 ****************************************************************************/
int hardfault_check_status(char *caller);

/****************************************************************************
 * Name: hardfault_write
 *
 * Description:
 *      Will parse and write a human readable output of the data
 *      in the BBSRAM file. Once
 *
 *
 * Inputs:
 *   - caller:  A label to display in syslog output
 *   - fd:      An FD to write the data to
 *   - format:  Select which format to use.
 *
 *              HARDFAULT_DISPLAY_FORMAT  On the console the details are
 *                                        at the bottom
 *              HARDFAULT_FILE_FORMAT     In a file details are at the top
 *                                        of the log file
 *
 *    - rearm: If true will move the file to the Armed state, if
 *             false the file is not armed and can be read again
 *
 *  Returned Value:
 *
 *    OK  or errno
 *
 *
 ****************************************************************************/
int hardfault_write(char *caller, int fd, int format, bool rearm);

/****************************************************************************
 * Name: hardfault_rearm
 *
 * Description:
 *      Will move the file to the Armed state
 *
 *
 * Inputs:
 *   - caller:  A label to display in syslog output
 *
 *  Returned Value:
 *
 *    OK  or errno
 *
 *
 ****************************************************************************/
int hardfault_rearm(char *caller);

/****************************************************************************
 * Name: hardfault_increment_reboot
 *
 * Description:
 *      Will increment the reboot counter. The reboot counter will help
 *      detect reboot loops.
 *
 *
 * Inputs:
 *   - caller:  A label to display in syslog output
 *   - reset :  when set will reset the reboot counter to 0.
 *
 *  Returned Value:
 *
 *    The current value of the reboot counter (post increment).
 *
 *
 ****************************************************************************/
int hardfault_increment_reboot(char *caller, bool reset);

#if defined(__cplusplus)
extern "C"
//}
#endif