/** ************************************************************************** * @file trackers.h * @brief Заголочный файл для работы с трекерами @ref TRACKERS. ************************************************************************** * @addtogroup TRACKERS Trackers defines * @ingroup MYLIBS_DEFINES * @brief Дефайны для работы с трекерами * @details Есть дефайн для объявления структуры трекера: TrackerTypeDef(num_user_vars). Структура состоит из следующих элементов: - cnt_ok - cnt_err - cnt_warn - user[num_user_vars] Также есть ряд функций (дефайнов) для обращения к элементам этой структуры. Если трекеры @ref TRACKERS_ENABLE отключены, то все дефайны определяются как ничего и на производительность кода не влияют @par Пример: Определяем typedef трекера измерений Measure_TrackerTypeDef @verbatim typedef TrackerTypeDef(MEASURE_USER_VARS_NUMB) Measure_TrackerTypeDef; @endverbatim И через @ref Measure_TrackerTypeDef структура подключается в другие структуры Для работы с структурой можно использовать функции: - Для получения значения: - TrackerGet_Ok() - TrackerGet_Err() - TrackerGet_Warn() - TrackerGet_User(n) - Для записи значения: - TrackerCnt_Ok() - TrackerCnt_Err() - TrackerCnt_Warn() - TrackerCnt_User() - TrackerWrite_User(n) - Для очищения значения: - TrackerClear_All() - TrackerClear_Ok() - TrackerClear_Err() - TrackerClear_Warn() - TrackerClear_User(n) - TrackerClear_UserAll() * @{ *************************************************************************/ #ifndef __TRACKERS_H_ #define __TRACKERS_H_ #include "mylibs_defs.h" #ifdef TRACKERS_ENABLE /** * @brief Структура для счетчиков отладки * @param num_user_vars - количество пользовательских переменных * @details Содержит счетчик для успешных событый (cnt_ok), * счетчик для ошибок (cnt_err), счетчик для предупреждений (cnt_warn). * * Также есть возможность объявить пользовательские переменные в * количестве штук. */ #define TrackerTypeDef(num_user_vars) \ struct \ { \ uint32_t cnt_ok; \ uint32_t cnt_err; \ uint32_t cnt_warn; \ uint32_t user[num_user_vars]; \ } /** @brief Получить количетство пользовательских переменных */ #define num_of_usercnts(_user_) (sizeof(_user_) / sizeof(uint32_t)) /** @brief Проверка существует ли указанная пользовательская переменная */ #define assert_usertracker(_cntstruct_, _uservarnumb_) ((_uservarnumb_) < num_of_usercnts((_cntstruct_).user)) /** @brief Условие для проверки существует ли указанная пользовательская переменная */ #define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(assert_usertracker(_cntstruct_, _uservarnumb_)) /** @brief Тернарный оператор для проверки существует ли указанная пользовательская переменная */ #define tern_assert_usertracker(_cntstruct_, _uservarnumb_) (assert_usertracker(_cntstruct_, _uservarnumb_)) ? _uservarnumb_ : 0 /** @brief Считать счетчик успешных событий */ #define TrackerGet_Ok(_cntstruct_) (_cntstruct_).cnt_ok /** @brief Считать счетчик ошибок */ #define TrackerGet_Err(_cntstruct_) (_cntstruct_).cnt_err /** @brief Считать счетчик предупреждений */ #define TrackerGet_Warn(_cntstruct_) (_cntstruct_).cnt_warn /** * @brief Считать пользовательскую переменную * @note Здесь нет проверки - существует ли пользовательская переменная! * Есть возможность выйти за границы структуры!!! * Чтобы этого избежать можно использовать дефайн #ref assert_usertracker() @verbatim if(assert_usertracker(struct, 0)) { TrackerGet_User(struct, 0) } @endverbatim */ #define TrackerGet_User(_cntstruct_, _uservarnumb_) (_cntstruct_).user[tern_assert_usertracker(_cntstruct_, _uservarnumb_)] /** @brief Инкрементирование счетчика успешных событий */ #define TrackerCnt_Ok(_cntstruct_) (_cntstruct_).cnt_ok++ /** @brief Инкрементирование счетчика ошибок */ #define TrackerCnt_Err(_cntstruct_) (_cntstruct_).cnt_err++ /** @brief Инкрементирование счетчика предупреждений */ #define TrackerCnt_Warn(_cntstruct_) (_cntstruct_).cnt_warn++ /** @brief Инкрементирование пользовательской переменной */ #define TrackerCnt_User(_cntstruct_, _uservarnumb_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_]++; /** @brief Запись числа в пользовательскую переменную */ #define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_] = (_val_) /** @brief Очистка всей структуры */ #define TrackerClear_All(_cntstruct_) memset(&(_cntstruct_), 0, sizeof(_cntstruct_)) /** @brief Очистка счетчика успешных событий */ #define TrackerClear_Ok(_cntstruct_) (_cntstruct_).cnt_ok = 0 /** @brief Очистка счетчика ошибок */ #define TrackerClear_Err(_cntstruct_) (_cntstruct_).cnt_err = 0 /** @brief Очистка счетчика предупреждений */ #define TrackerClear_Warn(_cntstruct_) (_cntstruct_).cnt_warn = 0 /** @brief Очистка пользовательской переменной */ #define TrackerClear_User(_cntstruct_, _uservarnumb_) if_assert_usertracker(_cntstruct_, _uservarnumb_) (_cntstruct_).user[_uservarnumb_] = 0; /** @brief Очистка всех пользовательских переменных */ #define TrackerClear_UserAll(_cntstruct_) memset(&(_cntstruct_).user, 0, sizeof((_cntstruct_).user)) #else //TRACKERS_ENABLE #define TrackerTypeDef(num_user_vars) void * #define num_of_usercnts(_user_) #define assert_tracecnt(_cntstruct_, _uservarnumb_) #define TrackerCnt_Ok(_cntstruct_) #define TrackerCnt_Err(_cntstruct_) #define TrackerCnt_Warn(_cntstruct_) #define TrackerCnt_User(_cntstruct_, _uservarnumb_) #define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_) /** @brief Очистка всей структуры */ #define TrackerClear_All(_cntstruct_) #define TrackerClear_Ok(_cntstruct_) #define TrackerClear_Err(_cntstruct_) #define TrackerClear_Warn(_cntstruct_) #define TrackerClear_User(_cntstruct_) #define TrackerClear_UserAll(_cntstruct_) #endif //TRACKERS_ENABLE #endif //__TRACKERS_H_