diff --git a/CMakeLists.txt b/CMakeLists.txt index d056835..5372c52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,4 +73,6 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() +include(${CMAKE_DIR}/full_firmware_info.cmake) + add_subdirectory(${ROOT_DIR}/Src/platform/${APP_PLATFORM}) diff --git a/Src/applications/dronecan/CMakeLists.txt b/Src/applications/dronecan/CMakeLists.txt index 26a4145..8b279db 100644 --- a/Src/applications/dronecan/CMakeLists.txt +++ b/Src/applications/dronecan/CMakeLists.txt @@ -8,6 +8,7 @@ cmake_path(GET APPLICATIONS_DIR PARENT_PATH SRC_DIR) add_definitions(-DCONFIG_USE_DRONECAN=1) include(${SRC_DIR}/modules/dronecan/core/CMakeLists.txt) +include(${SRC_DIR}/modules/system/CMakeLists.txt) include(${SRC_DIR}/modules/dronecan/arming/CMakeLists.txt) include(${SRC_DIR}/modules/circuit_status/dronecan/CMakeLists.txt) include(${SRC_DIR}/modules/dronecan/feedback/CMakeLists.txt) diff --git a/Src/modules/system/CMakeLists.txt b/Src/modules/system/CMakeLists.txt new file mode 100644 index 0000000..3ba9199 --- /dev/null +++ b/Src/modules/system/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2023 Dmitry Ponomarev +# Distributed under the terms of the GPL v3 license, available in the file LICENSE. + + +list(APPEND APPLICATION_HEADERS + ${CMAKE_CURRENT_LIST_DIR} +) + +list(APPEND APPLICATION_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/main.cpp +) + +list(APPEND LIBPARAMS_PARAMS + ${CMAKE_CURRENT_LIST_DIR}/params.yaml +) diff --git a/Src/modules/system/main.cpp b/Src/modules/system/main.cpp new file mode 100644 index 0000000..f068470 --- /dev/null +++ b/Src/modules/system/main.cpp @@ -0,0 +1,35 @@ +/** + * This program is free software under the GNU General Public License v3. + * See for details. + * Author: Dmitry Ponomarev + */ + +#include "modules/system/main.hpp" +#include +#include "can_driver.h" +#include "common/algorithms.hpp" +#include "params.hpp" +#include "logger.hpp" + +static Logger logger = Logger("SYS"); + +REGISTER_MODULE(SystemModule) + +void SystemModule::init() { + health = Status::OK; + need_notification = paramsGetIntegerValue(IntParamsIndexes::PARAM_LOG_LEVEL) <= 1; + mode = Module::Mode::STANDBY; +} + +void SystemModule::spin_once() { + if (!need_notification || HAL_GetTick() < 1000) { + return; + } + + need_notification = false; + + // Maximum expected firmware full info size + constexpr size_t max_full_info_size = sizeof("Node v99.99.99_BADCOFFE RelWithDebInfo CLANG 999.999.999"); + static_assert(sizeof(FIRMWARE_FULL_INFO) < max_full_info_size); + logger.log_info(FIRMWARE_FULL_INFO); +} diff --git a/Src/modules/system/main.hpp b/Src/modules/system/main.hpp new file mode 100644 index 0000000..4fd6a5f --- /dev/null +++ b/Src/modules/system/main.hpp @@ -0,0 +1,30 @@ +/** + * This program is free software under the GNU General Public License v3. + * See for details. + * Author: Dmitry Ponomarev + */ + +#ifndef SRC_MODULES_SYSTEM_HPP_ +#define SRC_MODULES_SYSTEM_HPP_ + +#include "module.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +class SystemModule : public Module { +public: + SystemModule() : Module(2, Protocol::DRONECAN) {} + void init() override; + +protected: + void spin_once() override; + bool need_notification{false}; +}; + +#ifdef __cplusplus +} +#endif + +#endif // SRC_MODULES_SYSTEM_HPP_ diff --git a/Src/modules/system/params.yaml b/Src/modules/system/params.yaml new file mode 100644 index 0000000..81787a0 --- /dev/null +++ b/Src/modules/system/params.yaml @@ -0,0 +1,15 @@ +system.log_level: + type: Integer + note: + "Log level. See [debug.LogLevel](https://dronecan.github.io/Specification/7._List_of_standard_data_types/#loglevel) and [diagnostic.Severity](https://github.com/OpenCyphal/public_regulated_data_types/blob/master/uavcan/diagnostic/Severity.1.0.dsdl). +
0 - Log everything (DEBUG, INFO, WARNING, ERROR) +
1 - Log at least INFO level +
2 - Log at least WARNING level +
3 - Log at least ERROR level +
4 - Disable logging +
By default 3 to show only realy important messages." + enum: PARAM_LOG_LEVEL + flags: mutable + default: 3 + min: 0 + max: 4 diff --git a/cmake/full_firmware_info.cmake b/cmake/full_firmware_info.cmake new file mode 100644 index 0000000..902e306 --- /dev/null +++ b/cmake/full_firmware_info.cmake @@ -0,0 +1,8 @@ +# Copyright (C) 2023-2024 Dmitry Ponomarev +# Distributed under the terms of the GPL v3 license, available in the file LICENSE. + +if(NOT CMAKE_CXX_COMPILER_ID) + message(FATAL_ERROR "C++ compiler not set yet") +endif() +set(TOOLCHAIN_INFO "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") +add_definitions(-DFIRMWARE_FULL_INFO="Node v${APP_VERSION_MAJOR}.${APP_VERSION_MINOR}.${APP_VERSION_PATCH}_${GIT_HASH_SHORT_8_DIGITS} ${CMAKE_BUILD_TYPE} ${TOOLCHAIN_INFO}") diff --git a/cmake/git.cmake b/cmake/git.cmake index 353bf74..44065da 100644 --- a/cmake/git.cmake +++ b/cmake/git.cmake @@ -1,12 +1,25 @@ # Copyright (C) 2023-2024 Dmitry Ponomarev # Distributed under the terms of the GPL v3 license, available in the file LICENSE. +# Function to ensure a variable is within the range of 0 to 99 +function(check_version_component component_name component_value) + if(NOT ("${component_value}" MATCHES "^[0-9]+$")) + message(FATAL_ERROR "${component_name} must be an integer.") + endif() + + if(${component_value} GREATER 99 OR ${component_value} LESS 0) + message(FATAL_ERROR "${component_name} must be between 0 and 99. Current value: ${component_value}") + endif() +endfunction() + execute_process( COMMAND git rev-parse --short=16 HEAD COMMAND_ERROR_IS_FATAL ANY - OUTPUT_VARIABLE GIT_HASH_SHORT + OUTPUT_VARIABLE GIT_HASH_SHORT_16_DIGITS OUTPUT_STRIP_TRAILING_WHITESPACE ) +string(SUBSTRING "${GIT_HASH_SHORT_16_DIGITS}" 0 8 GIT_HASH_SHORT_8_DIGITS) + execute_process( COMMAND rl-git-info --major COMMAND_ERROR_IS_FATAL ANY @@ -19,8 +32,21 @@ execute_process( OUTPUT_VARIABLE APP_VERSION_MINOR OUTPUT_STRIP_TRAILING_WHITESPACE ) +execute_process( + COMMAND rl-git-info --patch + COMMAND_ERROR_IS_FATAL ANY + OUTPUT_VARIABLE APP_VERSION_PATCH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Check each version component +check_version_component("APP_VERSION_MAJOR" ${APP_VERSION_MAJOR}) +check_version_component("APP_VERSION_MINOR" ${APP_VERSION_MINOR}) +check_version_component("APP_VERSION_PATCH" ${APP_VERSION_PATCH}) + add_definitions(-DAPP_VERSION_MAJOR=${APP_VERSION_MAJOR}) add_definitions(-DAPP_VERSION_MINOR=${APP_VERSION_MINOR}) +add_definitions(-DAPP_VERSION_PATCH=${APP_VERSION_PATCH}) -set(GIT_HASH "0x${GIT_HASH_SHORT}") +set(GIT_HASH "0x${GIT_HASH_SHORT_16_DIGITS}") add_definitions(-DGIT_HASH=${GIT_HASH})