From a0d13f08c11ab9b7a011580e1356f65205a66855 Mon Sep 17 00:00:00 2001 From: Matthias Mitscherlich Date: Mon, 11 Mar 2024 15:45:48 +0100 Subject: [PATCH] Started with a blank main file - Added GPIO handling - Added a logger class with additional static debug log handling Tested, functional --- code/main/CMakeLists.txt | 9 +- code/main/FunctionStatus.h | 78 +++++++++++ code/main/hal/inc/ISerialBus.h | 103 ++++++++++++++ code/main/hal/inc/gpio.h | 122 ++++++++++++++++ code/main/hal/inc/uart.h | 91 ++++++++++++ code/main/hal/src/gpio.cpp | 127 +++++++++++++++++ code/main/hal/src/uart.cpp | 90 ++++++++++++ code/main/main.cpp | 49 ++++++- code/main/platform/inc/logger.h | 178 ++++++++++++++++++++++++ code/main/platform/src/logger.cpp | 224 ++++++++++++++++++++++++++++++ 10 files changed, 1067 insertions(+), 4 deletions(-) create mode 100644 code/main/FunctionStatus.h create mode 100644 code/main/hal/inc/ISerialBus.h create mode 100644 code/main/hal/inc/gpio.h create mode 100644 code/main/hal/inc/uart.h create mode 100644 code/main/hal/src/gpio.cpp create mode 100644 code/main/hal/src/uart.cpp create mode 100644 code/main/platform/inc/logger.h create mode 100644 code/main/platform/src/logger.cpp diff --git a/code/main/CMakeLists.txt b/code/main/CMakeLists.txt index c335d36..8a0818b 100644 --- a/code/main/CMakeLists.txt +++ b/code/main/CMakeLists.txt @@ -5,7 +5,10 @@ idf_component_register( SRCS # list the source files of this component "main.cpp" # "old/src/bmp280.cpp" -# "old/src/gpio.cpp" + "hal/src/gpio.cpp" + "hal/src/uart.cpp" + + "platform/src/logger.cpp" # "old/src/i2c.cpp" # "old/src/wifi.cpp" # "old/src/logger.cpp" @@ -18,6 +21,8 @@ idf_component_register( # "old/src/temperaturewordmap.cpp" # "old/src/temperature.cpp" INCLUDE_DIRS # optional, add here public include directories + "./" + "hal/inc" "platform/inc" "application/inc" PRIV_INCLUDE_DIRS # optional, add here private include directories @@ -25,4 +30,4 @@ idf_component_register( PRIV_REQUIRES # optional, list the private requirements ) -component_compile_definitions("ESP_LWIP_COMPONENT_BUILD" "RELEASE=\"0.1\"") +component_compile_definitions("ESP_LWIP_COMPONENT_BUILD" "MAJORRELEASE=0" "MINORRELEASE=1") diff --git a/code/main/FunctionStatus.h b/code/main/FunctionStatus.h new file mode 100644 index 0000000..174ff36 --- /dev/null +++ b/code/main/FunctionStatus.h @@ -0,0 +1,78 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file FunctionStatus.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_FUNCTIONSTATUS_H_ +#define MAIN_FUNCTIONSTATUS_H_ + +/** + * FunctionStatus implementation + * \addtogroup Global + * + * The FunctionStatus enumeration is the global function status representation. The values defined here shall + * be used throughout the whole project. + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + +/** + * \enum FunctionStatus + * @{ + */ + +typedef enum +{ + FUNCTION_STATUS_OK = 0, //!< The function execution was successful + FUNCTION_STATUS_ERROR = 1, //!< The function execution caused an unspecified error + FUNCTION_STATUS_NOT_INITIALIZED = 2, //!< The function execution was aborted because the module + //!< instance is not initialized + FUNCTION_STATUS_ALREADY_INITIALIZED = 3, //!< The function execution was aborted because the module + //!< instance is already initialized + FUNCTION_STATUS_UNDEFINED_VALUE = 4, //!< The function failed because an undefined value was used + //!< This most probably happened when checking an enum + // Interfaces/Busses + FUNCTION_STATUS_NOT_OPEN = 10, //!< The Interface cannot be used because it has not been opened + FUNCTION_STATUS_ALREADY_OPEN = 11, //!< The interface cannot be opened because it is already open + FUNCTION_STATUS_ALREADY_CLOSE = 12, //!< The interface cannot be closed because it is already closed + +} FunctionStatus; + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +/** @} */ + + +#endif /* MAIN_FUNCTIONSTATUS_H_ */ diff --git a/code/main/hal/inc/ISerialBus.h b/code/main/hal/inc/ISerialBus.h new file mode 100644 index 0000000..61fa7ae --- /dev/null +++ b/code/main/hal/inc/ISerialBus.h @@ -0,0 +1,103 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file ISerialBus.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_HAL_INC_ISERIALBUS_H_ +#define MAIN_HAL_INC_ISERIALBUS_H_ + +/** + * ISerialBus implementation + * \defgroup ISerialBus + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly +#include + + +// ProjectIncludes +// All include files that are provided by the project +#include "FunctionStatus.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + +template +class ISerialBus +{ + // ----------------------------------------------------------------------------------------------------------------- + // Public Section + // ----------------------------------------------------------------------------------------------------------------- + public: + // Virtual Class Destructor (required for absolute virtual classes) + virtual ~ISerialBus() {} + + FunctionStatus open() {status = OPEN; return FUNCTION_STATUS_OK;} + + FunctionStatus close() {status = CLOSED; return FUNCTION_STATUS_OK;} + + virtual FunctionStatus read(T* buffer, uint32_t length, uint32_t* actualLength) = 0; + + virtual FunctionStatus write(T* buffer, uint32_t length) = 0; + + + + // ----------------------------------------------------------------------------------------------------------------- + // Protected Section + // ----------------------------------------------------------------------------------------------------------------- + protected: + + typedef enum + { + CLOSED = 0, + OPEN + } Status_t; + + // The current open/close status of the interface + Status_t status; + + // ----------------------------------------------------------------------------------------------------------------- + // Private Section + // ----------------------------------------------------------------------------------------------------------------- + private: + +}; + +/** @} */ + + +#endif /* MAIN_HAL_INC_ISERIALBUS_H_ */ diff --git a/code/main/hal/inc/gpio.h b/code/main/hal/inc/gpio.h new file mode 100644 index 0000000..9e4c334 --- /dev/null +++ b/code/main/hal/inc/gpio.h @@ -0,0 +1,122 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file gpio.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_HAL_INC_GPIO_H_ +#define MAIN_HAL_INC_GPIO_H_ + +/** + * gpio implementation + * \defgroup gpio + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly +#include +#include + + + +// ProjectIncludes +// All include files that are provided by the project +#include "FunctionStatus.h" //!< Include to use the generic function status enumeration type + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + +class gpio +{ + // ----------------------------------------------------------------------------------------------------------------- + // Public Section + // ----------------------------------------------------------------------------------------------------------------- + public: + + typedef enum + { + GPIO_DIRECTION_INPUT = 0, + GPIO_DIRECTION_OUTPUT = 1 + } Direction_t; + + typedef enum + { + GPIO_VALUE_LOW = 0, + GPIO_VALUE_HIGH = 1 + } Value_t; + + /** ------------------------------------------------------------------------------------------------------------- + * GPIO + * \brief Constructs a new instance of GPIO + * + * + * @param number The IO instance given in as its unique GPIO number + * @param direction Direction of the GPIO. + * Default value: @arg GPIO_DIRECTION_INPUT + * @arg GPIO_DIRECTION_INPUT for incoming signal + * @arg GPIO_DIRECTION_OUTPUT for outgoing signal + * @param initialValue The initial value for this GPIO. For outputs the given value will be + * applied immediately after initialization. For inputs this value is only + * initial and is not the real representation of the input. + * Default value: @arg GPIO_VALUE_LOW + * @arg GPIO_VALUE_LOW the signal at the GPIO is equal to GND + * @arg GPIO_VALUE_HIGH the signal at the GPIO is equal to VCC + * -------------------------------------------------------------------------------------------------------------- + */ + gpio(uint32_t number, Direction_t direction = GPIO_DIRECTION_INPUT, Value_t initialValue = GPIO_VALUE_LOW); + + FunctionStatus set(Value_t value); + FunctionStatus get(Value_t* const value); + FunctionStatus toogle(); + + // ----------------------------------------------------------------------------------------------------------------- + // Protected Section + // ----------------------------------------------------------------------------------------------------------------- + protected: + uint32_t number; + Direction_t direction; + Value_t currentState; + + // ----------------------------------------------------------------------------------------------------------------- + // Private Section + // ----------------------------------------------------------------------------------------------------------------- + private: + +}; + +/** @} */ + + +#endif /* MAIN_HAL_INC_GPIO_H_ */ diff --git a/code/main/hal/inc/uart.h b/code/main/hal/inc/uart.h new file mode 100644 index 0000000..54088de --- /dev/null +++ b/code/main/hal/inc/uart.h @@ -0,0 +1,91 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file uart.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_HAL_INC_UART_H_ +#define MAIN_HAL_INC_UART_H_ + +/** + * uart implementation + * \defgroup uart + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly +#include + + +// ProjectIncludes +// All include files that are provided by the project +#include "ISerialBus.h" +#include "driver/uart.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + +class uart : public ISerialBus +{ + // ----------------------------------------------------------------------------------------------------------------- + // Public Section + // ----------------------------------------------------------------------------------------------------------------- + public: + // Class Constructor + uart(uart_port_t* uartPort); + ~uart(); + + FunctionStatus read(uint8_t* buffer, uint32_t length, uint32_t* actualLength); + + FunctionStatus write(uint8_t* buffer, uint32_t length); + + // ----------------------------------------------------------------------------------------------------------------- + // Protected Section + // ----------------------------------------------------------------------------------------------------------------- + protected: + + + // ----------------------------------------------------------------------------------------------------------------- + // Private Section + // ----------------------------------------------------------------------------------------------------------------- + private: + uart_port_t* port; + +}; + +/** @} */ + + +#endif /* MAIN_HAL_INC_UART_H_ */ diff --git a/code/main/hal/src/gpio.cpp b/code/main/hal/src/gpio.cpp new file mode 100644 index 0000000..56e57bf --- /dev/null +++ b/code/main/hal/src/gpio.cpp @@ -0,0 +1,127 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file gpio.c +/// \brief Description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +#include +#include "driver/gpio.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// File-scope variables +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function definitions +// -------------------------------------------------------------------------------------------------------------------- + + +gpio::gpio(uint32_t number, Direction_t direction, Value_t initialValue) +{ + this->number = number; + this->direction = direction; + + //zero-initialize the config structure. + gpio_config_t io_conf = {}; + //disable interrupt + io_conf.intr_type = GPIO_INTR_DISABLE; + //set as output mode + io_conf.mode = (this->direction == GPIO_DIRECTION_OUTPUT) ? GPIO_MODE_OUTPUT : GPIO_MODE_INPUT; + //bit mask of the pins that you want to set + io_conf.pin_bit_mask = (1ULL << this->number); + //disable pull-down mode + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + //disable pull-up mode + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + //configure GPIO with the given settings + ESP_ERROR_CHECK(gpio_config(&io_conf)); + + this->currentState = GPIO_VALUE_LOW; + + set(initialValue); + +} + + +FunctionStatus gpio::set(Value_t value) +{ + FunctionStatus returnValue = FUNCTION_STATUS_ERROR; + + if (this->direction == GPIO_DIRECTION_OUTPUT) + { + ESP_ERROR_CHECK(gpio_set_level((gpio_num_t)this->number, (uint32_t)value)); + this->currentState = value; + returnValue = FUNCTION_STATUS_OK; + } + + return returnValue; +} + + +FunctionStatus gpio::get(Value_t* value) +{ + FunctionStatus returnValue = FUNCTION_STATUS_OK; + + if (gpio_get_level((gpio_num_t)this->number)) + { + this->currentState = GPIO_VALUE_HIGH; + } + else + { + this->currentState = GPIO_VALUE_LOW; + } + + *value = this->currentState; + + return returnValue; +} + + +FunctionStatus gpio::toogle() +{ + FunctionStatus returnValue = FUNCTION_STATUS_ERROR; + + if (this->currentState == GPIO_VALUE_LOW) + { + // Going to HIGH + set(GPIO_VALUE_HIGH); + } + else + { + // Going to LOW + set(GPIO_VALUE_LOW); + } + + return returnValue; +} diff --git a/code/main/hal/src/uart.cpp b/code/main/hal/src/uart.cpp new file mode 100644 index 0000000..b7faa55 --- /dev/null +++ b/code/main/hal/src/uart.cpp @@ -0,0 +1,90 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file uart.cpp +/// \brief Description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +#include "uart.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// File-scope variables +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function definitions +// -------------------------------------------------------------------------------------------------------------------- + + +uart::uart(uart_port_t* uartPort) +{ + this->port = uartPort; + this->status = CLOSED; +} + +uart::~uart() +{ + +} + +FunctionStatus uart::write(uint8_t* buffer, uint32_t length) +{ + FunctionStatus returnValue = FUNCTION_STATUS_OK; + + if (status == OPEN) + { + uart_write_bytes(*this->port, (const void*)buffer, length); + } + else + { + returnValue = FUNCTION_STATUS_NOT_OPEN; + } + + return returnValue; +} + +FunctionStatus uart::read(uint8_t* buffer, uint32_t length, uint32_t* actualLength) +{ + FunctionStatus returnValue = FUNCTION_STATUS_OK; + + if (status == OPEN) + { + // Do Stuff + } + else + { + returnValue = FUNCTION_STATUS_NOT_OPEN; + } + + return returnValue; +} diff --git a/code/main/main.cpp b/code/main/main.cpp index 08e5d60..aacf0a3 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -17,9 +17,22 @@ // Include files // -------------------------------------------------------------------------------------------------------------------- +#include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" +// ESP includes +#include "driver/uart.h" +#include "esp_log.h" +#include "nvs_flash.h" + +// HAL includes +#include "gpio.h" +#include "uart.h" + +// Platform includes +#include "logger.h" // -------------------------------------------------------------------------------------------------------------------- // Constant and macro definitions // -------------------------------------------------------------------------------------------------------------------- @@ -34,13 +47,14 @@ // File-scope variables // -------------------------------------------------------------------------------------------------------------------- +static uart_port_t uartPort = UART_NUM_0; - +static TaskHandle_t loggerTaskHandle; // -------------------------------------------------------------------------------------------------------------------- // Function declarations // -------------------------------------------------------------------------------------------------------------------- - +void loggerTask(void* parameters); // -------------------------------------------------------------------------------------------------------------------- // Function definitions @@ -76,6 +90,26 @@ extern "C" void app_main(void) ESP_ERROR_CHECK(uart_set_pin(uartPort, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(uart_driver_install(uartPort, 1024, 1024, 0, NULL, 0)); + uart uartDebug = uart(&uartPort); + uartDebug.open(); + + // ----------------------------------------------------------------------------------------------------------------- + // System-wide Debug Logger + + logger debugLogger = logger(16, uartDebug); + // Call the logger executable within a dedicated task and forget about it afterwards + xTaskCreate(loggerTask, (const char*)"loggerTask", 3072, &debugLogger, 3, &loggerTaskHandle); + + LOGGER_PRINT("\n\r-----------------------------------------------------------------------\n\r"); + LOGGER_PRINT("System Start\n\r"); + LOGGER_PRINT("\n\r"); + LOGGER_PRINT("WordClock\n\r"); + LOGGER_PRINT("Release: %d.%d \n\r", MAJORRELEASE, MINORRELEASE); + LOGGER_PRINT("Compiled on %s at %s\n\r\n\r\n\r", __DATE__, __TIME__); + + gpio debugIO = gpio(2, gpio::Direction_t::GPIO_DIRECTION_OUTPUT, gpio::Value_t::GPIO_VALUE_LOW); + + while(1) @@ -84,3 +118,14 @@ extern "C" void app_main(void) } } + + +void loggerTask(void* parameters) +{ + logger* debugLogger = (logger*) parameters; + while (1) + { + debugLogger->task(); + vTaskDelay(10); + } +} diff --git a/code/main/platform/inc/logger.h b/code/main/platform/inc/logger.h new file mode 100644 index 0000000..5616374 --- /dev/null +++ b/code/main/platform/inc/logger.h @@ -0,0 +1,178 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file logger.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_PLATFORM_INC_LOGGER_H_ +#define MAIN_PLATFORM_INC_LOGGER_H_ + +/** + * logger implementation + * \defgroup logger + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly +#include +#include +#include +#include + + +// ProjectIncludes +// All include files that are provided by the project +#include + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + +#define ENABLE_SERIAL_LOGGING + + +#if defined(ENABLE_SERIAL_LOGGING) +#define LOGGER_LOG(severity,...) \ + debugLogger.log(__FILE__, __func__, __LINE__, severity, ##__VA_ARGS__) +#else +#define LOGGER_LOG(severity, message) +#endif + +/** + * Logs an print message + * \memberof Logger + */ +#define LOGGER_PRINT(...) LOGGER_LOG(logger::LogType::LOGTYPE_PRINT, ##__VA_ARGS__) + +/** + * Logs an debug message + * \memberof Logger + */ +#define LOGGER_DEBUG(...) LOGGER_LOG(logger::LogType::LOGTYPE_DEBUG, ##__VA_ARGS__) + +/** + * Logs an info message + * \memberof Logger + */ +#define LOGGER_INFO(...) LOGGER_LOG(logger::LogType::LOGTYPE_INFO, ##__VA_ARGS__) + +/** + * Logs an warning message + * \memberof Logger + */ +#define LOGGER_WARNING(...) LOGGER_LOG(logger::LogType::LOGTYPE_WARNING, ##__VA_ARGS__) + +/** + * Logs an success message + * \memberof Logger + */ +#define LOGGER_SUCCESS(...) LOGGER_LOG(logger::LogType::LOGTYPE_SUCCESS, ##__VA_ARGS__) + +/** + * Logs an error message + * \memberof Logger + */ +#define LOGGER_ERROR(...) LOGGER_LOG(logger::LogType::LOGTYPE_ERROR, ##__VA_ARGS__) + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + +class logger; +extern logger debugLogger; + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + +class logger +{ + // ----------------------------------------------------------------------------------------------------------------- + // Public Section + // ----------------------------------------------------------------------------------------------------------------- + public: + + typedef enum + { + LOGTYPE_PRINT, /**< Raw print */ + LOGTYPE_DEBUG, /**< Debug information only; will not be stored on SD-card */ + LOGTYPE_INFO, /**< Informational messages of important events */ + LOGTYPE_WARNING, /**< Recoverable fault */ + LOGTYPE_SUCCESS, /**< A specific success message */ + LOGTYPE_ERROR /**< Unrecoverable fault */ + } LogType; + + // Class Constructor + logger(uint32_t queuesize, ISerialBus& serialPort); + + FunctionStatus log(const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* format, ...); + + // The Logger task - should be called by the system scheduler regularly + void task(); + + // ----------------------------------------------------------------------------------------------------------------- + // Protected Section + // ----------------------------------------------------------------------------------------------------------------- + protected: + + + // ----------------------------------------------------------------------------------------------------------------- + // Private Section + // ----------------------------------------------------------------------------------------------------------------- + private: + struct LogQueueItem + { + std::string fileName; + std::string functionName; + std::string context; + uint32_t lineNumber; + LogType logType; + }; + + struct typeParameters + { + LogType logType; + std::string vt100Prefix; + std::string logPrefix; + std::string vt100Postfix; + }; + + void composeTypeParameterList(void); + + void composeLogQueueItem(struct LogQueueItem* logQueueItem, std::string fileName, std::string functionName, + int lineNumber, LogType logType, std::string context); + + std::list typeParameterList; + + std::list queue; + ISerialBus& port; + uint32_t queuesize; + uint32_t numberOfLostMessages; + +}; + +/** @} */ + + +#endif /* MAIN_PLATFORM_INC_LOGGER_H_ */ diff --git a/code/main/platform/src/logger.cpp b/code/main/platform/src/logger.cpp new file mode 100644 index 0000000..2c353f5 --- /dev/null +++ b/code/main/platform/src/logger.cpp @@ -0,0 +1,224 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file logger.cpp +/// \brief Description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +#include + +#include +#include +#include + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// File-scope variables +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function definitions +// -------------------------------------------------------------------------------------------------------------------- + + +logger::logger(uint32_t queuesize, ISerialBus& serialPort) : port {serialPort}, queuesize {queuesize} +{ + numberOfLostMessages = 0; + // Compose the debug type level list + composeTypeParameterList(); +} + + +FunctionStatus logger::log(const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* format, ...) +{ + FunctionStatus returnValue = FUNCTION_STATUS_OK; + +#if defined(ENABLE_SERIAL_LOGGING) + bool overflowRecovery = false; + int nrOfMessages; + struct LogQueueItem logQueueItem; + va_list ap; + + nrOfMessages = queue.size(); + + if((nrOfMessages == queuesize - 1) && !overflowRecovery) + { + // Queue almost full, only one entry left. Log a warning instead + composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, "Log queue overflow"); + queue.push_back(logQueueItem); + + overflowRecovery = true; + numberOfLostMessages = 1; + } + else if((nrOfMessages == 0) && overflowRecovery) + { + // Queue empty again after an overflow + char str[128]; + snprintf(str, sizeof(str) / sizeof(str[0]), "%d messages lost", (unsigned int)numberOfLostMessages); + composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, str); + queue.push_back(logQueueItem); + + overflowRecovery = false; + } + else if(!overflowRecovery) + { + // Normal behaviour, queue not full + char str[128]; + va_start(ap, format); + vsnprintf(str, sizeof(str) / sizeof(str[0]), format, ap); + va_end(ap); + + composeLogQueueItem(&logQueueItem, fileName, functionName, lineNumber, logType, str); + queue.push_back(logQueueItem); + } + else + { + // Count number of lost messages + ++numberOfLostMessages; + } +#endif + return returnValue; +} + + +void logger::composeTypeParameterList(void) +{ + typeParameterList.clear(); + // Add Debug information + typeParameterList.push_back({LOGTYPE_DEBUG, "\033[33m", "DBG", "\033[0m"}); + // Add Warning information + typeParameterList.push_back({LOGTYPE_WARNING, "\033[35m", "WRN", "\033[0m"}); + // Add Error information + typeParameterList.push_back({LOGTYPE_ERROR, "\033[31m", "ERR", "\033[0m"}); + // Add Success information + typeParameterList.push_back({LOGTYPE_SUCCESS, "\033[32m", "SCS", "\033[0m"}); + // Add Information information + typeParameterList.push_back({LOGTYPE_INFO, "\033[33m", "INF", "\033[0m"}); + // Add Print information + typeParameterList.push_back({LOGTYPE_PRINT, "", "DBG", "\033[0m"}); + +} + + +#if defined(ENABLE_SERIAL_LOGGING) +void logger::composeLogQueueItem(struct LogQueueItem* logQueueItem, std::string fileName, std::string functionName, + int lineNumber, LogType logType, std::string context) +{ + + logQueueItem->logType = logType; + logQueueItem->context = context; +// strncpy((char*)&(logQueueItem->context[0]), context, contextSize); +// logQueueItem->context[contextSize - 1] = '\0'; + + if(logType != LOGTYPE_PRINT) + { + int fileNameIndex = 0; + + // If filename starts with "src/", strip this part + if((fileName[0] == 's') && + (fileName[1] == 'r') && + (fileName[2] == 'c') && + (fileName[3] == '/')) + { + fileNameIndex = 4; + } + +// It is known that the strncpy use can potentially truncate the source string, meaning +// that the target string size is smaller then the original string +// This is not a problem in this particular case, so the compiler warning is disabled +// for this situation +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" + // All logtypes except LOGTYPE_PRINT need filename, functionname and linenumber. + logQueueItem->fileName = fileName; + logQueueItem->functionName = functionName; +// strncpy((char*)&(logQueueItem->fileName[0]), &fileName[fileNameIndex], fileNameSize); +// strncpy((char*)&(logQueueItem->functionName[0]), functionName, functionNameSize); +#pragma GCC diagnostic pop + logQueueItem->lineNumber = lineNumber; + + // Fix terminating null byte in strncpy in case string to be copied is too long +// logQueueItem->fileName[fileNameSize - 1] = '\0'; +// logQueueItem->functionName[functionNameSize - 1] = '\0'; + } +} +#endif + +void logger::task() +{ + struct LogQueueItem logQueueItem; + + // Check if there is anything in the queue + // If queue is empty, return to scheduler + if (queue.empty()) + { + return; + } + // Get the first log item from queue + logQueueItem = queue.front(); + // Remove the item from the queue + this->queue.pop_front(); + + + if(logQueueItem.logType == LOGTYPE_PRINT) + { + // Raw print + #if defined(ENABLE_SERIAL_LOGGING) + + port.write((uint8_t*)logQueueItem.context.c_str(), logQueueItem.context.length() + 1); + #endif + + } + else + { + unsigned int seconds = 0; + +#if defined(ENABLE_SERIAL_LOGGING) + // Formatted print + + // Find the correct Log level type + auto it = std::find_if(typeParameterList.begin(), typeParameterList.end(), [&logQueueItem](const struct typeParameters& obj) {return obj.logType == logQueueItem.logType;}); + + std::string outputString = it->vt100Prefix + " " + + it->vt100Prefix + " " + + std::to_string(seconds) + " " + + logQueueItem.fileName + " " + + logQueueItem.functionName + " " + + "(line " + std::to_string(logQueueItem.lineNumber) + "): " + + logQueueItem.context + " " + + it->vt100Postfix; + + port.write((uint8_t*)outputString.c_str(), outputString.length() + 1); +#endif + + } +}