75#ifdef SERIAL_TRACE_ENABLE
77 #if defined(RTT_TRACE_ENABLE)
78 #undef SWO_TRACE_ENABLE
79 #include "SEGGER_RTT.h"
80 #define my_printf(...) SEGGER_RTT_printf(0, __VA_ARGS__)
81 #elif defined(SWO_TRACE_ENABLE)
82 #undef RTT_TRACE_ENABLE
83 #define my_printf(...) printf(__VA_ARGS__)
85 #define my_printf(...)
86 #warning No trace is selected. Serial debug wont work.
90 #define my_printf(...)
91 #undef RTT_TRACE_ENABLE
92 #undef SWO_TRACE_ENABLE
98#define local_time() HAL_GetTick()
107log_printf(TAG, fmt, ...)
109 #define log_printf(TAG, fmt, ...) \
110my_printf("\n[%lu] [%s] " fmt, \
111(unsigned long)local_time(), TAG, ##__VA_ARGS__)
113 #define log_printf(TAG, fmt, ...) \
114my_printf("\n[%lu] [%s] (%s:%d) " fmt, \
115(unsigned long)local_time(), TAG, __FILE__, __LINE__, ##__VA_ARGS__)
150#ifndef GPIO_TRACE_ENABLE
151 #define TRACE_GPIO_SET(_gpio_,_pin_)
152 #define TRACE_GPIO_RESET(_gpio_,_pin_)
154 #define TRACE_GPIO_SET(_gpio_,_pin_) (_gpio_)->BSRR = (((_pin_)))
155 #define TRACE_GPIO_RESET(_gpio_,_pin_) (_gpio_)->BSRR = ((_pin_)<<16)
165#if defined(HAL_MODULE_ENABLED) && defined(RTT_TRACE_ENABLE)
206 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR | FLASH_FLAG_WRPERR | FLASH_FLAG_OPERR);
207 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {
229 if (tag == 0xFFFFFFFF)
232 SEGGER_RTT_BUFFER_UP *up = &_SEGGER_RTT.aUp[0];
233 unsigned buf_size = up->SizeOfBuffer;
234 unsigned wr = up->WrOff;
237 unsigned n = (tail_size > buf_size) ? buf_size : tail_size;
243 uint32_t base_tag = tag & 0xFFFFFF00;
244 uint32_t next_tag = (tag & 0xFF) == 0 ? tag + 1 : tag;
251 if (flash_hdr->
tag == 0xFFFFFFFF)
255 if((flash_hdr->
tag & 0xFFFFFF00) == base_tag)
257 if ((tag & 0xFF) == 0)
258 next_tag = flash_hdr->
tag + 1;
260 if(flash_hdr->
tag == tag)
265 if(next_tag - tag > 0xFF)
276 unsigned valid_count = 0;
278 for (
unsigned i = 0; i < n; i++)
280 unsigned idx = (wr + buf_size - n + i) % buf_size;
281 char c = up->pBuffer[idx];
283 temp[valid_count++] = c;
290 flash_data.
tag = next_tag;
291 flash_data.
size = valid_count;
292 memcpy(flash_data.
data, temp, valid_count);
295 const uint32_t *p = (
const uint32_t *)&flash_data;
298 if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + i * 4, p[i]) != HAL_OK)
307 return (
int)(next_tag&0xFF);
324__STATIC_FORCEINLINE
int RTT_ReadFromFlash(uint32_t tag,
char *Buffer, uint32_t tail_size, uint32_t *read_size)
326 if (!Buffer || tail_size == 0)
329 if (tag == 0xFFFFFFFF)
335 uint32_t base_tag = tag & 0xFFFFFF00;
342 if (flash_hdr->
tag == 0xFFFFFFFF)
346 if((flash_hdr->
tag & 0xFFFFFF00) == base_tag)
348 if ((tag & 0xFF) == 0)
349 target_hdr = flash_hdr;
351 if(flash_hdr->
tag == tag)
353 target_hdr = flash_hdr;
361 if (!target_hdr)
return -1;
368 uint32_t n = (tail_size > target_hdr->
size) ? target_hdr->
size : tail_size;
370 uint32_t start = target_hdr->
size - n;
372 memcpy(Buffer, &target_hdr->
data[start], n);
374 if(read_size != NULL)
382 return (
int)(target_hdr->
tag & 0xFF);
390 FLASH_EraseInitTypeDef eraseInit;
391 uint32_t pageError = 0;
395 eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
397 eraseInit.NbSectors = 1;
399 if (HAL_FLASHEx_Erase(&eraseInit, &pageError) != HAL_OK)
412#define RTT_FlashPrepare(...)
413#define RTT_EraseFlash(...) 0
414#define RTT_SaveToFlash(...) 0
415#define RTT_ReadFromFlash(...) 0
466#if defined(HAL_MODULE_ENABLED) && defined(HARDFAULT_SERIAL_TRACE)
468#ifndef HF_RTT_TAIL_SIZE
469#define HF_RTT_TAIL_SIZE RTT_FLASH_BUFFER_SIZE
502 uint32_t read_size = 0;
506 my_printf(
"\n--- Recovered HardFault RTT buffer #%u ---\n", n_hardfault);
507 for (
int i = 0; i < read_size; i++)
510 if (c == 0 || c == (
char)0xFF)
break;
516 my_printf(
"\n--------- HardFault Dump End ---------\n");
525static void *ret_adr[10] = {0};
546 "MRSEQ %[ptr], MSP\n"
547 "MRSNE %[ptr], PSP\n"
548 : [ptr]
"=r"(stack_frame)
551 my_printf(
"\n===== HardFault occurred! =====\n");
552 my_printf(
"R0 = 0x%08X\n", stack_frame->r0);
553 my_printf(
"R1 = 0x%08X\n", stack_frame->r1);
554 my_printf(
"R2 = 0x%08X\n", stack_frame->r2);
555 my_printf(
"R3 = 0x%08X\n", stack_frame->r3);
556 my_printf(
"R12 = 0x%08X\n", stack_frame->r12);
557 my_printf(
"LR = 0x%08X\n", stack_frame->lr);
558 my_printf(
"PC = 0x%08X\n", stack_frame->pc);
559 my_printf(
"PSR = 0x%08X\n", stack_frame->psr);
565 my_printf(
"MMFAR = 0x%08X\n", SCB->MMFAR);
570 ret_adr[0] = __builtin_return_address(0);
571 ret_adr[1] = __builtin_return_address(1);
572 ret_adr[2] = __builtin_return_address(2);
574 for (
int i = 0; i < 3; i++)
577 my_printf(
" #%d: 0x%08lX\r\n", i, ret_adr[i]);
582#define HF_CheckRecovered(...) 0
583#define HF_HandleFault(...)
#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.
__STATIC_FORCEINLINE void HF_HandleFault(void)
Обработчик HardFault.
__STATIC_FORCEINLINE void RTT_FlashPrepare(void)
Подготовка Flash к записи
__STATIC_FORCEINLINE int RTT_ReadFromFlash(uint32_t tag, char *Buffer, uint32_t tail_size, uint32_t *read_size)
Читает последние символы RTT-буфера из Flash по тегу
__STATIC_FORCEINLINE int RTT_SaveToFlash(uint32_t tag, uint32_t tail_size)
Сохраняет последние символы RTT-буфера в Flash по тегу
__STATIC_FORCEINLINE int RTT_EraseFlash(void)
Стирание сектора Flash с RTT-буфером
#define my_printf(...)
Универсальный макрос для вывода трассировки
Заголочный файл для дефайнов библиотеки MyLibsGeneral.
Контекст стек-фрейма процессора при HardFault.
uint32_t pc
Program Counter.
uint32_t lr
Link Register.
uint32_t psr
Program Status Register.