MyLibs 1.0
Расширенные библиотеки для STM32
Loading...
Searching...
No Matches
trace.h
Go to the documentation of this file.
1/**
2**************************************************************************
3* @file trace.h
4* @brief Заголочный файл для работы с трассировкой.
5**************************************************************************
6* @addtogroup TRACE Trace defines
7* @ingroup MYLIBS_DEFINES
8* @brief Дефайны для работы с трассировкой
9*************************************************************************/
10#ifndef __TRACE_H_
11#define __TRACE_H_
12#include "mylibs_defs.h"
13
14#include <string.h>
15/**
16 * @addtogroup TRACE_SERIAL Serial trace defines
17 * @ingroup TRACE
18 * @brief Дефайны для работы с serial трассировкой (SWO, RTT)
19 * @details В зависимости от настроек определяется дефайн @ref my_printf() и @ref log_printf() для работы с трассировкой:
20 - @ref SERIAL_TRACE_ENABLE - Если трассировка отключена, то все дефайны определяются как 'ничего'
21 и на производительность кода не влияют
22
23 - @ref RTT_TRACE_ENABLE - для RTT это будет вызов функции SEGGER_RTT_printf(), с подключением библиотеки SEGGER_RTT.h
24 Предварительно надо подключить библиотеку SEGGER RTT и вызвать функцию SEGGER_RTT_Init()
25
26 - @ref SWO_TRACE_ENABLE для SWO это будет просто printf()
27
28 Но библиотеку STDOUT надо подключить самостоятельно:
29
30 @verbatim
31 Manage Run-Time Environment -> Compiler -> I/O -> STDOUT
32 @endverbatim
33
34 Для SWO также надо включить трассировку:
35
36 @verbatim
37 Options For Target -> Debug -> Debugger Settings
38 @endverbatim
39
40 В вкладке Debug:
41 - Port = SW
42 В вкладке Trace:
43 - Указать Core Clock
44 - Выставить Trace Port = SWO
45 - ITM - выбрать нужный порт (для Keil нулевой порт)
46
47
48 * @{
49 *
50 * @def my_printf(...)
51 * @brief Универсальный макрос для вывода трассировки
52 * @details Варианты реализации:
53 * - RTT_TRACE_ENABLE `SEGGER_RTT_printf(0, ...)`
54 * - SWO_TRACE_ENABLE - `printf(...)`
55 * - NO_TRACE - пустой макрос
56 *
57 * @def log_printf(TAG, fmt, ...)
58 * @brief Макрос логирования с поддержкой уровней LOG_LEVEL
59 * @param TAG Тэг лога
60 * @param fmt, ... Форматируемая строка
61 * @details Варианты реализации:
62 * - LOG_LEVEL == 0 - логирование отключено (макрос пустой)
63 * - LOG_LEVEL == 1 - выводится время и TAG
64 * - LOG_LEVEL >= 2 - выводится время, TAG, имя файла и номер строки
65 */
66#ifdef SERIAL_TRACE_ENABLE
67
68 #if defined(RTT_TRACE_ENABLE)
69 #undef SWO_TRACE_ENABLE
70 #include "SEGGER_RTT.h"
71 #define my_printf(...) SEGGER_RTT_printf(0, __VA_ARGS__)
72 #elif defined(SWO_TRACE_ENABLE)
73 #undef RTT_TRACE_ENABLE
74 #define my_printf(...) printf(__VA_ARGS__)
75 #else // NO_TRACE
76 #define my_printf(...)
77 #warning No trace is selected. Serial debug wont work.
78 #endif // RTT_TRACE_ENABLE/SWO_TRACE_ENABLE/NO_TRACE
79#else //SERIAL_TRACE_ENABLE
80
81 #define my_printf(...)
82 #undef RTT_TRACE_ENABLE
83 #undef SWO_TRACE_ENABLE
84
85#endif //SERIAL_TRACE_ENABLE
86
87
88#ifndef LOG_LEVEL
89#define LOG_LEVEL 1 ///< @brief Уровень логирования (по умолчанию == 1)
90#endif
91
92#if LOG_LEVEL == 0 // лог отключен
93 #define \
94log_printf(TAG, fmt, ...)
95#elif LOG_LEVEL == 1 // только тэг
96 #define log_printf(TAG, fmt, ...) \
97my_printf("\n[%lu] [%s] " fmt, \
98(unsigned long)uwTick, TAG, ##__VA_ARGS__)
99#elif LOG_LEVEL >= 2 // всё
100 #define log_printf(TAG, fmt, ...) \
101my_printf("\n[%lu] [%s] (%s:%d) " fmt, \
102(unsigned long)uwTick, TAG, __FILE__, __LINE__, ##__VA_ARGS__)
103#endif
104
105/** TRACE_SERIAL
106 * @}
107 */
108
109/**
110 * @addtogroup TRACE_GPIO GPIO trace defines
111 * @ingroup TRACE
112 * @brief Дефайны для работы с GPIO трассировкой
113 * @details Определяется дефайны для работы с GPIO трассировкой:
114 - TRACE_GPIO_RESET() - для сброса ножки GPIO (через BSRR)
115 - TRACE_GPIO_SET() - для выставления ножки GPIO (через BSRR)
116
117 - Если трассировка @ref GPIO_TRACE_ENABLE отключена, то все дефайны определяются как 'ничего'
118 и на производительность кода не влияют
119 * @{
120 *
121 * @def TRACE_GPIO_RESET(_gpio_, _pin_)
122 * @brief Сбросить указанную ножку GPIO
123 * @param _gpio_ Указатель на структуру GPIO (напр. GPIOA)
124 * @param _pin_ Номер ножки (напр. GPIO_PIN_0)
125 * @details Варианты реализации:
126 * - GPIO_TRACE_ENABLE не определён - макрос пустой
127 * - GPIO_TRACE_ENABLE определён - устанавливает бит сброса через BSRR ((_pin_)<<16)
128 *
129 * @def TRACE_GPIO_SET(_gpio_, _pin_)
130 * @brief Установить указанную ножку GPIO
131 * @param _gpio_ Указатель на структуру GPIO (например GPIOA)
132 * @param _pin_ Номер ножки (напр. GPIO_PIN_0)
133 * @details Варианты реализации:
134 * - GPIO_TRACE_ENABLE не определён - макрос пустой
135 * - GPIO_TRACE_ENABLE определён - устанавливает бит установки через BSRR (_pin_)
136 */
137#ifndef GPIO_TRACE_ENABLE
138 #define TRACE_GPIO_SET(_gpio_,_pin_)
139 #define TRACE_GPIO_RESET(_gpio_,_pin_)
140#else
141 #define TRACE_GPIO_SET(_gpio_,_pin_) (_gpio_)->BSRR = (((_pin_)))
142 #define TRACE_GPIO_RESET(_gpio_,_pin_) (_gpio_)->BSRR = ((_pin_)<<16)
143#endif //GPIO_TRACE_ENABLE
144
145
146/** TRACE_GPIO
147 * @}
148 */
149
150
151
152#if defined(HAL_MODULE_ENABLED) && defined(RTT_TRACE_ENABLE)
153
154/**
155 * @addtogroup TRACE_RTT_FLASH Flash RTT Buffer
156 * @ingroup TRACE
157 * @brief Макросы и функции для сохранения/чтения RTT буфера в Flash
158 * @details Модуль позволяет сохранять данные RTT буфера во Flash и читать их обратно по тегам.
159 * Теги работают следующим образом:
160 * - Базовый тег (младший байт = 0): модуль сам выбирает первый свободный слот во Flash;
161 * новые записи получают автоинкрементированный младший байт тега (от 0x00 до 0xFF).
162 * - Конкретный тег (младший байт != 0): запись или чтение происходит строго с указанным тегом;
163 * если слот с таким тегом уже занят, запись не выполняется.
164 * - Автоинкремент позволяет хранить несколько последовательных записей в пределах одного базового тега,
165 * без необходимости вручную отслеживать адреса Flash или позиции буферов.
166 *
167 * Параметры:
168 * - @ref RTT_FLASH_BUFFER_SIZE - Размер буфера RTT в Flash
169 * - @ref RTT_FLASH_SECTOR - Сектор FLASH куда положится RTT буфер
170 * - @ref RTT_FLASH_SECTOR_START - Начало сектора RTT_FLASH_SECTOR
171 * - @ref RTT_FLASH_SECTOR_END - Конец сектора RTT_FLASH_SECTOR
172 *
173 * @{
174 */
175
176
177/**
178 * @brief Структура RTT, которая будет положена в Flash
179 */
180typedef struct {
181 uint32_t tag; ///< Уникальный идентификатор буфера
182 uint32_t size; ///< Размер данных
183 char data[RTT_FLASH_BUFFER_SIZE]; ///< Буфер RTT
185
186/**
187 * @brief Подготовка Flash к записи
188 * @details Сбрасывает ошибки Flash и ожидает готовности перед записью
189 */
190__STATIC_FORCEINLINE void RTT_FlashPrepare(void)
191{
192 HAL_FLASH_Unlock();
193 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR | FLASH_FLAG_WRPERR | FLASH_FLAG_OPERR);
194 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {
195 __NOP();
196 }
197}
198
199/**
200 * @brief Сохраняет последние символы RTT-буфера в Flash по тегу
201 * @param tag Базовый или конкретный идентификатор буфера.
202 * @param tail_size Количество последних символов RTT для копирования
203 * @param buf_num Указатель на переменную в которую запишется номер буфера для конкретного тега
204 * @return >=0 — номер буфера (тег) для записи, <0 — ошибка (нет места, тег уже занят, ошибка записи в флеш)
205 *
206 * @details Автоматически копирует последние tail_size символов из RTT-буфера
207 * и записывает их во Flash.
208 * Тег может быть базовым или конкретным:
209 * - Если базовый (младший байт == 0) — будет выбран первый свободный слот с автоинкрементом.
210 * Автоинкремент формируется в пределах от 0x1 до 0xFF
211 * - Если конкретный (младший байт != 0) — запись выполняется только с этим тегом, иначе ошибка.
212 *
213 */
214__STATIC_FORCEINLINE int RTT_SaveToFlash(uint32_t tag, uint32_t tail_size)
215{
216 if (tag == 0xFFFFFFFF)
217 return -1; // Неверный тег
218
219 SEGGER_RTT_BUFFER_UP *up = &_SEGGER_RTT.aUp[0];
220 unsigned buf_size = up->SizeOfBuffer;
221 unsigned wr = up->WrOff;
222
223 // Ограничиваем по размеру буфера RTT и RTT_FLASH_BUFFER_SIZE
224 unsigned n = (tail_size > buf_size) ? buf_size : tail_size;
225 if (n > RTT_FLASH_BUFFER_SIZE)
227
228 uint32_t addr = RTT_FLASH_SECTOR_START;
229 RTT_FlashHeader_t *flash_hdr = NULL;
230 uint32_t base_tag = tag & 0xFFFFFF00;
231 uint32_t next_tag = (tag & 0xFF) == 0 ? tag + 1 : tag;
232
233 // Ищем первый свободный слот, параллельно автоинкрементируем тег
234 while ((addr + sizeof(RTT_FlashHeader_t)) <= RTT_FLASH_SECTOR_END)
235 {
236 flash_hdr = (RTT_FlashHeader_t *)addr;
237
238 if (flash_hdr->tag == 0xFFFFFFFF)
239 break; // Нашли свободное место
240
241
242 if((flash_hdr->tag & 0xFFFFFF00) == base_tag) // выбраный тег
243 {
244 if ((tag & 0xFF) == 0) // если он базовый - ищем последний
245 next_tag = flash_hdr->tag + 1; // автоинкремент
246 else
247 if(flash_hdr->tag == tag) // если он конкретный и уже существует - то ошибка
248 return -1; // конкретный тег уже занят
249 }
250
251
252 if(next_tag - tag > 0xFF)
253 return -1; // автоинкремент слишком большой
254
255 addr += sizeof(RTT_FlashHeader_t);
256 }
257
258 if ((addr + sizeof(RTT_FlashHeader_t)) > RTT_FLASH_SECTOR_END)
259 return -1; // Нет свободного места
260
261 // Копируем последние n символов из RTT
262 char temp[RTT_FLASH_BUFFER_SIZE];
263 unsigned valid_count = 0;
264
265 for (unsigned i = 0; i < n; i++)
266 {
267 unsigned idx = (wr + buf_size - n + i) % buf_size;
268 char c = up->pBuffer[idx];
269 if (c != 0)
270 temp[valid_count++] = c;
271 }
272
274
275 // Формируем структуру в RAM
276 RTT_FlashHeader_t flash_data;
277 flash_data.tag = next_tag;
278 flash_data.size = valid_count;
279 memcpy(flash_data.data, temp, valid_count);
280
281 // Записываем структуру во Flash (по 4 байта)
282 const uint32_t *p = (const uint32_t *)&flash_data;
283 for (unsigned i = 0; i < sizeof(RTT_FlashHeader_t) / 4; i++)
284 {
285 if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + i * 4, p[i]) != HAL_OK)
286 return -1;
287 }
288
289 HAL_FLASH_Lock();
290 __DSB();
291 __ISB();
292
293
294 return (int)(next_tag&0xFF);
295}
296
297
298/**
299 * @brief Читает последние символы RTT-буфера из Flash по тегу
300 * @param tag Базовый или конкретный идентификатор буфера.
301 * @param Buffer Буфер назначения для копирования данных
302 * @param tail_size Количество последних символов, которые нужно прочитать
303 * @param read_size Количество считанных символов
304 * @return >=0 — номер буфера (тег) для записи, <0 — ошибка (тег не найден или структура повреждена)
305 *
306 * @details Копирует последние tail_size символов из найденной записи Flash в Buffer.
307 * Тег может быть базовым или конкретным:
308 * - Если базовый (младший байт == 0) — будет прочитана последняя запись из группы.
309 * - Если конкретный (младший байт != 0) — прочитывается именно эта запись.
310 */
311__STATIC_FORCEINLINE int RTT_ReadFromFlash(uint32_t tag, char *Buffer, uint32_t tail_size, uint32_t *read_size)
312{
313 if (!Buffer || tail_size == 0)
314 return -1; // Неверные параметры
315
316 if (tag == 0xFFFFFFFF)
317 return -1; // Недопустимый тег
318
319 uint32_t addr = RTT_FLASH_SECTOR_START;
320 RTT_FlashHeader_t *flash_hdr = NULL;
321 RTT_FlashHeader_t *target_hdr = NULL;
322 uint32_t base_tag = tag & 0xFFFFFF00;
323
324 // Поиск записи по тегу
325 while ((addr + sizeof(RTT_FlashHeader_t)) <= RTT_FLASH_SECTOR_END)
326 {
327 flash_hdr = (RTT_FlashHeader_t *)addr;
328
329 if (flash_hdr->tag == 0xFFFFFFFF)
330 break; // Достигнут конец записанных структур
331
332 // выбраный тег
333 if((flash_hdr->tag & 0xFFFFFF00) == base_tag)
334 {
335 if ((tag & 0xFF) == 0) // если он базовый - ищем последний
336 target_hdr = flash_hdr; // сохраняем последний в группе
337 else
338 if(flash_hdr->tag == tag) // если он конкретный и найден - берем его
339 {
340 target_hdr = flash_hdr;
341 break; // конкретный тег найден
342 }
343 }
344
345 addr += sizeof(RTT_FlashHeader_t);
346 }
347
348 if (!target_hdr) return -1; // Тег не найден
349
350 // Проверка корректности размера
351 if (target_hdr->size > RTT_FLASH_BUFFER_SIZE)
352 return -1; // Повреждённая запись
353
354 // Определяем количество читаемых символов
355 uint32_t n = (tail_size > target_hdr->size) ? target_hdr->size : tail_size;
356 // Начальная позиция для чтения последних tail_size символов
357 uint32_t start = target_hdr->size - n;
358 // Копируем данные из Flash в RAM
359 memcpy(Buffer, &target_hdr->data[start], n);
360
361 if(read_size != NULL)
362 {
363 *read_size = n;
364 }
365
366 __DSB();
367 __ISB();
368
369 return (int)(target_hdr->tag & 0xFF);
370}
371
372/**
373 * @brief Стирание сектора Flash с RTT-буфером
374 */
375__STATIC_FORCEINLINE int RTT_EraseFlash(void)
376{
377 FLASH_EraseInitTypeDef eraseInit;
378 uint32_t pageError = 0;
379
381
382 eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
383 eraseInit.Sector = RTT_FLASH_SECTOR;
384 eraseInit.NbSectors = 1;
385
386 if (HAL_FLASHEx_Erase(&eraseInit, &pageError) != HAL_OK)
387 {
388 return -1;
389 }
390 return 0;
391 HAL_FLASH_Lock();
392}
393
394/** TRACE_RTT_FLASH
395 * @}
396 */
397
398#else // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
399#define RTT_FlashPrepare(...)
400#define RTT_EraseFlash(...) 0
401#define RTT_SaveToFlash(...) 0
402#define RTT_ReadFromFlash(...) 0
403#endif // HAL_MODULE_ENABLED && RTT_TRACE_ENABLE
404
405
406
407
408/**
409 * @addtogroup TRACE_HARDFAULT Hardfault trace defines
410 * @ingroup TRACE
411 * @brief Модуль трассировки HardFault с возможностью сохранения RTT буфера во Flash
412 * @details
413 * Этот модуль позволяет сохранять контекст процессора и последние символы RTT буфера при возникновении HardFault.
414 *
415 * Механизм работы:
416 * - При срабатывании HardFault вызывается HF_HandleFault(), который:
417 * 1. Получает указатель на стек, где произошёл HardFault (MSP или PSP).
418 * 2. Выводит значения регистров R0-R3, R12, LR, PC, PSR и системных регистров SCB.
419 * 3. Формирует строку с регистрами и копирует последние символы RTT буфера.
420 * 4. Сохраняет данные во Flash с базовым тегом HF_RTT_TAG_BASE.
421 * - Для восстановления последнего HardFault используется HF_CheckRecovered(), который:
422 * 1. Читает запись во Flash по базовому тегу.
423 * 2. Выводит сохранённый RTT буфер и контекст регистров.
424 * 3. Опционально стирает Flash после восстановления.
425 *
426 * Параметры:
427 * - @ref HARDFAULT_SERIAL_TRACE - Включить обработку и serial трассировку Hardfault
428 * Если отключена то вставляются заглушки, никак не влияющие на параметры и остальную программу
429 * - @ref HF_RTT_TAG_BASE - Базовый тег RTT Flash для HardFault
430 * - @ref HF_RTT_TAIL_SIZE - Размер буфера RTT, который сохранится при Hardfault
431 * - @ref HF_STACK_DUMP_WORDS - Сколько слов стека будет проанализировано во время Hardfault
432 * - @ref HF_FLASH_ADDR - Адрес FLASH куда положится RTT буфер
433 * - @ref HF_RAM_END - Конец RAM памяти (чтобы во время анализа стека не выйти за пределы)
434 *
435 @code
436 void Hardfault()
437 {
438 HF_HandleFault();
439 NVIC_SystemReset();
440 }
441
442 int main()
443 {
444 if(HF_CheckRecovered(0))
445 {
446 //set hardfault error
447 RTT_EraseFlash(); // erase rtt flash after message readed
448 }
449 }
450 @endcode
451 * @{
452 */
453#if defined(HAL_MODULE_ENABLED) && defined(HARDFAULT_SERIAL_TRACE)
454
455#ifndef HF_RTT_TAIL_SIZE
456#define HF_RTT_TAIL_SIZE RTT_FLASH_BUFFER_SIZE ///< Размер буфера RTT, который сохранится при Hardfault
457#endif
458
459/**
460 * @brief Контекст стек-фрейма процессора при HardFault
461 * @details Сохраняет регистры R0-R3, R12, LR, PC, PSR для последующего анализа.
462 */
463typedef struct {
464 uint32_t r0; ///< Регистр R0
465 uint32_t r1; ///< Регистр R1
466 uint32_t r2; ///< Регистр R2
467 uint32_t r3; ///< Регистр R3
468 uint32_t r12; ///< Регистр R12
469 uint32_t lr; ///< Link Register
470 uint32_t pc; ///< Program Counter
471 uint32_t psr; ///< Program Status Register
473
474/**
475 * @brief Проверка и вывод последнего HardFault-трейса из Flash
476 * @details
477 * Функция ищет последнюю запись HardFault по базовому тегу HF_RTT_TAG_BASE
478 * и выводит её содержимое в консоль. После успешного вывода Flash можно опционально очистить.
479 *
480 * @return int
481 * - 1 — данные HardFault найдены и выведены
482 * - 0 — данные отсутствуют или тег не найден
483 *
484 * @note Вызов рекомендуется при инициализации приложения для анализа предыдущего сбоя.
485 */
486__STATIC_FORCEINLINE int HF_CheckRecovered(int erase)
487{
488 char buffer[RTT_FLASH_BUFFER_SIZE];
489 uint32_t read_size = 0;
490 int n_hardfault = RTT_ReadFromFlash(HF_RTT_TAG_BASE, buffer, HF_RTT_TAIL_SIZE, &read_size);
491 if (n_hardfault > 0)
492 {
493 my_printf("\n--- Recovered HardFault RTT buffer #%u ---\n", n_hardfault);
494 for (int i = 0; i < read_size; i++)
495 {
496 char c = buffer[i];
497 if (c == 0 || c == (char)0xFF) break;
498 my_printf("%c", c);
499 }
500
501 if(erase)
503 my_printf("\n--------- HardFault Dump End ---------\n");
504 return 1;
505 }
506 return 0;
507}
508
509
510static HF_StackFrame_t *stack_frame;
511static uint32_t stack_dump[HF_STACK_DUMP_WORDS];
512static void *ret_adr[10] = {0};
513/**
514 * @brief Обработчик HardFault
515 * @details
516 * Вызывается из прерывания HardFault или в любом месте где понятно что ошибка критическая.
517 * Последовательно выполняет:
518 * 1. Определяет активный стек (MSP или PSP) на момент сбоя.
519 * 2. Сохраняет значения регистров R0-R3, R12, LR, PC, PSR.
520 * 3. Выводит системные регистры CFSR, HFSR, DFSR, AFSR, MMFAR, BFAR.
521 * 4. Формирует stack trace с 3 уровнями возврата.
522 * 5. Копирует последние символы RTT буфера.
523 * 6. Сохраняет все данные во Flash через RTT_SaveToFlash с базовым тегом HF_RTT_TAG_BASE.
524 *
525 * @note Функция защищена, так как вызывается в контексте сбоя — минимизирует использование вызовов HAL.
526 */
527__STATIC_FORCEINLINE void HF_HandleFault(void)
528{
529 // Получаем указатель на стек, где произошёл HardFault
530 __ASM volatile(
531 "TST lr, #4 \n"
532 "ITE EQ \n"
533 "MRSEQ %[ptr], MSP\n"
534 "MRSNE %[ptr], PSP\n"
535 : [ptr] "=r"(stack_frame)
536 );
537
538 my_printf("\n===== HardFault occurred! =====\n");
539 my_printf("R0 = 0x%08X\n", stack_frame->r0);
540 my_printf("R1 = 0x%08X\n", stack_frame->r1);
541 my_printf("R2 = 0x%08X\n", stack_frame->r2);
542 my_printf("R3 = 0x%08X\n", stack_frame->r3);
543 my_printf("R12 = 0x%08X\n", stack_frame->r12);
544 my_printf("LR = 0x%08X\n", stack_frame->lr);
545 my_printf("PC = 0x%08X\n", stack_frame->pc);
546 my_printf("PSR = 0x%08X\n", stack_frame->psr);
547
548 my_printf("CFSR = 0x%08X\n", SCB->CFSR);
549 my_printf("HFSR = 0x%08X\n", SCB->HFSR);
550 my_printf("DFSR = 0x%08X\n", SCB->DFSR);
551 my_printf("AFSR = 0x%08X\n", SCB->AFSR);
552 my_printf("MMFAR = 0x%08X\n", SCB->MMFAR);
553 my_printf("BFAR = 0x%08X\n", SCB->BFAR);
554
555 // --- Stack trace ---
556 my_printf("--- Stack trace ---\n");
557 ret_adr[0] = __builtin_return_address(0);
558 ret_adr[1] = __builtin_return_address(1);
559 ret_adr[2] = __builtin_return_address(2);
560
561 for (int i = 0; i < 3; i++) // развернуть n уровней
562 {
563 if(ret_adr[i])
564 my_printf(" #%d: 0x%08lX\r\n", i, ret_adr[i]); // -1 для Thumb
565 }
567}
568#else // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
569#define HF_CheckRecovered(...) 0
570#define HF_HandleFault(...)
571#endif // HAL_MODULE_ENABLED && HARDFAULT_SERIAL_TRACE
572/** TRACE_HARDFAULT
573 * @}
574 */
575
576
577
578#endif //__TRACE_H_
#define RTT_FLASH_SECTOR
Сектор FLASH куда положится RTT буфер
#define RTT_FLASH_BUFFER_SIZE
Размер буфера RTT в Flash.
#define RTT_FLASH_SECTOR_START
Начало сектора RTT_FLASH_SECTOR.
#define HF_STACK_DUMP_WORDS
Сколько слов стека будет проанализировано во время Hardfault.
#define HF_RTT_TAG_BASE
базовый тег для HardFault
#define HF_RTT_TAIL_SIZE
Размер буфера RTT, который сохранится при Hardfault.
#define RTT_FLASH_SECTOR_END
Конец сектора RTT_FLASH_SECTOR.
__STATIC_FORCEINLINE int HF_CheckRecovered(int erase)
Проверка и вывод последнего HardFault-трейса из Flash.
Definition trace.h:486
__STATIC_FORCEINLINE void HF_HandleFault(void)
Обработчик HardFault.
Definition trace.h:527
__STATIC_FORCEINLINE void RTT_FlashPrepare(void)
Подготовка Flash к записи
Definition trace.h:190
__STATIC_FORCEINLINE int RTT_ReadFromFlash(uint32_t tag, char *Buffer, uint32_t tail_size, uint32_t *read_size)
Читает последние символы RTT-буфера из Flash по тегу
Definition trace.h:311
__STATIC_FORCEINLINE int RTT_SaveToFlash(uint32_t tag, uint32_t tail_size)
Сохраняет последние символы RTT-буфера в Flash по тегу
Definition trace.h:214
__STATIC_FORCEINLINE int RTT_EraseFlash(void)
Стирание сектора Flash с RTT-буфером
Definition trace.h:375
#define my_printf(...)
Универсальный макрос для вывода трассировки
Definition trace.h:71
Заголочный файл для дефайнов библиотеки MyLibsGeneral.
Контекст стек-фрейма процессора при HardFault.
Definition trace.h:463
uint32_t pc
Program Counter.
Definition trace.h:470
uint32_t r1
Регистр R1.
Definition trace.h:465
uint32_t r0
Регистр R0.
Definition trace.h:464
uint32_t r3
Регистр R3.
Definition trace.h:467
uint32_t r2
Регистр R2.
Definition trace.h:466
uint32_t lr
Link Register.
Definition trace.h:469
uint32_t r12
Регистр R12.
Definition trace.h:468
uint32_t psr
Program Status Register.
Definition trace.h:471
Структура RTT, которая будет положена в Flash.
Definition trace.h:180
uint32_t tag
Уникальный идентификатор буфера
Definition trace.h:181
char data[1024]
Буфер RTT.
Definition trace.h:183
uint32_t size
Размер данных
Definition trace.h:182