diff --git a/.github/workflows/build-test-baremetal.yml b/.github/workflows/build-test-baremetal.yml index f1fd17c..bf8765e 100644 --- a/.github/workflows/build-test-baremetal.yml +++ b/.github/workflows/build-test-baremetal.yml @@ -21,6 +21,10 @@ jobs: DOCKER_IMAGE: kubasejdak/arm-none-eabi-gcc:13-24.04 - PRESET: freertos-armv7-m4-conan-gcc-release DOCKER_IMAGE: kubasejdak/arm-none-eabi-gcc:13-24.04 + - PRESET: freertos-armv7-m4-conan-clang-debug + DOCKER_IMAGE: kubasejdak/arm-none-eabi-clang:18-24.04 + - PRESET: freertos-armv7-m4-conan-clang-release + DOCKER_IMAGE: kubasejdak/arm-none-eabi-clang:18-24.04 steps: - uses: actions/checkout@v6 @@ -55,4 +59,4 @@ jobs: # - examples-stm32f4 steps: - name: Check all jobs - run: echo '${{ toJSON(needs.*.result) }}' | grep -qvE '"(failure|cancelled|skipped)"' + run: '! echo ''${{ toJSON(needs.*.result) }}'' | grep -qE ''"(failure|cancelled|skipped)"''' diff --git a/.github/workflows/build-test-linux.yml b/.github/workflows/build-test-linux.yml index 2aa8fd0..fa7cd3b 100644 --- a/.github/workflows/build-test-linux.yml +++ b/.github/workflows/build-test-linux.yml @@ -181,4 +181,4 @@ jobs: - sanitizers-x64 steps: - name: Check all jobs - run: echo '${{ toJSON(needs.*.result) }}' | grep -qvE '"(failure|cancelled|skipped)"' + run: '! echo ''${{ toJSON(needs.*.result) }}'' | grep -qE ''"(failure|cancelled|skipped)"''' diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index d5c3f09..71770f7 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -66,4 +66,4 @@ jobs: - generate-coverage-report steps: - name: Check all jobs - run: echo '${{ toJSON(needs.*.result) }}' | grep -qvE '"(failure|cancelled|skipped)"' + run: '! echo ''${{ toJSON(needs.*.result) }}'' | grep -qE ''"(failure|cancelled|skipped)"''' diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index d48d525..0fdcc59 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -32,6 +32,8 @@ jobs: include: - PRESET: linux-native-conan-clang-debug DOCKER_IMAGE: kubasejdak/clang:18-24.04 + - PRESET: freertos-armv7-m4-conan-clang-debug + DOCKER_IMAGE: kubasejdak/arm-none-eabi-clang:18-24.04 steps: - uses: actions/checkout@v6 @@ -47,4 +49,4 @@ jobs: - linting steps: - name: Check all jobs - run: echo '${{ toJSON(needs.*.result) }}' | grep -qvE '"(failure|cancelled|skipped)"' + run: '! echo ''${{ toJSON(needs.*.result) }}'' | grep -qE ''"(failure|cancelled|skipped)"''' diff --git a/CMakePresets.json b/CMakePresets.json index d7b6c43..1a1b813 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -116,6 +116,14 @@ { "name": "freertos-armv7-m4-conan-gcc-release", "inherits": ["freertos-armv7-m4-gcc", "release", "conan"] + }, + { + "name": "freertos-armv7-m4-conan-clang-debug", + "inherits": ["freertos-armv7-m4-clang", "debug", "conan"] + }, + { + "name": "freertos-armv7-m4-conan-clang-release", + "inherits": ["freertos-armv7-m4-clang", "release", "conan"] } ] } diff --git a/LICENSE b/LICENSE index 23095bb..8a71b69 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Kuba Sejdak () +Copyright (c) 2019 Kuba Sejdak (kuba.sejdak@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/cmake/modules/Findplatform.cmake b/cmake/modules/Findplatform.cmake index 972cdab..7372f62 100644 --- a/cmake/modules/Findplatform.cmake +++ b/cmake/modules/Findplatform.cmake @@ -1,7 +1,7 @@ include(FetchContent) FetchContent_Declare(platform GIT_REPOSITORY https://github.com/kubasejdak-org/platform.git - GIT_TAG db273b749620432ea33300cce10d2431fb1db1d4 + GIT_TAG f7e9d72017452973400fa02a442b6fc3335aebc3 SOURCE_SUBDIR lib ) diff --git a/cmake/presets/baremetal.json b/cmake/presets/baremetal.json index 09bbf4e..11c6a49 100644 --- a/cmake/presets/baremetal.json +++ b/cmake/presets/baremetal.json @@ -25,6 +25,14 @@ "cacheVariables": { "TOOLCHAIN": "arm-none-eabi-gcc" } + }, + { + "name": "freertos-armv7-m4-clang", + "hidden": true, + "inherits": "freertos-armv7-m4", + "cacheVariables": { + "TOOLCHAIN": "arm-none-eabi-clang" + } } ] } diff --git a/lib/osal/freertos/.clang-tidy b/lib/osal/freertos/.clang-tidy new file mode 100644 index 0000000..55e933e --- /dev/null +++ b/lib/osal/freertos/.clang-tidy @@ -0,0 +1,6 @@ +--- +InheritParentConfig: true +Checks: ' + -misc-include-cleaner +' +... diff --git a/lib/osal/freertos/Mutex.cpp b/lib/osal/freertos/Mutex.cpp index 51d37e0..2d012a7 100644 --- a/lib/osal/freertos/Mutex.cpp +++ b/lib/osal/freertos/Mutex.cpp @@ -38,6 +38,7 @@ #include #include +#include #include OsalError osalMutexCreate(OsalMutex* mutex, OsalMutexType type) diff --git a/lib/osal/freertos/Semaphore.cpp b/lib/osal/freertos/Semaphore.cpp index ba19526..350a57e 100644 --- a/lib/osal/freertos/Semaphore.cpp +++ b/lib/osal/freertos/Semaphore.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include diff --git a/lib/osal/freertos/Thread.cpp b/lib/osal/freertos/Thread.cpp index 4fc06a1..7daccc7 100644 --- a/lib/osal/freertos/Thread.cpp +++ b/lib/osal/freertos/Thread.cpp @@ -39,19 +39,24 @@ #include #include +#include #include #include +namespace { + /// Helper thread function which is used as a wrapper for OSAL thread function. /// @param arg Helper thread arguments. /// @note This function is used to implement thread joining. -static void threadWrapper(void* arg) +void threadWrapper(void* arg) { auto* params = static_cast(arg); params->func(params->arg); osalSemaphoreSignal(¶ms->semaphore); } +} // namespace + OsalError osalThreadCreate(OsalThread* thread, OsalThreadConfig config, OsalThreadFunction func, void* arg) { return osalThreadCreateEx(thread, config, func, arg, nullptr); @@ -132,7 +137,7 @@ OsalError osalThreadJoin(OsalThread* thread) return OsalError::InvalidArgument; auto error = osalSemaphoreWait(&thread->impl.params.semaphore); - if (error) + if (error != OsalError{}) return error; thread->joined = true; @@ -146,7 +151,7 @@ void osalThreadYield() uint32_t osalThreadId() { - return static_cast(reinterpret_cast(xTaskGetCurrentTaskHandle())); + return static_cast(std::bit_cast(xTaskGetCurrentTaskHandle())); } OsalError osalThreadName(char* name, size_t size) diff --git a/lib/osal/freertos/sleep.cpp b/lib/osal/freertos/sleep.cpp index c3fcf3f..6f906c4 100644 --- a/lib/osal/freertos/sleep.cpp +++ b/lib/osal/freertos/sleep.cpp @@ -35,6 +35,8 @@ #include #include +#include + void osalSleepMs(uint64_t cDurationMs) { vTaskDelay(cDurationMs / portTICK_PERIOD_MS); diff --git a/lib/osal/include/osal/Semaphore.h b/lib/osal/include/osal/Semaphore.h index 5b2ea94..d411870 100644 --- a/lib/osal/include/osal/Semaphore.h +++ b/lib/osal/include/osal/Semaphore.h @@ -35,7 +35,7 @@ extern "C" { #include "internal/SemaphoreImpl.h" #include "osal/Error.h" -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) +#include /// Represents OSAL semaphore handle. /// @note Size of this structure depends on the concrete implementation. In particular, SemaphoreImpl @@ -47,9 +47,9 @@ struct OsalSemaphore { /// Creates new semaphore with the given initial value. /// @param semaphore Semaphore handle to be initialized. -/// @param initialValue Initial value of the semaphore to be created. +/// @param initValue Initial value of the semaphore to be created. /// @return Error code of the operation. -OsalError osalSemaphoreCreate(OsalSemaphore* semaphore, unsigned int initialValue); +OsalError osalSemaphoreCreate(OsalSemaphore* semaphore, unsigned int initValue); /// Destroys semaphore represented by the given handle. /// @param semaphore Semaphore handle to be destroyed. diff --git a/lib/osal/include/osal/Thread.h b/lib/osal/include/osal/Thread.h index bee22fc..1f65383 100644 --- a/lib/osal/include/osal/Thread.h +++ b/lib/osal/include/osal/Thread.h @@ -35,8 +35,8 @@ extern "C" { #include "internal/ThreadImpl.h" #include "osal/Error.h" -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) +#include +#include /// Represents OSAL thread handle. /// @note Size of this structure depends on the concrete implementation. In particular, ThreadImpl diff --git a/lib/osal/include/osal/sleep.h b/lib/osal/include/osal/sleep.h index 493e560..d9bc28e 100644 --- a/lib/osal/include/osal/sleep.h +++ b/lib/osal/include/osal/sleep.h @@ -32,7 +32,7 @@ extern "C" { #endif -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) +#include /// Suspends the current thread for the specified amount of time in ms. /// @param cDurationMs Amount of time in ms for which current thread should be suspended. diff --git a/lib/osal/include/osal/time.h b/lib/osal/include/osal/time.h index 917b8e7..dcaaad9 100644 --- a/lib/osal/include/osal/time.h +++ b/lib/osal/include/osal/time.h @@ -34,9 +34,9 @@ extern "C" { #include "osal/Error.h" -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) +#include +#include +#include /// Converts time_t value to struct tm. /// @param value Value to be converted. diff --git a/lib/osal/include/osal/timestamp.h b/lib/osal/include/osal/timestamp.h index 3267984..ad14cca 100644 --- a/lib/osal/include/osal/timestamp.h +++ b/lib/osal/include/osal/timestamp.h @@ -32,7 +32,7 @@ extern "C" { #endif -#include // NOLINT(modernize-deprecated-headers,hicpp-deprecated-headers) +#include /// Returns the timestamp relative to library initialization in ms. /// @return Timestamp relative to library initialization in ms. diff --git a/lib/osal/linux/Semaphore.cpp b/lib/osal/linux/Semaphore.cpp index f888df6..00de20a 100644 --- a/lib/osal/linux/Semaphore.cpp +++ b/lib/osal/linux/Semaphore.cpp @@ -39,13 +39,13 @@ #include #include -OsalError osalSemaphoreCreate(OsalSemaphore* semaphore, unsigned int initialValue) +OsalError osalSemaphoreCreate(OsalSemaphore* semaphore, unsigned int initValue) { if (semaphore == nullptr) return OsalError::InvalidArgument; sem_t handle{}; - [[maybe_unused]] auto result = sem_init(&handle, 0, initialValue); + [[maybe_unused]] auto result = sem_init(&handle, 0, initValue); assert(result == 0); semaphore->impl.handle = handle; diff --git a/tests/init/freertos-arm/CMakeLists.txt b/tests/init/freertos-arm/CMakeLists.txt index 9e4decd..4675239 100644 --- a/tests/init/freertos-arm/CMakeLists.txt +++ b/tests/init/freertos-arm/CMakeLists.txt @@ -5,7 +5,7 @@ target_sources(platform-init PRIVATE find_package(stm32f4xx) target_include_directories(stm32f4xx - PUBLIC + SYSTEM PUBLIC . ) @@ -23,7 +23,7 @@ target_link_options(platform-init add_library(freertos-config INTERFACE) target_include_directories(freertos-config - INTERFACE + SYSTEM INTERFACE . ) diff --git a/tests/init/freertos-arm/stm32f407vgtx.ld b/tests/init/freertos-arm/stm32f407vgtx.ld index 9c0830d..2b8225e 100644 --- a/tests/init/freertos-arm/stm32f407vgtx.ld +++ b/tests/init/freertos-arm/stm32f407vgtx.ld @@ -61,11 +61,19 @@ _Min_Stack_Size = 0x950; /* required amount of stack */ /* Specify the memory areas */ MEMORY { -RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K +RAM (rw) : ORIGIN = 0x20000000, LENGTH = 128K +CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K } +/* Define program headers */ +PHDRS +{ + flash PT_LOAD FLAGS(5); /* Read + Execute */ + ccmram PT_LOAD FLAGS(6); /* Read + Write */ + ram PT_LOAD FLAGS(6); /* Read + Write */ +} + /* Define output sections */ SECTIONS { @@ -75,7 +83,7 @@ SECTIONS . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); - } >FLASH + } >FLASH :flash /* The program code and other data goes into FLASH */ .text : @@ -92,7 +100,7 @@ SECTIONS . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ - } >FLASH + } >FLASH :flash /* Constant data goes into FLASH */ .rodata : @@ -101,54 +109,39 @@ SECTIONS *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); - } >FLASH + } >FLASH :flash - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH :flash .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; - } >FLASH + } >FLASH :flash .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH + } >FLASH :flash .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH + } >FLASH :flash .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(4); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(4); - _edata = .; /* define a global symbol at data end */ - } >RAM AT> FLASH + } >FLASH :flash _siccmram = LOADADDR(.ccmram); - /* CCM-RAM section + /* CCM-RAM section (VMA 0x10000000 — placed before .data for ascending VMA order) * * IMPORTANT NOTE! * If initialized variables will be placed in this section, @@ -163,7 +156,22 @@ SECTIONS . = ALIGN(4); _eccmram = .; /* create a global symbol at ccmram end */ - } >CCMRAM AT> FLASH + } >CCMRAM AT> FLASH :ccmram + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH :ram /* Uninitialized data section */ @@ -180,7 +188,7 @@ SECTIONS . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; - } >RAM + } >RAM :ram /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : @@ -193,7 +201,7 @@ SECTIONS PROVIDE (heapMax = .); . = . + _Min_Stack_Size; . = ALIGN(8); - } >RAM + } >RAM :ram diff --git a/tools/adjust-compilation-db.py b/tools/adjust-compilation-db.py index 2bb3156..d07cb20 100755 --- a/tools/adjust-compilation-db.py +++ b/tools/adjust-compilation-db.py @@ -3,7 +3,7 @@ import json COMPILATION_DB_FILE = "compile_commands.json" -PATTERNS_TO_REMOVE = ["_deps"] +PATTERNS_TO_REMOVE = ["_deps", "tests/init"] with open(COMPILATION_DB_FILE) as file: compilation_db = json.load(file)