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