ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
4 мая
1401297
il-2 (08.02.2024 12:07, просмотров: 1625)
Где-то была тема про ведение отладочных логов. Я вот для себя сваял макросы. Очень удобно получилось. Делюсь: 

#define _C_LOG_RECORD(name, rec_p, ...) do { uint16_t i = name##_top; \

if ( rec_p != NULL ) memcpy(&name[i], rec_p, sizeof(name[0])); \

if ( ++i >= (sizeof(name)/sizeof(name[0]) ) i = 0; \

name##_top = i; } while(0)

#define _C_LOG_TOP_NAME(name, ...) name##_top


/** @brief Declare logging variables - array and top index */

#define C_LOG_DECL(name, type, element_cnt) uint16_t name##_top; type name[element_cnt]


/** @brief Get top record pointer */

#define C_LOG_REC_P(name) (&name[_C_LOG_TOP_NAME(name, 0)])


/** @brief Record log: C_LOG_RECORD(name) - shift top index, C_LOG_RECORD(name, rec_p) - record data from rec_p and shift top index */

#define C_LOG_RECORD(...) _C_LOG_RECORD(__VA_ARGS__, NULL, 0)


/** @brief Record triggered log (top index != 0 condition) */

#define C_LOG_TRIGGER(...) if ( _C_LOG_TOP_NAME(__VA_ARGS__, 0) ) _C_LOG_RECORD(__VA_ARGS__, NULL, 0)


// Usage example


typedef struct _log_t { uint8_t event, param; } log_t;

C_LOG_DECL(event_log, log_t, 100);


void t function1(uint8_t event, uint8_t param)

{

log_t *log_ptr = C_LOG_REC_P(event_log);

log_ptr->event = event;

log_ptr->param = param;

C_LOG_RECORD(event_log);

...

}


void function2(uint8_t event, uint8_t param)

{

log_t log_record;

log_record.event = event;

log_record.param = param;

C_LOG_TRIGGER(event_log, &log_record);

...

}


Для записи лога есть 2 макроса - C_LOG_RECORD и C_LOG_TRIGGER. Первый просто делает запись в голову лога и сдвигает указатель, второй - делает запись только если указатель != 0 (т.е. если уже были записи в лог).

Так-же оба макроса можно использовать 2 способами:

- получить указатель на голову лога (C_LOG_REC_P), заполнить все поля и затем передвинуть указатель (C_LOG_RECORD / C_LOG_TRIGGER с 1-м параметром)

- завести внешнюю переменную, заполнить ее и потом записать в лог (C_LOG_RECORD / C_LOG_TRIGGER с 2-мя параметрами)