From bb3a4a5963d34328a935a296d69f8d6463a0f541 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Thu, 19 Jan 2023 23:57:37 +0100 Subject: [PATCH 01/26] Change includes --- include/sta/rtos/mutex.hpp | 2 +- include/sta/rtos/signal.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sta/rtos/mutex.hpp b/include/sta/rtos/mutex.hpp index 757292e..c60f34c 100644 --- a/include/sta/rtos/mutex.hpp +++ b/include/sta/rtos/mutex.hpp @@ -5,7 +5,7 @@ #ifndef STA_RTOS_MUTEX_HPP #define STA_RTOS_MUTEX_HPP -#include +#include #include diff --git a/include/sta/rtos/signal.hpp b/include/sta/rtos/signal.hpp index 49fa599..ea54513 100644 --- a/include/sta/rtos/signal.hpp +++ b/include/sta/rtos/signal.hpp @@ -5,7 +5,7 @@ #ifndef STA_RTOS_SIGNAL_HPP #define STA_RTOS_SIGNAL_HPP -#include +#include #include From c644da1769bb0638f06ab7327f1242ab5b8bdb61 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 00:14:49 +0100 Subject: [PATCH 02/26] Add Dave Nadler's malloc implementation --- src/heap_useNewlib_ST.c | 287 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 src/heap_useNewlib_ST.c diff --git a/src/heap_useNewlib_ST.c b/src/heap_useNewlib_ST.c new file mode 100644 index 0000000..1fb3987 --- /dev/null +++ b/src/heap_useNewlib_ST.c @@ -0,0 +1,287 @@ +/** + * \file heap_useNewlib_ST.c + * \brief Wrappers required to use newlib malloc-family within FreeRTOS. + * + * \par Overview + * Route FreeRTOS memory management functions to newlib's malloc family. + * Thus newlib and FreeRTOS share memory-management routines and memory pool, + * and all newlib's internal memory-management requirements are supported. + * + * \author Dave Nadler + * \date 20-August-2019 + * \version 27-Jun-2020 Correct "FreeRTOS.h" capitalization, commentary + * \version 24-Jun-2020 commentary only + * \version 11-Sep-2019 malloc accounting, comments, newlib version check + * + * \see http://www.nadler.com/embedded/newlibAndFreeRTOS.html + * \see https://sourceware.org/newlib/libc.html#Reentrancy + * \see https://sourceware.org/newlib/libc.html#malloc + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fenv_005flock + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fmalloc_005flock + * \see https://sourceforge.net/p/freertos/feature-requests/72/ + * \see http://www.billgatliff.com/newlib.html + * \see http://wiki.osdev.org/Porting_Newlib + * \see http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html + * + * + * \copyright + * (c) Dave Nadler 2017-2020, All Rights Reserved. + * Web: http://www.nadler.com + * email: drn@nadler.com + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Use or redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * - Use or redistributions of source code must retain ALL ORIGINAL COMMENTS, AND + * ANY CHANGES MUST BE DOCUMENTED, INCLUDING: + * - Reason for change (purpose) + * - Functional change + * - Date and author contact + * + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// ================================================================================================ +// ======================================= Configuration ======================================== +// These configuration symbols could be provided by from build... +#define STM_VERSION // Replace sane LD symbols with STM CubeMX's poor standard exported LD symbols +#define ISR_STACK_LENGTH_BYTES (configISR_STACK_SIZE_WORDS*4) // bytes to reserve for ISR (MSP) stack +// ======================================= Configuration ======================================== +// ================================================================================================ + + +#include // maps to newlib... +#include // mallinfo... +#include // ENOMEM +#include +#include + +#include "newlib.h" +#if ((__NEWLIB__ == 2) && (__NEWLIB_MINOR__ < 5)) ||((__NEWLIB__ == 3) && (__NEWLIB_MINOR__ > 1)) + #warning "This wrapper was verified for newlib versions 2.5 - 3.1; please ensure newlib's external requirements for malloc-family are unchanged!" +#endif + +#include "FreeRTOS.h" // defines public interface we're implementing here +#if !defined(configUSE_NEWLIB_REENTRANT) || (configUSE_NEWLIB_REENTRANT!=1) + #warning "#define configUSE_NEWLIB_REENTRANT 1 // Required for thread-safety of newlib sprintf, dtoa, strtok, etc..." + // If you're *REALLY* sure you don't need FreeRTOS's newlib reentrancy support, comment out the above warning... +#endif +#include "task.h" + +// ================================================================================================ +// External routines required by newlib's malloc (sbrk/_sbrk, __malloc_lock/unlock) +// ================================================================================================ + +// Simplistic sbrk implementations assume stack grows downwards from top of memory, +// and heap grows upwards starting just after BSS. +// FreeRTOS normally allocates task stacks from a pool placed within BSS or DATA. +// Thus within a FreeRTOS task, stack pointer is always below end of BSS. +// When using this module, stacks are allocated from malloc pool, still always prior +// current unused heap area... + +// Doesn't work with FreeRTOS: STM CubeMX 2018-2019 Incorrect Implementation +#if 0 + caddr_t _sbrk(int incr) + { + extern char end asm("end"); // From linker: lowest unused RAM address, just beyond end of BSS. + static char *heap_end; + char *prev_heap_end; + if (heap_end == 0) heap_end = &end; + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) // Fails here: always true for FreeRTOS task stacks + { + errno = ENOMEM; // ...so first call inside a FreeRTOS task lands here + return (caddr_t) -1; + } + heap_end += incr; + return (caddr_t) prev_heap_end; + } +#endif + +register char * stack_ptr asm("sp"); + +#ifdef STM_VERSION // Use STM CubeMX LD symbols for heap+stack area + // To avoid modifying STM LD file (and then having CubeMX trash it), use available STM symbols + // Unfortunately STM does not provide standardized markers for RAM suitable for heap! + // STM CubeMX-generated LD files provide the following symbols: + // end /* aligned first word beyond BSS */ + // _estack /* one word beyond end of "RAM" Ram type memory, for STM32F429 0x20030000 */ + // Kludge below uses CubeMX-generated symbols instead of sane LD definitions + #define __HeapBase end + #define __HeapLimit _estack // In K64F LD this is already adjusted for ISR stack space... + static int heapBytesRemaining; + // no DRN HEAP_SIZE symbol from LD... // that's (&__HeapLimit)-(&__HeapBase) + uint32_t TotalHeapSize; // publish for diagnostic routines; filled in first _sbrk call. +#else + // Note: DRN's K64F LD provided: __StackTop (byte beyond end of memory), __StackLimit, HEAP_SIZE, STACK_SIZE + // __HeapLimit was already adjusted to be below reserved stack area. + extern char HEAP_SIZE; // make sure to define this symbol in linker LD command file + static int heapBytesRemaining = (int)&HEAP_SIZE; // that's (&__HeapLimit)-(&__HeapBase) +#endif + + +#ifdef MALLOCS_INSIDE_ISRs // STM code to avoid malloc within ISR (USB CDC stack) + // We can't use vTaskSuspendAll() within an ISR. + // STM's stunningly bad coding malpractice calls malloc within ISRs (for example, on USB connect function USBD_CDC_Init) + // So, we must just suspend/resume interrupts, lengthening max interrupt response time, aarrggg... + #define DRN_ENTER_CRITICAL_SECTION(_usis) { _usis = taskENTER_CRITICAL_FROM_ISR(); } // Disables interrupts (after saving prior state) + #define DRN_EXIT_CRITICAL_SECTION(_usis) { taskEXIT_CRITICAL_FROM_ISR(_usis); } // Re-enables interrupts (unless already disabled prior taskENTER_CRITICAL) +#else + #define DRN_ENTER_CRITICAL_SECTION(_usis) vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started, but not in ISR + #define DRN_EXIT_CRITICAL_SECTION(_usis) xTaskResumeAll(); // Note: safe to use before FreeRTOS scheduler started, but not in ISR +#endif + +#ifndef NDEBUG + static int totalBytesProvidedBySBRK = 0; +#endif +extern char __HeapBase, __HeapLimit; // symbols from linker LD command file + +// Use of vTaskSuspendAll() in _sbrk_r() is normally redundant, as newlib malloc family routines call +// __malloc_lock before calling _sbrk_r(). Note vTaskSuspendAll/xTaskResumeAll support nesting. + +//! _sbrk_r version supporting reentrant newlib (depends upon above symbols defined by linker control file). +void * _sbrk_r(struct _reent *pReent, int incr) { + #ifdef MALLOCS_INSIDE_ISRs // block interrupts during free-storage use + UBaseType_t usis; // saved interrupt status + #endif + static char *currentHeapEnd = &__HeapBase; + #ifdef STM_VERSION // Use STM CubeMX LD symbols for heap + if(TotalHeapSize==0) { + TotalHeapSize = heapBytesRemaining = (int)((&__HeapLimit)-(&__HeapBase))-ISR_STACK_LENGTH_BYTES; + }; + #endif + char* limit = (xTaskGetSchedulerState()==taskSCHEDULER_NOT_STARTED) ? + stack_ptr : // Before scheduler is started, limit is stack pointer (risky!) + &__HeapLimit-ISR_STACK_LENGTH_BYTES; // Once running, OK to reuse all remaining RAM except ISR stack (MSP) stack + DRN_ENTER_CRITICAL_SECTION(usis); + if (currentHeapEnd + incr > limit) { + // Ooops, no more memory available... + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + extern void vApplicationMallocFailedHook( void ); + DRN_EXIT_CRITICAL_SECTION(usis); + vApplicationMallocFailedHook(); + } + #elif defined(configHARD_STOP_ON_MALLOC_FAILURE) + // If you want to alert debugger or halt... + // WARNING: brkpt instruction may prevent watchdog operation... + while(1) { __asm("bkpt #0"); }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop forever) + #else + // Default, if you prefer to believe your application will gracefully trap out-of-memory... + pReent->_errno = ENOMEM; // newlib's thread-specific errno + DRN_EXIT_CRITICAL_SECTION(usis); + #endif + return (char *)-1; // the malloc-family routine that called sbrk will return 0 + } + // 'incr' of memory is available: update accounting and return it. + char *previousHeapEnd = currentHeapEnd; + currentHeapEnd += incr; + heapBytesRemaining -= incr; + #ifndef NDEBUG + totalBytesProvidedBySBRK += incr; + #endif + DRN_EXIT_CRITICAL_SECTION(usis); + return (char *) previousHeapEnd; +} +//! non-reentrant sbrk uses is actually reentrant by using current context +// ... because the current _reent structure is pointed to by global _impure_ptr +char * sbrk(int incr) { return _sbrk_r(_impure_ptr, incr); } +//! _sbrk is a synonym for sbrk. +char * _sbrk(int incr) { return sbrk(incr); }; + +#ifdef MALLOCS_INSIDE_ISRs // block interrupts during free-storage use + static UBaseType_t malLock_uxSavedInterruptStatus; +#endif +void __malloc_lock(struct _reent *r) { + (void)(r); + #if defined(MALLOCS_INSIDE_ISRs) + DRN_ENTER_CRITICAL_SECTION(malLock_uxSavedInterruptStatus); + #else + bool insideAnISR = xPortIsInsideInterrupt(); + configASSERT( !insideAnISR ); // Make damn sure no more mallocs inside ISRs!! + vTaskSuspendAll(); + #endif +}; +void __malloc_unlock(struct _reent *r) { + (void)(r); + #if defined(MALLOCS_INSIDE_ISRs) + DRN_EXIT_CRITICAL_SECTION(malLock_uxSavedInterruptStatus); + #else + (void)xTaskResumeAll(); + #endif +}; + +// newlib also requires implementing locks for the application's environment memory space, +// accessed by newlib's setenv() and getenv() functions. +// As these are trivial functions, momentarily suspend task switching (rather than semaphore). +// Not required (and trimmed by linker) in applications not using environment variables. +// ToDo: Move __env_lock/unlock to a separate newlib helper file. +void __env_lock() { vTaskSuspendAll(); }; +void __env_unlock() { (void)xTaskResumeAll(); }; + +#if 1 // Provide malloc debug and accounting wrappers + /// /brief Wrap malloc/malloc_r to help debug who requests memory and why. + /// To use these, add linker options: -Xlinker --wrap=malloc -Xlinker --wrap=_malloc_r + // Note: These functions are normally unused and stripped by linker. + size_t TotalMallocdBytes; + int MallocCallCnt; + static bool inside_malloc; + void *__wrap_malloc(size_t nbytes) { + extern void * __real_malloc(size_t nbytes); + MallocCallCnt++; + TotalMallocdBytes += nbytes; + inside_malloc = true; + void *p = __real_malloc(nbytes); // will call malloc_r... + inside_malloc = false; + return p; + }; + void *__wrap__malloc_r(void *reent, size_t nbytes) { + (void)(reent); + extern void * __real__malloc_r(size_t nbytes); + if(!inside_malloc) { + MallocCallCnt++; + TotalMallocdBytes += nbytes; + }; + void *p = __real__malloc_r(nbytes); + return p; + }; +#endif + +// ================================================================================================ +// Implement FreeRTOS's memory API using newlib-provided malloc family. +// ================================================================================================ + +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION { + void *p = malloc(xSize); + return p; +} +void vPortFree( void *pv ) PRIVILEGED_FUNCTION { + free(pv); +}; + +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION { + struct mallinfo mi = mallinfo(); // available space now managed by newlib + return mi.fordblks + heapBytesRemaining; // plus space not yet handed to newlib by sbrk +} + +// GetMinimumEverFree is not available in newlib's malloc implementation. +// So, no implementation is provided: size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +//! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; From ebd7b8a60f68d51fab02a9931d17056b69f52f80 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 00:21:39 +0100 Subject: [PATCH 03/26] Add config integration --- src/heap_useNewlib_ST.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/heap_useNewlib_ST.c b/src/heap_useNewlib_ST.c index 1fb3987..b56419c 100644 --- a/src/heap_useNewlib_ST.c +++ b/src/heap_useNewlib_ST.c @@ -57,6 +57,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * \author Henrik Stickann + * \data 20-January-2023 + * + * Changes: + * * Add macro to only use implementation when requested by user + */ +#include +#ifdef STA_RTOS_MALLOC_ENABLE + // ================================================================================================ // ======================================= Configuration ======================================== // These configuration symbols could be provided by from build... @@ -285,3 +295,6 @@ size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION { //! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; + + +#endif // STA_RTOS_MALLOC_ENABLE From 3a02ba19f2d912aa3271d5ce4706472bab4e4921 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 00:27:12 +0100 Subject: [PATCH 04/26] Add config macro for ISR stack size --- src/heap_useNewlib_ST.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/heap_useNewlib_ST.c b/src/heap_useNewlib_ST.c index b56419c..4639e6c 100644 --- a/src/heap_useNewlib_ST.c +++ b/src/heap_useNewlib_ST.c @@ -67,6 +67,16 @@ #include #ifdef STA_RTOS_MALLOC_ENABLE +// Allow setting configISR_STACK_SIZE_WORDS via the STA_RTOS_ISR_STACK_SIZE_WORDS config macro +#ifdef STA_RTOS_ISR_STACK_SIZE_WORDS +# ifdef configISR_STACK_SIZE_WORDS +# warning "STA_RTOS_ISR_STACK_SIZE_WORDS value overriden by configISR_STACK_SIZE_WORDS!" +# else // configISR_STACK_SIZE_WORDS +# define configISR_STACK_SIZE_WORDS STA_RTOS_ISR_STACK_SIZE_WORDS +# endif // configISR_STACK_SIZE_WORDS +#endif // STA_RTOS_ISR_STACK_SIZE_WORDS + + // ================================================================================================ // ======================================= Configuration ======================================== // These configuration symbols could be provided by from build... From 61d586ae475b70b7292c61e186b4d612a1fff14f Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 02:37:39 +0100 Subject: [PATCH 05/26] Rename runtime stats macro --- src/runtime_stats.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/runtime_stats.c b/src/runtime_stats.c index 2841d23..78ec692 100644 --- a/src/runtime_stats.c +++ b/src/runtime_stats.c @@ -1,5 +1,5 @@ #include -#ifdef STA_RTOS_STM32_RUNTIME_TIM +#ifdef STA_RTOS_RUNTIME_STATS_TIM #include @@ -7,14 +7,14 @@ void configureTimerForRunTimeStats() { // Start timer base - HAL_TIM_Base_Start(&STA_RTOS_STM32_RUNTIME_TIM); + HAL_TIM_Base_Start(&STA_RTOS_RUNTIME_STATS_TIM); // Reset timer - __HAL_TIM_SET_COUNTER(&STA_RTOS_STM32_RUNTIME_TIM, 0); + __HAL_TIM_SET_COUNTER(&STA_RTOS_RUNTIME_STATS_TIM, 0); } unsigned long getRunTimeCounterValue() { - return __HAL_TIM_GET_COUNTER(&STA_RTOS_STM32_RUNTIME_TIM); + return __HAL_TIM_GET_COUNTER(&STA_RTOS_RUNTIME_STATS_TIM); } -#endif // STA_RTOS_STM32_RUNTIME_TIM +#endif // STA_RTOS_RUNTIME_STATS_TIM From 5cf9b254917b3ddfdb9b7c61fcc2a57ed1e8dd88 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 03:28:06 +0100 Subject: [PATCH 06/26] Move runtime stats debug helper --- src/{ => debug}/runtime_stats.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => debug}/runtime_stats.c (100%) diff --git a/src/runtime_stats.c b/src/debug/runtime_stats.c similarity index 100% rename from src/runtime_stats.c rename to src/debug/runtime_stats.c From 2aed5c5ba31859cd95c5b2ec1f877d571fefa0b2 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 03:28:48 +0100 Subject: [PATCH 07/26] Add stack overflow detection helper --- src/debug/stack_overflow.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/debug/stack_overflow.cpp diff --git a/src/debug/stack_overflow.cpp b/src/debug/stack_overflow.cpp new file mode 100644 index 0000000..06cf2a7 --- /dev/null +++ b/src/debug/stack_overflow.cpp @@ -0,0 +1,24 @@ +#include +#ifdef STA_RTOS_STACK_OVERFLOW_HOOK + +#include +#include + +#include +#include + + +extern "C" void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName) +{ + // TODO Handle corrupted parameters + // * check pcTaskName is cstring (look for \0 within ? bytes) + STA_DEBUG_PRINT("Stack overflow detected in task "); + if (pcTaskName) + { + STA_DEBUG_PRINTLN(pcTaskName); + } + STA_HALT(); +} + + +#endif // STA_RTOS_STACK_OVERFLOW_HOOK From ced0bd1a2a8a4395ac39f5ab6f0567f78ff67ea4 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 13:15:44 +0100 Subject: [PATCH 08/26] Only ignore Debug/Release folders in repo base --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cfe5f9d..32f2c6e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ *.launch # Build artifacts -Debug/ -Release/ +/Debug/ +/Release/ # Doxygen docs/html From f866e270811e40ec0b8faa3e22d4146acbafff94 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 14:12:40 +0100 Subject: [PATCH 09/26] Implement robust task name printing --- src/debug/stack_overflow.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/debug/stack_overflow.cpp b/src/debug/stack_overflow.cpp index 06cf2a7..158c454 100644 --- a/src/debug/stack_overflow.cpp +++ b/src/debug/stack_overflow.cpp @@ -8,14 +8,25 @@ #include -extern "C" void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName) +extern "C" void vApplicationStackOverflowHook(xTaskHandle xTask, char * pcTaskName) { - // TODO Handle corrupted parameters - // * check pcTaskName is cstring (look for \0 within ? bytes) STA_DEBUG_PRINT("Stack overflow detected in task "); if (pcTaskName) { - STA_DEBUG_PRINTLN(pcTaskName); + // Manually calculate string length + // Limited to configMAX_TASK_NAME_LEN to avoid reading + // garbage values in case TCB has been corrupted + size_t len = 0; + while (len < configMAX_TASK_NAME_LEN) + { + if (pcTaskName[len] == '\0') + { + break; + } + ++len; + } + + STA_DEBUG_PRINTLN(pcTaskName, len); } STA_HALT(); } From 1c8e427bc3f005cd8660d788d6102e8623220730 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 15:07:00 +0100 Subject: [PATCH 10/26] Simplify system events API --- include/sta/rtos/system/system_event.hpp | 34 ++++++++---------- src/system/system_event.cpp | 44 ++++++++++++++++++------ 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/include/sta/rtos/system/system_event.hpp b/include/sta/rtos/system/system_event.hpp index f6465f3..3018090 100644 --- a/include/sta/rtos/system/system_event.hpp +++ b/include/sta/rtos/system/system_event.hpp @@ -2,10 +2,8 @@ * @file * @brief Implementation of system events. */ -#ifndef STA_RTOS_SYSTEM_SYSTEM_EVENT_HPP -#define STA_RTOS_SYSTEM_SYSTEM_EVENT_HPP - -#include +#ifndef STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP +#define STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP /** @@ -22,23 +20,13 @@ * * @ingroup STA_RTOS_BuildConfig */ -# define STA_RTOS2_SYSTEM_EVENT_ENABLE +# define STA_RTOS2_SYSTEM_EVENTS_ENABLE #endif // DOXYGEN -/** - * @def STA_RTOS_SYSTEM_EVENT_NAME - * @brief Set name of system event flags. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_SYSTEM_EVENT_NAME -# define STA_RTOS_SYSTEM_EVENT_NAME systemEvent -#endif // !STA_RTOS_SYSTEM_EVENT_NAME - - #include -#ifdef STA_RTOS_SYSTEM_EVENT_ENABLE +#ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE + #include @@ -51,13 +39,19 @@ * * @ingroup STA_RTOS_SysEvent */ -#define STA_SYSTEM_EVENT_STARTUP 0x100000U +#define STA_SYSTEM_EVENTS_STARTUP 0x100000U namespace sta { namespace rtos { + /** + * @brief Initialize system events. + */ + void initSystemEvents(); + + /** * @brief Signal system events. * @@ -98,6 +92,6 @@ namespace sta } // namespace sta -#endif // STA_RTOS_SYSTEM_EVENT_ENABLE +#endif // STA_RTOS_SYSTEM_EVENTS_ENABLE -#endif // STA_RTOS_SYSTEM_SYSTEM_EVENT_HPP +#endif // STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP diff --git a/src/system/system_event.cpp b/src/system/system_event.cpp index 7e96fa9..b9d86ed 100644 --- a/src/system/system_event.cpp +++ b/src/system/system_event.cpp @@ -1,43 +1,67 @@ #include +#ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE -#ifdef STA_RTOS_SYSTEM_EVENT_ENABLE +#include #include - -#define STA_RTOS_SYSTEM_EVENT_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_SYSTEM_EVENT_NAME) +#include +#include -// Access handle from freertos.c -extern osEventFlagsId_t STA_RTOS_SYSTEM_EVENT_HANDLE; +namespace +{ + // Static memory for system events + StaticEventGroup_t systemEventControlBlock; + // Event handle + osEventFlagsId_t systemEventsHandle = nullptr; +} namespace sta { namespace rtos { + void initSystemEvents() + { + // Create event using static allocation + const osEventFlagsAttr_t attributes = { + .name = "systemEvent", + .cb_mem = &systemEventControlBlock, + .cb_size = sizeof(systemEventControlBlock), + }; + + if (systemEventsHandle == nullptr) + { + systemEventsHandle = osEventFlagsNew(&attributes); + } + } + + void signalSystemEvents(uint32_t flags) { - osEventFlagsSet(STA_RTOS_SYSTEM_EVENT_HANDLE, flags); + STA_ASSERT_MSG(systemEventsHandle != nullptr, "System events not initialized"); + osEventFlagsSet(systemEventsHandle, flags); } void waitForSystemEvents(uint32_t flags, uint32_t options, uint32_t timeout) { - osEventFlagsWait(STA_RTOS_SYSTEM_EVENT_HANDLE, flags, options | osFlagsNoClear, timeout); + STA_ASSERT_MSG(systemEventsHandle != nullptr, "System events not initialized"); + osEventFlagsWait(systemEventsHandle, flags, options | osFlagsNoClear, timeout); } void signalStartupEvent() { - signalSystemEvents(STA_SYSTEM_EVENT_STARTUP); + signalSystemEvents(STA_SYSTEM_EVENTS_STARTUP); } void waitForStartupEvent() { - waitForSystemEvents(STA_SYSTEM_EVENT_STARTUP, osFlagsWaitAll, osWaitForever); + waitForSystemEvents(STA_SYSTEM_EVENTS_STARTUP, osFlagsWaitAll, osWaitForever); } } // namespace rtos } // namespace sta -#endif // STA_RTOS_SYSTEM_EVENT_ENABLE +#endif // STA_RTOS_SYSTEM_EVENTS_ENABLE From 04b2303a3a0be868679afda827c26a44d64e9a01 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 15:40:14 +0100 Subject: [PATCH 11/26] Simplify system watchdog API --- include/sta/rtos/system/watchdog.hpp | 60 ++-------------- src/system/watchdog.cpp | 103 +++++++++++++++++++++++++++ src/system/watchdog/handles.hpp | 18 ----- src/system/watchdog/heartbeat.cpp | 32 --------- src/system/watchdog/watchdog.cpp | 43 ----------- 5 files changed, 107 insertions(+), 149 deletions(-) create mode 100644 src/system/watchdog.cpp delete mode 100644 src/system/watchdog/handles.hpp delete mode 100644 src/system/watchdog/heartbeat.cpp delete mode 100644 src/system/watchdog/watchdog.cpp diff --git a/include/sta/rtos/system/watchdog.hpp b/include/sta/rtos/system/watchdog.hpp index d74c5ce..3a414d7 100644 --- a/include/sta/rtos/system/watchdog.hpp +++ b/include/sta/rtos/system/watchdog.hpp @@ -5,8 +5,6 @@ #ifndef STA_RTOS_SYSTEM_WATCHDOG_HPP #define STA_RTOS_SYSTEM_WATCHDOG_HPP -#include - /** * @defgroup STA_RTOS_Watchdog Watchdog task @@ -37,61 +35,10 @@ #endif // !STA_RTOS_WATCHDOG_TIMER_PERIOD -/** - * @def STA_RTOS_WATCHDOG_TIMER_NAME - * @brief Set name of watchdog timer. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_WATCHDOG_TIMER_NAME -# define STA_RTOS_WATCHDOG_TIMER_NAME heartbeat -#endif // !STA_RTOS_WATCHDOG_TIMER_NAME - -/** - * @def STA_RTOS_WATCHDOG_TIMER_HANDLE - * @brief Set variable name of heartbeat timer handle. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_WATCHDOG_TIMER_HANDLE -# define STA_RTOS_WATCHDOG_TIMER_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TIMER_NAME) -#endif // !STA_RTOS_WATCHDOG_TIMER_HANDLE - -/** - * @def STA_RTOS_WATCHDOG_TIMER_CALLBACK - * @brief Set name of heartbeat timer callback function. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_WATCHDOG_TIMER_CALLBACK -# define STA_RTOS_WATCHDOG_TIMER_CALLBACK STA_RTOS_MAKE_CALLBACK_NAME(STA_RTOS_WATCHDOG_TIMER_NAME) -#endif // !STA_RTOS_WATCHDOG_TIMER_CALLBACK - - -/** - * @def STA_RTOS_WATCHDOG_TASK_NAME - * @brief Set name of watchdog task. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_WATCHDOG_TASK_NAME -# define STA_RTOS_WATCHDOG_TASK_NAME watchdog -#endif // !STA_RTOS_WATCHDOG_TASK_NAME - -/** - * @def STA_RTOS_WATCHDOG_ENTRY_FUNCTION - * @brief Set name of watchdog task entry function. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_WATCHDOG_ENTRY_FUNCTION -# define STA_RTOS_WATCHDOG_ENTRY_FUNCTION STA_RTOS_MAKE_ENTRY_NAME(STA_RTOS_WATCHDOG_TASK_NAME) -#endif // !STA_RTOS_WATCHDOG_ENTRY_FUNCTION - - #include #ifdef STA_RTOS_WATCHDOG_ENABLE + #include @@ -111,11 +58,12 @@ namespace sta namespace rtos { /** - * @brief Start heartbeat timer for watchdog. + * @brief Initialize system watchdog. * * @ingroup STA_RTOS_Watchdog */ - void startWatchdogTimer(); + void initWatchdog(); + /** * @brief Send notification to watchdog task. * diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp new file mode 100644 index 0000000..e93b148 --- /dev/null +++ b/src/system/watchdog.cpp @@ -0,0 +1,103 @@ +#include +#ifdef STA_RTOS_WATCHDOG_ENABLE + +#include +#include +#include +#include + +#include +#include + + +namespace +{ + StaticTask_t watchdogCB; + StaticTimer_t watchdogTimerCB; + + osThreadId_t watchdogTaskHandle = nullptr; + osTimerId_t watchdogTimerHandle = nullptr; + + // Static stack memory + uint32_t stackBuffer[256]; +} + + +extern "C" +{ + void watchdogTask(void * arg); + void watchdogTimerCallback(void *); +} + + +namespace sta +{ + namespace rtos + { + void initWatchdog() + { + // Create thread using static allocation + const osThreadAttr_t taskAttributes = { + .name = "sysWatchdog", + .cb_mem = &watchdogCB, + .cb_size = sizeof(watchdogCB), + .stack_mem = &stackBuffer[0], + .stack_size = sizeof(stackBuffer), + .priority = (osPriority_t) osPriorityLow, + }; + + watchdogTaskHandle = osThreadNew(watchdogTask, NULL, &taskAttributes); + STA_ASSERT_MSG(watchdogTaskHandle != nullptr, "System watchdog task initialization failed"); + + + // Create timer using static allocation + const osTimerAttr_t timerAttributes = { + .name = "sysWatchdogTimer", + .attr_bits = 0, // Reserved, must be set to 0 + .cb_mem = &watchdogTimerCB, + .cb_size = sizeof(watchdogTimerCB) + }; + + watchdogTimerHandle = osTimerNew(watchdogTimerCallback, osTimerPeriodic, nullptr, &timerAttributes); + STA_ASSERT_MSG(watchdogTimerHandle != nullptr, "System watchdog timer initialization failed"); + osTimerStart(watchdogTimerHandle, STA_RTOS_WATCHDOG_TIMER_PERIOD); + } + + + void notifyWatchdog(uint32_t flags) + { + STA_ASSERT_MSG(watchdogTaskHandle != nullptr, "System watchdog not initialized"); + osThreadFlagsSet(watchdogTaskHandle, flags); + } + + STA_WEAK void watchdogEventHandler(void * arg, uint32_t flags) + {} + } // namespace rtos +} // namespace sta + + + +void watchdogTask(void * arg) +{ + sta::rtos::waitForStartupEvent(); + + while (true) + { + // Wait for any flag to be set + uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, osWaitForever); + + // Call event handler + sta::rtos::watchdogEventHandler(arg, flags); + } +} + +void watchdogTimerCallback(void *) +{ + // Notify watchdog task to send heartbeat message + // Required because blocking in a timer callback is not allowed + osThreadFlagsSet(watchdogTaskHandle, STA_WATCHDOG_FLAG_HEARTBEAT); +} + + + +#endif // STA_RTOS_WATCHDOG_ENABLE diff --git a/src/system/watchdog/handles.hpp b/src/system/watchdog/handles.hpp deleted file mode 100644 index 95c75fe..0000000 --- a/src/system/watchdog/handles.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP -#define STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP - -#include - -#include - - -#define WATCHDOG_TASK_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TASK_NAME) -#define WATCHDOG_TIMER_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TIMER_NAME) - - -// Access handles from freertos.c -extern osThreadId_t WATCHDOG_TASK_HANDLE; -extern osTimerId_t WATCHDOG_TIMER_HANDLE; - - -#endif // STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP diff --git a/src/system/watchdog/heartbeat.cpp b/src/system/watchdog/heartbeat.cpp deleted file mode 100644 index 0ceb15d..0000000 --- a/src/system/watchdog/heartbeat.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#ifdef STA_RTOS_WATCHDOG_ENABLE - -#include "handles.hpp" - - -namespace sta -{ - namespace rtos - { - void startWatchdogTimer() - { - osTimerStart(WATCHDOG_TIMER_HANDLE, STA_RTOS_WATCHDOG_TIMER_PERIOD); - } - } // namespace rtos -} // namespace sta - - -// Declare with C linkage -extern "C" -{ - void STA_RTOS_WATCHDOG_TIMER_CALLBACK(void *) - { - // Notify watchdog task to send heartbeat message - // Required because blocking in a timer callback is not allowed - osThreadFlagsSet(WATCHDOG_TASK_HANDLE, STA_WATCHDOG_FLAG_HEARTBEAT); - } -} - - -#endif // STA_RTOS_WATCHDOG_ENABLE diff --git a/src/system/watchdog/watchdog.cpp b/src/system/watchdog/watchdog.cpp deleted file mode 100644 index 775b9c9..0000000 --- a/src/system/watchdog/watchdog.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include - -#ifdef STA_RTOS_WATCHDOG_ENABLE - -#include -#include - - -#include "handles.hpp" - - -namespace sta -{ - namespace rtos - { - void notifyWatchdog(uint32_t flags) - { - osThreadFlagsSet(WATCHDOG_TASK_HANDLE, flags); - } - } // namespace rtos -} // namespace sta - - -// Declare with C linkage -extern "C" -{ - void STA_RTOS_WATCHDOG_ENTRY_FUNCTION(void * arg) - { - sta::rtos::waitForStartupEvent(); - - while (true) - { - // Wait for any flag to be set - uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, osWaitForever); - - // Call event handler - sta::rtos::watchdogEventHandler(arg, flags); - } - } -} - - -#endif // STA_RTOS_WATCHDOG_ENABLE From d323d2ada5944d407b180d332858d7cdbdfe7511 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 22:16:45 +0100 Subject: [PATCH 12/26] Remove unused include --- src/system/system_event.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/system/system_event.cpp b/src/system/system_event.cpp index b9d86ed..caf89ab 100644 --- a/src/system/system_event.cpp +++ b/src/system/system_event.cpp @@ -4,9 +4,7 @@ #include #include - #include -#include namespace From ecacb923f2bf9ba1f3033bf53b084ab514ca381b Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 22:18:16 +0100 Subject: [PATCH 13/26] Rework CAN bus system task --- include/sta/rtos/system/can_bus.hpp | 35 +- src/system/can_bus.cpp | 659 +++++++++++++++++----------- 2 files changed, 406 insertions(+), 288 deletions(-) diff --git a/include/sta/rtos/system/can_bus.hpp b/include/sta/rtos/system/can_bus.hpp index 0810ac3..63bd4fd 100644 --- a/include/sta/rtos/system/can_bus.hpp +++ b/include/sta/rtos/system/can_bus.hpp @@ -5,8 +5,6 @@ #ifndef STA_RTOS_SYSTEM_CAN_BUS_HPP #define STA_RTOS_SYSTEM_CAN_BUS_HPP -#include - /** * @defgroup STA_RTOS_CanBus CAN driver @@ -25,30 +23,12 @@ # define STA_RTOS_CAN_BUS_ENABLE #endif // DOXYGEN -/** - * @def STA_RTOS_CAN_BUS_TASK_NAME - * @brief Set name of CAN driver task. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_CAN_BUS_TASK_NAME -# define STA_RTOS_CAN_BUS_TASK_NAME canBus -#endif // !STA_RTOS_CAN_BUS_TASK_NAME - -/** - * @def STA_RTOS_CAN_BUS_ENTRY_FUNCTION - * @brief Set name of CAN driver task entry function. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_CAN_BUS_ENTRY_FUNCTION -# define STA_RTOS_CAN_BUS_ENTRY_FUNCTION STA_RTOS_MAKE_ENTRY_NAME(STA_RTOS_CAN_BUS_TASK_NAME) -#endif // !STA_RTOS_CAN_BUS_ENTRY_FUNCTION - #include #ifdef STA_RTOS_CAN_BUS_ENABLE + +#include #include #include @@ -121,13 +101,18 @@ namespace sta * @{ */ + /** + * @brief Initialize CAN bus. + */ + void initCanBus(); + /** - * @brief Extra initialization run at start of CAN bus task. + * @brief Return CanController for use in CAN system task. * - * May be overridden by application if required. + * Implementation must be provided by application. */ - void setupCanBus(); + extern CanController * getCanController(); diff --git a/src/system/can_bus.cpp b/src/system/can_bus.cpp index 6451d56..c75412d 100644 --- a/src/system/can_bus.cpp +++ b/src/system/can_bus.cpp @@ -6,61 +6,101 @@ #ifdef STA_RTOS_CAN_BUS_ENABLE #include -#include #include +#include #include - -#include -#include - #include #include - #include #include #include -#include - -#include - -#include +#include #include +#include #include -#define STA_RTOS_MAKE_DATA_QUEUE_NAME(name) _STA_RTOS_CONCAT(name, DataQueue) -#define STA_RTOS_MAKE_SYS_QUEUE_NAME(name) _STA_RTOS_CONCAT(name, SysQueue) +namespace +{ + StaticTask_t canBusCB; + StaticQueue_t canBusDataQueueCB; + StaticQueue_t canBusSysQueueCB; + + osThreadId_t canBusTaskHandle = nullptr; + osMessageQueueId_t canBusDataQueueHandle = nullptr; + osMessageQueueId_t canBusSysQueueHandle = nullptr; + + sta::CanController * canBusController = nullptr; + + const size_t queueLength = 8; + + // Static memory buffers + CanDataMsg canBusDataQueueBuffer[queueLength]; + CanSysMsg canBusSysQueueBuffer[queueLength]; + uint32_t canBusStack[256]; +} -#define STA_RTOS_CAN_BUS_THREAD STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_CAN_BUS_TASK_NAME) -#define STA_RTOS_CAN_BUS_DATA_QUEUE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_MAKE_DATA_QUEUE_NAME(STA_RTOS_CAN_BUS_TASK_NAME)) -#define STA_RTOS_CAN_BUS_SYS_QUEUE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_MAKE_SYS_QUEUE_NAME(STA_RTOS_CAN_BUS_TASK_NAME)) - - -// Access handles from freertos.c -extern osThreadId_t STA_RTOS_CAN_BUS_THREAD; -extern osMessageQueueId_t STA_RTOS_CAN_BUS_DATA_QUEUE; -extern osMessageQueueId_t STA_RTOS_CAN_BUS_SYS_QUEUE; +extern "C" void canBusTask(void *); namespace sta { namespace rtos { - extern CanController * CanBusController; + void initCanBus() + { + // Create thread using static allocation + const osThreadAttr_t taskAttributes = { + .name = "sysCanBus", + .cb_mem = &canBusCB, + .cb_size = sizeof(canBusCB), + .stack_mem = &canBusStack[0], + .stack_size = sizeof(canBusStack), + .priority = (osPriority_t) osPriorityLow, + }; + + canBusTaskHandle = osThreadNew(canBusTask, NULL, &taskAttributes); + STA_ASSERT_MSG(canBusTaskHandle != nullptr, "System CAN task initialization failed"); - STA_WEAK - void setupCanBus() - {} + // Create message queues using static allocation + const osMessageQueueAttr_t dataQueueAttributes = { + .name = "sysCanDataOut", + .attr_bits = 0, + .cb_mem = &canBusDataQueueCB, + .cb_size = sizeof(canBusDataQueueCB), + .mq_mem = &canBusDataQueueBuffer, + .mq_size = sizeof(canBusDataQueueBuffer) + }; + + canBusDataQueueHandle = osMessageQueueNew(queueLength, sizeof(CanDataMsg), &dataQueueAttributes); + STA_ASSERT_MSG(canBusDataQueueHandle != nullptr, "System CAN data message queue initialization failed"); + + const osMessageQueueAttr_t sysQueueAttributes = { + .name = "sysCanSysOut", + .attr_bits = 0, + .cb_mem = &canBusSysQueueCB, + .cb_size = sizeof(canBusSysQueueCB), + .mq_mem = &canBusSysQueueBuffer, + .mq_size = sizeof(canBusSysQueueBuffer) + }; + + canBusSysQueueHandle = osMessageQueueNew(queueLength, sizeof(CanSysMsg), &sysQueueAttributes); + STA_ASSERT_MSG(canBusSysQueueHandle != nullptr, "System CAN system message queue initialization failed"); + + + // Get initialized CAN controller from application + canBusController = getCanController(); + } void notifyCanBus(uint32_t flags) { // Send flags to thread - osThreadFlagsSet(STA_RTOS_CAN_BUS_THREAD, flags); + osThreadFlagsSet(canBusTaskHandle, flags); } @@ -69,10 +109,10 @@ namespace sta STA_ASSERT((msg.header.sid & STA_CAN_SID_SYS_BITS) == 0); STA_ASSERT(msg.header.payloadLength <= sizeof(msg.payload)); - if (osOK == osMessageQueuePut(STA_RTOS_CAN_BUS_DATA_QUEUE, &msg, 0, timeout)) + if (osOK == osMessageQueuePut(canBusDataQueueHandle, &msg, 0, timeout)) { // Signal thread - osThreadFlagsSet(STA_RTOS_CAN_BUS_THREAD, STA_RTOS_CAN_FLAG_DATA_QUEUED); + osThreadFlagsSet(canBusTaskHandle, STA_RTOS_CAN_FLAG_DATA_QUEUED); return true; } else @@ -85,10 +125,10 @@ namespace sta { STA_ASSERT((msg.header.sid & ~STA_CAN_SID_SYS_BITS) == 0); - if (osOK == osMessageQueuePut(STA_RTOS_CAN_BUS_SYS_QUEUE, &msg, 0, timeout)) + if (osOK == osMessageQueuePut(canBusSysQueueHandle, &msg, 0, timeout)) { // Signal thread - osThreadFlagsSet(STA_RTOS_CAN_BUS_THREAD, STA_RTOS_CAN_FLAG_SYS_QUEUED); + osThreadFlagsSet(canBusTaskHandle, STA_RTOS_CAN_FLAG_SYS_QUEUED); return true; } else @@ -100,70 +140,19 @@ namespace sta bool getCanBusMsg(CanDataMsg * msg, uint32_t timeout) { - return (osOK == osMessageQueueGet(STA_RTOS_CAN_BUS_DATA_QUEUE, msg, 0, timeout)); + return (osOK == osMessageQueueGet(canBusDataQueueHandle, msg, 0, timeout)); } bool getCanBusMsg(CanSysMsg * msg, uint32_t timeout) { - return (osOK == osMessageQueueGet(STA_RTOS_CAN_BUS_SYS_QUEUE, msg, 0, timeout)); + return (osOK == osMessageQueueGet(canBusSysQueueHandle, msg, 0, timeout)); } } // namespace rtos } // namespace sta -using namespace sta; - - -/**< ISOTP CAN transmitter */ -IsotpTransmitter gCanTx(rtos::CanBusController, HAL_GetTick); -/**< ISOTP CAN receiver */ -IsotpReceiver gCanRx(rtos::CanBusController, HAL_GetTick); - - -CanRxCallback filterCallbacks[STA_RTOS_CAN_BUS_MAX_FILTER]; - - namespace debug { - /** - * @brief Display ISOTP TX/RX statistics. - */ - void showStatistics() - { - STA_DEBUG_PRINTLN(); - STA_DEBUG_PRINTLN("# ######################"); - STA_DEBUG_PRINTLN("# ## ISOTP statistics ##"); - STA_DEBUG_PRINTLN("# ######################"); - STA_DEBUG_PRINTLN("#"); - - STA_DEBUG_PRINTLN("# Transmitter"); - STA_DEBUG_PRINT("# messages: "); - STA_DEBUG_PRINTLN(gCanTx.stats().messages); - STA_DEBUG_PRINT("# blocks: "); - STA_DEBUG_PRINTLN(gCanTx.stats().blocks); - STA_DEBUG_PRINT("# frames: "); - STA_DEBUG_PRINTLN(gCanTx.stats().frames); - STA_DEBUG_PRINT("# timeouts: "); - STA_DEBUG_PRINTLN(gCanTx.stats().timeouts); - STA_DEBUG_PRINTLN("#"); - - STA_DEBUG_PRINTLN("# Receiver"); - STA_DEBUG_PRINT("# messages: "); - STA_DEBUG_PRINTLN(gCanRx.stats().messages); - STA_DEBUG_PRINT("# blocks: "); - STA_DEBUG_PRINTLN(gCanRx.stats().blocks); - STA_DEBUG_PRINT("# frames: "); - STA_DEBUG_PRINTLN(gCanRx.stats().frames); - STA_DEBUG_PRINT("# timeouts: "); - STA_DEBUG_PRINTLN(gCanRx.stats().timeouts); - STA_DEBUG_PRINT("# flow control errors: "); - STA_DEBUG_PRINTLN(gCanRx.stats().flowErrors); - STA_DEBUG_PRINT("# overflows: "); - STA_DEBUG_PRINTLN(gCanRx.stats().overflows); - STA_DEBUG_PRINTLN(); - } - - /** * @brief Output CAN frame ID to UART. * @@ -200,213 +189,357 @@ namespace debug } // namespace debug -namespace demo +namespace dummy { - extern void handleRxMessage(const uint8_t * buffer, uint16_t size); -} // namespace demo - - -/** - * @brief Process received ISOTP messages. - * - * @param msg ISOTP message - */ -void handleRxMessage(const sta::IsotpMessage & msg) -{ - STA_DEBUG_PRINTLN("[event] RX message"); - - debug::printFrameID(msg.frameID); - - // TODO Forward message to other threads - demo::handleRxMessage(msg.buffer, msg.size); -} - - -/** - * @brief Handle received data message CAN frames. - * - * @param header CAN frame header - * @param payload Payload buffer - */ -void receiveDataCallback(const sta::CanRxHeader & header, const uint8_t * payload) -{ - // Write frame payload to DebugSerial - STA_DEBUG_PRINTLN("[event] RX data frame"); - debug::printPayloadHex(payload, header.payloadLength); - - // Process RX frame - auto handle = gCanRx.processFrame(header, payload); - - if (handle != sta::IsotpReceiver::INVALID_HANDLE) + void handleSysMessage(const sta::CanRxHeader & header, const uint8_t * payload) { - // Get message if completed - sta::IsotpMessage msg; - if (gCanRx.getMessage(handle, &msg)) - { - handleRxMessage(msg); - } + // Write frame payload to DebugSerial + STA_DEBUG_PRINTLN("[event] RX sys frame"); - // Handle FC responses - gCanRx.processFC(handle); + debug::printFrameID(header.id); + debug::printPayloadHex(payload, header.payloadLength); + + // TODO Forward message to other threads } - // Process TX frame - gCanTx.processFrame(header, payload); -} - -/** - * @brief Handle received system message CAN frames. - * - * @param header CAN frame header - * @param payload Payload buffer - */ -void receiveSysCallback(const sta::CanRxHeader & header, const uint8_t * payload) -{ - // Write frame payload to DebugSerial - STA_DEBUG_PRINTLN("[event] RX sys frame"); - - debug::printFrameID(header.id); - debug::printPayloadHex(payload, header.payloadLength); - - // TODO Forward message to other threads -} - - -/** - * @brief Configure CAN filters. - */ -void setupCanSubscriptions() -{ - // Make sure to receive all messages - CanFilter filter; - - // Clear previous subscriptions - rtos::CanBusController->clearFilters(); - - - // All bits except [0:1] of the SID must be zero for system messages - filter.obj = {0, 0}; - filter.mask = {~STA_CAN_SID_SYS_BITS, 0}; - filter.type = sta::CanFilterIdFormat::ANY; - filter.fifo = 0; - - filterCallbacks[0] = receiveSysCallback; - rtos::CanBusController->configureFilter(0, filter, true); - - - // TODO Limit which data messages are received - // Bits [0:1] of the SID must be zero for data messages - filter.obj = {0, 0}; - filter.mask = {STA_CAN_SID_SYS_BITS, 0}; - filter.type = sta::CanFilterIdFormat::ANY; - filter.fifo = 1; - filterCallbacks[1] = receiveDataCallback; - rtos::CanBusController->configureFilter(1, filter, true); -} - - -/** - * @brief Process received CAN messages. - */ -void processMessages() -{ - for (auto fifo : rtos::CanBusController->getPendingRxFifos()) + void handleDataMessage(const sta::IsotpMessage & msg) { - CanRxHeader header; - uint8_t payload[STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE]; + STA_ASSERT(msg.buffer != nullptr); + STA_ASSERT(msg.size != 0); - if (rtos::CanBusController->receiveFrame(fifo, &header, payload)) + STA_DEBUG_PRINTLN("[event] RX data message"); + + debug::printFrameID(msg.frameID); + + // TODO Forward message to other threads + +// if (buffer[0] == DEMO_BMP_PACKET_ID) +// { +// BmpPacket packet; +// if (unpack(buffer + 1, size - 1, &packet)) +// { +// STA_DEBUG_PRINTLN(); +// STA_DEBUG_PRINTLN("# ############"); +// STA_DEBUG_PRINTLN("# ## BMP380 ##"); +// STA_DEBUG_PRINTLN("# ############"); +// STA_DEBUG_PRINTLN("#"); +// +// STA_DEBUG_PRINT("# temperature: "); +// STA_DEBUG_PRINT(packet.temperature); +// STA_DEBUG_PRINTLN(" *C"); +// STA_DEBUG_PRINT("# pressure: "); +// STA_DEBUG_PRINT(packet.pressure); +// STA_DEBUG_PRINTLN(" Pa"); +// STA_DEBUG_PRINT("# altitude: "); +// STA_DEBUG_PRINT(packet.altitude); +// STA_DEBUG_PRINTLN(" m"); +// STA_DEBUG_PRINTLN(); +// } +// else +// { +// STA_DEBUG_PRINTLN("[error] BMP unpack failed"); +// } +// } +// else { -// debug::displayFrameUART(frame); + STA_DEBUG_PRINT("ID: "); + STA_DEBUG_PRINTLN(msg.buffer[0], sta::IntegerBase::HEX); + STA_DEBUG_PRINT("size: "); + STA_DEBUG_PRINTLN(msg.size); + } + } +} // namespace dummy - // Forward frame to filter callback - if (fifo <= STA_RTOS_CAN_BUS_MAX_FILTER && filterCallbacks[header.filter]) + + +namespace sta +{ + class AlpakaCanBus + { + public: + using SysMsgHandler = void (*)(const CanRxHeader &, const uint8_t *); + using DataMsgHandler = void (*)(const IsotpMessage &); + + static const uint8_t FIFO_SYS = 0; + static const uint8_t FIFO_DATA = 1; + + public: + AlpakaCanBus(CanController * controller, TimeMsFn timeMs, SysMsgHandler sysMsgHandler, DataMsgHandler dataMsgHandler); + + + /** + * @brief Send system message. + * + * @param msg Message + */ + void send(const CanSysMsg & msg); + + /** + * @brief Send data message. + * + * @param msg Message + */ + void send(const CanDataMsg & msg); + + + /** + * @brief Process transmissions. + * + * Call regularly to advance transmission. + */ + void processTx(); + + /** + * @brief Process received CAN messages. + */ + void processRx(); + + /** + * @brief Display ISOTP TX/RX statistics. + */ + void showStatistics(); + + private: + /** + * @brief Configure CAN filters. + */ + void setupSubscriptions(); + + /** + * @brief Handle received data message CAN frames. + * + * @param header CAN frame header + * @param payload Payload buffer + */ + void receiveDataFrame(const CanRxHeader & header, const uint8_t * payload); + + private: + CanController * controller_; + IsotpTransmitter tx_; + IsotpReceiver rx_; + SysMsgHandler handleSysMsg_; + DataMsgHandler handleDataMsg_; + }; + + + AlpakaCanBus::AlpakaCanBus(CanController * controller, TimeMsFn timeMs, SysMsgHandler sysMsgHandler, DataMsgHandler dataMsgHandler) + : controller_{controller}, tx_{controller, timeMs}, rx_{controller, timeMs}, handleSysMsg_{sysMsgHandler}, handleDataMsg_{dataMsgHandler} + { + STA_ASSERT(handleSysMsg_ != nullptr); + STA_ASSERT(handleDataMsg_ != nullptr); + + setupSubscriptions(); + } + + + void AlpakaCanBus::send(const CanSysMsg & msg) + { + CanTxHeader header; + header.id.format = static_cast(msg.header.format); + header.id.sid = msg.header.sid & STA_CAN_SID_SYS_BITS; + header.id.eid = msg.header.eid; + header.payloadLength = msg.header.payloadLength; + + controller_->sendFrame(header, msg.payload); + } + + void AlpakaCanBus::send(const CanDataMsg & msg) + { + CanFrameId frameID; + frameID.format = static_cast(msg.header.format); + frameID.sid = msg.header.sid & ~STA_CAN_SID_SYS_BITS; + frameID.eid = msg.header.eid; + + // Start transmission via ISO-TP + tx_.send(frameID, msg.payload, msg.header.payloadLength); + } + + + inline void AlpakaCanBus::processTx() + { + tx_.process(); + } + + + void AlpakaCanBus::processRx() + { + for (auto fifo : controller_->getPendingRxFifos()) + { + CanRxHeader header; + uint8_t payload[STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE]; + + if (controller_->receiveFrame(fifo, &header, payload)) { - filterCallbacks[header.filter](header, payload); +// debug::displayFrameUART(frame); + + // Forward frame to callback + switch (fifo) + { + case FIFO_SYS: + handleSysMsg_(header, payload); + break; + + case FIFO_DATA: + receiveDataFrame(header, payload); + break; + + default: + STA_ASSERT(false); + } } } } -} - -extern "C" -{ - /** - * @brief CAN driver thread entry function. - */ - void canBusTask(void *) + void AlpakaCanBus::showStatistics() { - using namespace sta; + STA_DEBUG_PRINTLN(); + STA_DEBUG_PRINTLN("# ######################"); + STA_DEBUG_PRINTLN("# ## ISOTP statistics ##"); + STA_DEBUG_PRINTLN("# ######################"); + STA_DEBUG_PRINTLN("#"); - // Initialize CAN controller - rtos::setupCanBus(); + const auto & txStats = tx_.stats(); + STA_DEBUG_PRINTLN("# Transmitter"); + STA_DEBUG_PRINT("# messages: "); + STA_DEBUG_PRINTLN(txStats.messages); + STA_DEBUG_PRINT("# blocks: "); + STA_DEBUG_PRINTLN(txStats.blocks); + STA_DEBUG_PRINT("# frames: "); + STA_DEBUG_PRINTLN(txStats.frames); + STA_DEBUG_PRINT("# timeouts: "); + STA_DEBUG_PRINTLN(txStats.timeouts); + STA_DEBUG_PRINTLN("#"); - // Configure filters for - setupCanSubscriptions(); + const auto & rxStats = rx_.stats(); + STA_DEBUG_PRINTLN("# Receiver"); + STA_DEBUG_PRINT("# messages: "); + STA_DEBUG_PRINTLN(rxStats.messages); + STA_DEBUG_PRINT("# blocks: "); + STA_DEBUG_PRINTLN(rxStats.blocks); + STA_DEBUG_PRINT("# frames: "); + STA_DEBUG_PRINTLN(rxStats.frames); + STA_DEBUG_PRINT("# timeouts: "); + STA_DEBUG_PRINTLN(rxStats.timeouts); + STA_DEBUG_PRINT("# flow control errors: "); + STA_DEBUG_PRINTLN(rxStats.flowErrors); + STA_DEBUG_PRINT("# overflows: "); + STA_DEBUG_PRINTLN(rxStats.overflows); + STA_DEBUG_PRINTLN(); + } - rtos::waitForStartupEvent(); + void AlpakaCanBus::setupSubscriptions() + { + // Make sure to receive all messages + CanFilter filter; - while (true) + // Clear previous subscriptions + controller_->clearFilters(); + + + // All bits except [0:1] of the SID must be zero for system messages + filter.obj = {0, 0}; + filter.mask = {~STA_CAN_SID_SYS_BITS, 0}; + filter.type = sta::CanFilterIdFormat::ANY; + filter.fifo = FIFO_SYS; + controller_->configureFilter(FIFO_SYS, filter, true); + + // TODO Limit which data messages are received + // Bits [0:1] of the SID must be zero for data messages + filter.obj = {0, 0}; + filter.mask = {STA_CAN_SID_SYS_BITS, 0}; + filter.type = sta::CanFilterIdFormat::ANY; + filter.fifo = FIFO_DATA; + controller_->configureFilter(FIFO_DATA, filter, true); + } + + void AlpakaCanBus::receiveDataFrame(const CanRxHeader & header, const uint8_t * payload) + { + // Write frame payload to DebugSerial + STA_DEBUG_PRINTLN("[event] RX data frame"); + debug::printPayloadHex(payload, header.payloadLength); + + // Process RX frame + auto handle = rx_.processFrame(header, payload); + + if (handle != IsotpReceiver::INVALID_HANDLE) { - uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, 50); - - if (flags != static_cast(osErrorTimeout)) + // Get message if completed + IsotpMessage msg; + if (rx_.getMessage(handle, &msg)) { - STA_ASSERT_MSG((flags & osStatusReserved) == flags, "Unexpected error occurred in wait"); + handleDataMsg_(msg); + } - if (flags & STA_RTOS_CAN_FLAG_SYS_QUEUED) + // Handle FC responses + rx_.processFC(handle); + } + + // Process TX frame + tx_.processFrame(header, payload); + } +} // namespace sta + + + +/** + * @brief CAN driver thread entry function. + */ +void canBusTask(void *) +{ + using namespace sta; + + STA_ASSERT_MSG(canBusController != nullptr, "System CAN bus not initialized"); + + // Setup ISO-TP transceiver + AlpakaCanBus canBus(canBusController, HAL_GetTick, dummy::handleSysMessage, dummy::handleDataMessage); + + + rtos::waitForStartupEvent(); + + while (true) + { + uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, 50); + + if (flags != static_cast(osErrorTimeout)) + { + STA_ASSERT_MSG((flags & osStatusReserved) == flags, "Unexpected error occurred in wait"); + + if (flags & STA_RTOS_CAN_FLAG_SYS_QUEUED) + { + // Take messages from queue until empty + CanSysMsg msg; + while (rtos::getCanBusMsg(&msg, 0)) { - CanSysMsg msg; - CanTxHeader header; - - // Take messages from queue until empty - while (rtos::getCanBusMsg(&msg, 0)) - { - header.id.format = static_cast(msg.header.format); - header.id.sid = msg.header.sid & STA_CAN_SID_SYS_BITS; - header.id.eid = msg.header.eid; - header.payloadLength = msg.header.payloadLength; - - debug::printPayloadHex(msg.payload, header.payloadLength); - - rtos::CanBusController->sendFrame(header, msg.payload); - } - } - - if (flags & STA_RTOS_CAN_FLAG_DATA_QUEUED) - { - CanDataMsg msg; - CanFrameId frameID; - - // Take messages from queue until empty - while (rtos::getCanBusMsg(&msg, 0)) - { - frameID.format = static_cast(msg.header.format); - frameID.sid = msg.header.sid & ~STA_CAN_SID_SYS_BITS; - frameID.eid = msg.header.eid; - - // Transmit via ISO-TP - gCanTx.send(frameID, msg.payload, msg.header.payloadLength); - } - } - - if (flags & STA_RTOS_CAN_FLAG_MSG_AVAIL) - { - STA_DEBUG_PRINTLN("[event] CAN INT"); - - processMessages(); - } - - if (flags & STA_RTOS_CAN_FLAG_SHOW_STATS) - { - debug::showStatistics(); + canBus.send(msg); } } - // Process ISOTP transmissions - gCanTx.process(); + if (flags & STA_RTOS_CAN_FLAG_DATA_QUEUED) + { + // Take messages from queue until empty + CanDataMsg msg; + while (rtos::getCanBusMsg(&msg, 0)) + { + canBus.send(msg); + } + } + + if (flags & STA_RTOS_CAN_FLAG_MSG_AVAIL) + { + STA_DEBUG_PRINTLN("[event] CAN INT"); + + canBus.processRx(); + } + + if (flags & STA_RTOS_CAN_FLAG_SHOW_STATS) + { + canBus.showStatistics(); + } } + + // Process ISOTP transmissions + canBus.processTx(); } } From cccf24ae5963c0b3ff5c615d17cf049b96a6e313 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 22:33:27 +0100 Subject: [PATCH 14/26] Move C API to separate folder --- include/sta/rtos/{system => c_api}/can_msg.h | 6 +++--- include/sta/rtos/c_api/startup.h | 22 ++++++++++++++++++++ include/sta/rtos/system/can_bus.hpp | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) rename include/sta/rtos/{system => c_api}/can_msg.h (89%) create mode 100644 include/sta/rtos/c_api/startup.h diff --git a/include/sta/rtos/system/can_msg.h b/include/sta/rtos/c_api/can_msg.h similarity index 89% rename from include/sta/rtos/system/can_msg.h rename to include/sta/rtos/c_api/can_msg.h index 617da19..814ff27 100644 --- a/include/sta/rtos/system/can_msg.h +++ b/include/sta/rtos/c_api/can_msg.h @@ -2,8 +2,8 @@ * @file * @brief CAN driver message request types for use in C code. */ -#ifndef STA_RTOS_SYSTEM_CAN_MSG_H -#define STA_RTOS_SYSTEM_CAN_MSG_H +#ifndef STA_RTOS_C_API_CAN_MSG_H +#define STA_RTOS_C_API_CAN_MSG_H #include @@ -46,4 +46,4 @@ struct CanSysMsg }; -#endif // STA_RTOS_SYSTEM_CAN_MSG_H +#endif // STA_RTOS_C_API_CAN_MSG_H diff --git a/include/sta/rtos/c_api/startup.h b/include/sta/rtos/c_api/startup.h new file mode 100644 index 0000000..220436b --- /dev/null +++ b/include/sta/rtos/c_api/startup.h @@ -0,0 +1,22 @@ +#ifndef STA_RTOS_C_API_STARTUP_H +#define STA_RTOS_C_API_STARTUP_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief + * + * @param arg Default task argument + */ +void startALPAKA(void * arg); + + +#ifdef __cplusplus +} +#endif + + +#endif // STA_RTOS_C_API_STARTUP_H diff --git a/include/sta/rtos/system/can_bus.hpp b/include/sta/rtos/system/can_bus.hpp index 63bd4fd..7a95306 100644 --- a/include/sta/rtos/system/can_bus.hpp +++ b/include/sta/rtos/system/can_bus.hpp @@ -29,7 +29,7 @@ #include -#include +#include #include From aeb472fd03451da304a019d200f1e2c1b23e72ca Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 22:34:26 +0100 Subject: [PATCH 15/26] Simplify startup API --- include/sta/rtos/system/startup.hpp | 39 ------------------- src/system/startup.cpp | 60 ++++++++++++++++++----------- 2 files changed, 38 insertions(+), 61 deletions(-) diff --git a/include/sta/rtos/system/startup.hpp b/include/sta/rtos/system/startup.hpp index d34d43a..f3a2e46 100644 --- a/include/sta/rtos/system/startup.hpp +++ b/include/sta/rtos/system/startup.hpp @@ -5,8 +5,6 @@ #ifndef STA_RTOS_SYSTEM_STARTUP_HPP #define STA_RTOS_SYSTEM_STARTUP_HPP -#include - /** * @defgroup STA_RTOS_Startup Startup task @@ -17,41 +15,6 @@ */ -#ifdef DOXYGEN -/** - * @brief Enable module. - * - * @ingroup STA_RTOS_BuildConfig - */ -# define STA_RTOS_STARTUP_ENABLE -#endif // DOXYGEN - - -/** - * @def STA_RTOS_STARTUP_TASK_NAME - * @brief Set name of startup task. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_STARTUP_TASK_NAME -# define STA_RTOS_STARTUP_TASK_NAME startup -#endif // !STA_RTOS_STARTUP_TASK_NAME - -/** - * @def STA_RTOS_STARTUP_ENTRY_FUNCTION - * @brief Set name of startup task entry function. - * - * @ingroup STA_RTOS_BuildConfig - */ -#ifndef STA_RTOS_STARTUP_ENTRY_FUNCTION -# define STA_RTOS_STARTUP_ENTRY_FUNCTION STA_RTOS_MAKE_ENTRY_NAME(STA_RTOS_STARTUP_TASK_NAME) -#endif // !STA_RTOS_STARTUP_ENTRY_FUNCTION - - -#include -#ifdef STA_RTOS_STARTUP_ENABLE - - namespace sta { namespace rtos @@ -68,6 +31,4 @@ namespace sta } // namespace sta -#endif // STA_RTOS_STARTUP_ENABLE - #endif // STA_RTOS_SYSTEM_STARTUP_HPP diff --git a/src/system/startup.cpp b/src/system/startup.cpp index 9e31530..4308fdb 100644 --- a/src/system/startup.cpp +++ b/src/system/startup.cpp @@ -1,7 +1,10 @@ #include -#ifdef STA_RTOS_STARTUP_ENABLE +#include + +#include #include +#include #include #include #include @@ -17,33 +20,46 @@ namespace sta STA_WEAK void startupExtras(void *) {} + + + void initSystem() + { +#ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE + initSystemEvents(); +#endif // STA_RTOS_SYSTEM_EVENTS_ENABLE + +#ifdef STA_RTOS_WATCHDOG_ENABLE + initWatchdog(); +#endif // STA_RTOS_WATCHDOG_ENABLE + +#ifdef STA_RTOS_CAN_BUS_ENABLE + initCanBus(); +#endif // STA_RTOS_CAN_BUS_ENABLE + } } // namespace rtos } // namespace sta -// Declare with C linkage -extern "C" +void startALPAKA(void * arg) { - void STA_RTOS_STARTUP_ENTRY_FUNCTION(void * arg) + STA_ASSERT_MSG(osKernelGetState() != osKernelInactive, "Cannot call startALPAKA() before osKernelInitialize()"); + + // Call further initialization code + sta::rtos::startupExtras(arg); + + // Initialize HAL + sta::initHAL(); + + // Initialize RTOS system resources + sta::rtos::initSystem(); + + // Wake threads + sta::rtos::signalStartupEvent(); + + // Check if called from thread + if (osThreadGetId() != nullptr) { - // Call further initialization code - sta::rtos::startupExtras(arg); - - // Initialize HAL - sta::initHAL(); - -#ifdef STA_RTOS_WATCHDOG_ENABLE - // Start timers - sta::rtos::startWatchdogTimer(); -#endif // STA_RTOS_WATCHDOG_ENABLE - - // Wake threads - sta::rtos::signalStartupEvent(); - - // Terminate thread + // Terminate current thread osThreadExit(); } } - - -#endif // STA_RTOS_STARTUP_ENABLE From 600b2d01c786fc51814db9ac47fea7ab9862306c Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 22:37:51 +0100 Subject: [PATCH 16/26] Rename system events files --- include/sta/rtos/system/{system_event.hpp => system_events.hpp} | 0 src/system/can_bus.cpp | 2 +- src/system/startup.cpp | 2 +- src/system/{system_event.cpp => system_events.cpp} | 2 +- src/system/watchdog.cpp | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename include/sta/rtos/system/{system_event.hpp => system_events.hpp} (100%) rename src/system/{system_event.cpp => system_events.cpp} (96%) diff --git a/include/sta/rtos/system/system_event.hpp b/include/sta/rtos/system/system_events.hpp similarity index 100% rename from include/sta/rtos/system/system_event.hpp rename to include/sta/rtos/system/system_events.hpp diff --git a/src/system/can_bus.cpp b/src/system/can_bus.cpp index c75412d..e240e6d 100644 --- a/src/system/can_bus.cpp +++ b/src/system/can_bus.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/system/startup.cpp b/src/system/startup.cpp index 4308fdb..47ca3a9 100644 --- a/src/system/startup.cpp +++ b/src/system/startup.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/system/system_event.cpp b/src/system/system_events.cpp similarity index 96% rename from src/system/system_event.cpp rename to src/system/system_events.cpp index caf89ab..3e02ece 100644 --- a/src/system/system_event.cpp +++ b/src/system/system_events.cpp @@ -1,4 +1,4 @@ -#include +#include #ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE #include diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index e93b148..0a109e4 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include From 2d516bd3189400098b2f8fad9a2028b8c759d556 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sat, 21 Jan 2023 23:38:53 +0100 Subject: [PATCH 17/26] Cleanup docs and unused files --- README.md | 39 +++++++++++------------ include/sta/rtos/easy_config.hpp | 33 +------------------ include/sta/rtos/system/names.hpp | 12 ------- include/sta/rtos/system/system_events.hpp | 4 +-- src/system/system_events.cpp | 4 +-- 5 files changed, 24 insertions(+), 68 deletions(-) delete mode 100644 include/sta/rtos/system/names.hpp diff --git a/README.md b/README.md index 53d8390..9951443 100644 --- a/README.md +++ b/README.md @@ -17,17 +17,15 @@ The library provides implementations for the following interfaces using CMSIS-RT # Modules -## System Event +## System Events Provides an interface for common system events. Configuration: -* `#define STA_RTOS_SYSTEM_EVENT_ENABLE`: Enable module -* `#define STA_RTOS_SYSTEM_EVENT_HANDLE `: Override variable name of flag handle (default: systemEventHandle) +* `#define STA_RTOS_SYSTEM_EVENTS_ENABLE`: Enable module - -Requirements: -* RTOS: event flag +When enabled a new global event flag will be created. Initialization will be handled by the Startup module +if enabled. ## Watchdog @@ -38,30 +36,33 @@ and forwards the event flags to the `sta::watchdogEventHandler` function impleme Configuration: * `#define STA_RTOS_WATCHDOG_ENABLE`: Enable module * `#define STA_RTOS_WATCHDOG_TIMER_PERIOD `: Set period in ticks of heartbeat timer (default: 1000) -* `#define STA_RTOS_WATCHDOG_TIMER_HANDLE `: Override variable name of heartbeat timer handle (default: heartbeatHandle) -* `#define STA_RTOS_WATCHDOG_TIMER_CALLBACK `: Override name of heartbeat timer callback function (default: heartbeatCallback) -* `#define STA_RTOS_WATCHDOG_HANDLE `: Override variable name of watchdog task handle (default: watchdogHandle) -* `#define STA_RTOS_WATCHDOG_ENTRY_FUNCTION `: Override name of watchdog task entry function (default: watchdogTask) Requirements: -* Uses the `System Event` module -* RTOS: timer + task +* `System Events` module + + +## Can Bus + +TODO Add description + +Configuration: + +Requirements: +* `System Events` module ## Startup -The entry function for the startup task must be called manually from the default task. +The `startALPAKA` function must be called from the default task. -It provides all setup required by the enabled system tasks. If additional initialization is required by the -application the function `void sta::startupExtras(void *)` declared in `` can be implemented. +It provides all setup required by the enabled system tasks. If additional initialization is required +the function `void sta::startupExtras(void *)` declared in `` can be implemented by the application. Configuration: * `#define STA_RTOS_STARTUP_ENABLE`: Enable module -* `#define STA_RTOS_STARTUP_ENTRY_FUNCTION `: Override name of startup task entry function (default: startupTask) Requirements: -* Uses the `System Event` module -* RTOS: task +* `System Events` module ## Easy Config @@ -70,5 +71,3 @@ Simplify configuration of modules. Intended for use in ``. Configuration: * `#define STA_RTOS_SYSTEM_TASKS_ENABLE`: Enable all modules required for system tasks -* `#define STA_RTOS_WATCHDOG_TIMER_NAME `: Override handle and callback name for watchdog timer -* `#define STA_RTOS_WATCHDOG_NAME `: Override handle and entry function name for watchdog task diff --git a/include/sta/rtos/easy_config.hpp b/include/sta/rtos/easy_config.hpp index 1ead253..afa135f 100644 --- a/include/sta/rtos/easy_config.hpp +++ b/include/sta/rtos/easy_config.hpp @@ -5,8 +5,6 @@ #ifndef STA_RTOS_EASY_CONFIG_HPP #define STA_RTOS_EASY_CONFIG_HPP -#include - /** * @defgroup STA_RTOS_EasyConfig Easy Config @@ -19,7 +17,7 @@ #ifdef DOXYGEN /** - * @brief Don't warn about use of outside of . + * @brief Don't warn about use of outside of . * * @ingroup STA_RTOS_EasyConfig */ @@ -50,33 +48,4 @@ #endif // STA_RTOS_EASY_CONFIG_SYSTEM_TASKS_ENABLE -#ifdef DOXYGEN -/** - * @brief Common base name used for watchdog timer handle and callback names. - * - * @ingroup STA_RTOS_EasyConfig - */ -# define STA_RTOS_EASY_CONFIG_WATCHDOG_TIMER_NAME -#endif // DOXYGEN - -#ifdef STA_RTOS_EASY_CONFIG_WATCHDOG_TIMER_NAME -# define STA_RTOS_WATCHDOG_TIMER_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_EASY_CONFIG_WATCHDOG_TIMER_NAME) -# define STA_RTOS_WATCHDOG_TIMER_CALLBACK STA_RTOS_MAKE_CALLBACK_NAME(STA_RTOS_EASY_CONFIG_WATCHDOG_TIMER_NAME) -#endif // STA_RTOS_EASY_CONFIG_WATCHDOG_TIMER_NAME - -#ifdef DOXYGEN -/** - * @brief Common base name used for watchdog task handle and entry function names. - * - * @ingroup STA_RTOS_EasyConfig - */ -# define STA_RTOS_EASY_CONFIG_WATCHDOG_NAME -#endif // DOXYGEN - -#ifdef STA_RTOS_EASY_CONFIG_WATCHDOG_NAME -# define STA_RTOS_WATCHDOG_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_EASY_CONFIG_WATCHDOG_NAME) -# define STA_RTOS_WATCHDOG_ENTRY_FUNCTION STA_RTOS_MAKE_TASK_NAME(STA_RTOS_EASY_CONFIG_WATCHDOG_NAME) -#endif // STA_RTOS_EASY_CONFIG_WATCHDOG_NAME - - #endif // STA_RTOS_EASY_CONFIG_HPP diff --git a/include/sta/rtos/system/names.hpp b/include/sta/rtos/system/names.hpp deleted file mode 100644 index d123dae..0000000 --- a/include/sta/rtos/system/names.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef STA_RTOS_SYSTEM_NAMES_HPP -#define STA_RTOS_SYSTEM_NAMES_HPP - - -#define _STA_RTOS_CONCAT(a, b) a ## b - -#define STA_RTOS_MAKE_HANDLE_NAME(name) _STA_RTOS_CONCAT(name, Handle) -#define STA_RTOS_MAKE_CALLBACK_NAME(name) _STA_RTOS_CONCAT(name, Callback) -#define STA_RTOS_MAKE_ENTRY_NAME(name) _STA_RTOS_CONCAT(name, Task) - - -#endif // STA_RTOS_SYSTEM_NAMES_HPP diff --git a/include/sta/rtos/system/system_events.hpp b/include/sta/rtos/system/system_events.hpp index 3018090..41d1542 100644 --- a/include/sta/rtos/system/system_events.hpp +++ b/include/sta/rtos/system/system_events.hpp @@ -20,7 +20,7 @@ * * @ingroup STA_RTOS_BuildConfig */ -# define STA_RTOS2_SYSTEM_EVENTS_ENABLE +# define STA_RTOS_SYSTEM_EVENTS_ENABLE #endif // DOXYGEN @@ -39,7 +39,7 @@ * * @ingroup STA_RTOS_SysEvent */ -#define STA_SYSTEM_EVENTS_STARTUP 0x100000U +#define STA_RTOS_SYSTEM_EVENTS_STARTUP 0x100000U namespace sta diff --git a/src/system/system_events.cpp b/src/system/system_events.cpp index 3e02ece..44a15c0 100644 --- a/src/system/system_events.cpp +++ b/src/system/system_events.cpp @@ -51,12 +51,12 @@ namespace sta void signalStartupEvent() { - signalSystemEvents(STA_SYSTEM_EVENTS_STARTUP); + signalSystemEvents(STA_RTOS_SYSTEM_EVENTS_STARTUP); } void waitForStartupEvent() { - waitForSystemEvents(STA_SYSTEM_EVENTS_STARTUP, osFlagsWaitAll, osWaitForever); + waitForSystemEvents(STA_RTOS_SYSTEM_EVENTS_STARTUP, osFlagsWaitAll, osWaitForever); } } // namespace rtos } // namespace sta From 6b0f4dd84b309d92ff64cea67c9ee12cdf3e2a16 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sun, 22 Jan 2023 00:05:51 +0100 Subject: [PATCH 18/26] Rename system_events to events --- .../system/{system_events.hpp => events.hpp} | 21 +++---------------- src/system/can_bus.cpp | 2 +- src/system/{system_events.cpp => events.cpp} | 6 +----- src/system/startup.cpp | 2 +- src/system/watchdog.cpp | 2 +- 5 files changed, 7 insertions(+), 26 deletions(-) rename include/sta/rtos/system/{system_events.hpp => events.hpp} (78%) rename src/system/{system_events.cpp => events.cpp} (91%) diff --git a/include/sta/rtos/system/system_events.hpp b/include/sta/rtos/system/events.hpp similarity index 78% rename from include/sta/rtos/system/system_events.hpp rename to include/sta/rtos/system/events.hpp index 41d1542..603beb6 100644 --- a/include/sta/rtos/system/system_events.hpp +++ b/include/sta/rtos/system/events.hpp @@ -2,8 +2,8 @@ * @file * @brief Implementation of system events. */ -#ifndef STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP -#define STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP +#ifndef STA_RTOS_SYSTEM_EVENTS_HPP +#define STA_RTOS_SYSTEM_EVENTS_HPP /** @@ -14,19 +14,6 @@ * Check @ref STA_RTOS_BuildConfig for configuration options. */ -#ifdef DOXYGEN -/** - * @brief Enable module. - * - * @ingroup STA_RTOS_BuildConfig - */ -# define STA_RTOS_SYSTEM_EVENTS_ENABLE -#endif // DOXYGEN - - -#include -#ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE - #include @@ -92,6 +79,4 @@ namespace sta } // namespace sta -#endif // STA_RTOS_SYSTEM_EVENTS_ENABLE - -#endif // STA_RTOS_SYSTEM_SYSTEM_EVENTS_HPP +#endif // STA_RTOS_SYSTEM_EVENTS_HPP diff --git a/src/system/can_bus.cpp b/src/system/can_bus.cpp index e240e6d..b1f06cf 100644 --- a/src/system/can_bus.cpp +++ b/src/system/can_bus.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/system/system_events.cpp b/src/system/events.cpp similarity index 91% rename from src/system/system_events.cpp rename to src/system/events.cpp index 44a15c0..4bbd808 100644 --- a/src/system/system_events.cpp +++ b/src/system/events.cpp @@ -1,5 +1,4 @@ -#include -#ifdef STA_RTOS_SYSTEM_EVENTS_ENABLE +#include #include @@ -60,6 +59,3 @@ namespace sta } } // namespace rtos } // namespace sta - - -#endif // STA_RTOS_SYSTEM_EVENTS_ENABLE diff --git a/src/system/startup.cpp b/src/system/startup.cpp index 47ca3a9..dc48014 100644 --- a/src/system/startup.cpp +++ b/src/system/startup.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index 0a109e4..a487d9a 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include From e4835cc57d0d24c642874730c05583bfb0ebd5cb Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sun, 22 Jan 2023 00:06:29 +0100 Subject: [PATCH 19/26] Rename WATCHDOG macros to SYSTEM_WATCHDOG --- include/sta/rtos/system/watchdog.hpp | 14 +++++++------- src/system/watchdog.cpp | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/sta/rtos/system/watchdog.hpp b/include/sta/rtos/system/watchdog.hpp index 3a414d7..f7f2def 100644 --- a/include/sta/rtos/system/watchdog.hpp +++ b/include/sta/rtos/system/watchdog.hpp @@ -20,23 +20,23 @@ * * @ingroup STA_RTOS_BuildConfig */ -# define STA_RTOS_WATCHDOG_ENABLE +# define STA_RTOS_SYSTEM_WATCHDOG_ENABLE #endif // DOXYGEN /** - * @def STA_RTOS_WATCHDOG_TIMER_PERIOD + * @def STA_RTOS_SYSTEM_WATCHDOG_TIMER_PERIOD * @brief Set period in ticks of heartbeat timer. * * @ingroup STA_RTOS_BuildConfig */ -#ifndef STA_RTOS_WATCHDOG_TIMER_PERIOD -# define STA_RTOS_WATCHDOG_TIMER_PERIOD 1000 -#endif // !STA_RTOS_WATCHDOG_TIMER_PERIOD +#ifndef STA_RTOS_SYSTEM_WATCHDOG_TIMER_PERIOD +# define STA_RTOS_SYSTEM_WATCHDOG_TIMER_PERIOD 1000 +#endif // !STA_RTOS_SYSTEM_WATCHDOG_TIMER_PERIOD #include -#ifdef STA_RTOS_WATCHDOG_ENABLE +#ifdef STA_RTOS_SYSTEM_WATCHDOG_ENABLE #include @@ -87,6 +87,6 @@ namespace sta } // namespace sta -#endif // STA_RTOS_WATCHDOG_ENABLE +#endif // STA_RTOS_SYSTEM_WATCHDOG_ENABLE #endif // STA_RTOS_SYSTEM_WATCHDOG_HPP diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index a487d9a..2cdac7c 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -1,5 +1,5 @@ #include -#ifdef STA_RTOS_WATCHDOG_ENABLE +#ifdef STA_RTOS_SYSTEM_WATCHDOG_ENABLE #include #include @@ -60,7 +60,7 @@ namespace sta watchdogTimerHandle = osTimerNew(watchdogTimerCallback, osTimerPeriodic, nullptr, &timerAttributes); STA_ASSERT_MSG(watchdogTimerHandle != nullptr, "System watchdog timer initialization failed"); - osTimerStart(watchdogTimerHandle, STA_RTOS_WATCHDOG_TIMER_PERIOD); + osTimerStart(watchdogTimerHandle, STA_RTOS_SYSTEM_WATCHDOG_TIMER_PERIOD); } @@ -100,4 +100,4 @@ void watchdogTimerCallback(void *) -#endif // STA_RTOS_WATCHDOG_ENABLE +#endif // STA_RTOS_SYSTEM_WATCHDOG_ENABLE From aa1b46f3ed33c35901bc36cb8e47e7ac8ca75dfc Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sun, 22 Jan 2023 00:08:13 +0100 Subject: [PATCH 20/26] Remove unnecessary easy_config header --- include/sta/rtos/easy_config.hpp | 51 -------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 include/sta/rtos/easy_config.hpp diff --git a/include/sta/rtos/easy_config.hpp b/include/sta/rtos/easy_config.hpp deleted file mode 100644 index afa135f..0000000 --- a/include/sta/rtos/easy_config.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * @brief Helper for easy system task setup in ``. - */ -#ifndef STA_RTOS_EASY_CONFIG_HPP -#define STA_RTOS_EASY_CONFIG_HPP - - -/** - * @defgroup STA_RTOS_EasyConfig Easy Config - * @ingroup STA_RTOS_BuildConfig - * @brief Helpers for easy RTOS module setup. - * - * Use this header only inside the header of your application. - */ - - -#ifdef DOXYGEN -/** - * @brief Don't warn about use of outside of . - * - * @ingroup STA_RTOS_EasyConfig - */ -# define STA_RTOS_EASY_CONFIG_NO_WARNING -#endif // DOXYGEN - -#if !defined(STA_CONFIG_HPP) && !defined(STA_RTOS_EASY_CONFIG_NO_WARNING) -#warning "Intended for use in " -#endif // !STA_CONFIG_HPP && !STA_RTOS_EASY_CONFIG_NO_WARNING - - -#ifdef DOXYGEN -/** - * @brief Enable all system tasks and required features. - * - * @ingroup STA_RTOS_EasyConfig - */ -# define STA_RTOS_EASY_CONFIG_SYSTEM_TASKS_ENABLE -#endif // DOXYGEN - -#ifdef STA_RTOS_EASY_CONFIG_SYSTEM_TASKS_ENABLE -// Enable system events used by system tasks -# define STA_RTOS_SYSTEM_EVENT_ENABLE -// Enable system tasks -# define STA_RTOS_CAN_BUS_ENABLE -# define STA_RTOS_STARTUP_ENABLE -# define STA_RTOS_WATCHDOG_ENABLE -#endif // STA_RTOS_EASY_CONFIG_SYSTEM_TASKS_ENABLE - - -#endif // STA_RTOS_EASY_CONFIG_HPP From cff89bc2e4871d1fbca47bef1a112a97a2f36939 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sun, 22 Jan 2023 00:08:47 +0100 Subject: [PATCH 21/26] Update README --- README.md | 67 ++++++++++++++-------------------------------------- library.json | 2 +- 2 files changed, 19 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 9951443..2e6d246 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,21 @@ # STA RTOS Utilities -![pre-release v0.1.0](https://img.shields.io/static/v1?label=pre-release&message=v0.1.0&color=orange&logo=git) +![pre-release v1.0.0](https://img.shields.io/static/v1?label=pre-release&message=v1.0.0&color=orange&logo=git) ![Standard: C++11](https://img.shields.io/static/v1?label=standard&message=C%2B%2B11&color=blue&logo=cplusplus) -Library using CMSIS-RTOS2 functionality for RTOS projects. +Library providing the software stack for use with the ALPAKA hardware design for RTOS projects. -Modules are enabled via defines set in `` header which must be provided by the application. +Modules can be configured via defines set in `` header file which must be provided by the application. -# Interface implementations +# ALPAKA Modules -The library provides implementations for the following interfaces using CMSIS-RTOS2 functionality: -* `Mutex` -* `Signal` +All enabled modules are initialized by calling the `startALPAKA` function from the default task. - -# Modules - -## System Events - -Provides an interface for common system events. - -Configuration: -* `#define STA_RTOS_SYSTEM_EVENTS_ENABLE`: Enable module - -When enabled a new global event flag will be created. Initialization will be handled by the Startup module -if enabled. - - -## Watchdog - -The watchdog task waits for signals sent either from the heartbeat timer or manually via `sta::notifyWatchdog` -and forwards the event flags to the `sta::watchdogEventHandler` function implemented by the application. - -Configuration: -* `#define STA_RTOS_WATCHDOG_ENABLE`: Enable module -* `#define STA_RTOS_WATCHDOG_TIMER_PERIOD `: Set period in ticks of heartbeat timer (default: 1000) - -Requirements: -* `System Events` module +The function `startupExtras` is called before any module initialization and can be used by the application +to execute additional initialization steps before any task waiting for the startup system event will run. +The function prototype can be found in the `` header and can optionally be implemented +anywhere in the application code. ## Can Bus @@ -47,27 +24,19 @@ TODO Add description Configuration: -Requirements: -* `System Events` module +## Watchdog -## Startup - -The `startALPAKA` function must be called from the default task. - -It provides all setup required by the enabled system tasks. If additional initialization is required -the function `void sta::startupExtras(void *)` declared in `` can be implemented by the application. +The watchdog task waits for signals sent either from its heartbeat timer or manually via `sta::notifyWatchdog` +and passes the event flags to the `sta::watchdogEventHandler` function. This function must be implemented by the application. Configuration: -* `#define STA_RTOS_STARTUP_ENABLE`: Enable module - -Requirements: -* `System Events` module +* `#define STA_RTOS_WATCHDOG_ENABLE`: Enable module +* `#define STA_RTOS_WATCHDOG_TIMER_PERIOD `: Set period in ticks of heartbeat timer (default: 1000) -## Easy Config +# STA-Core Interfaces -Simplify configuration of modules. Intended for use in ``. - -Configuration: -* `#define STA_RTOS_SYSTEM_TASKS_ENABLE`: Enable all modules required for system tasks +The library provides implementations for the following interfaces using CMSIS-RTOS2 functionality: +* `Mutex` +* `Signal` diff --git a/library.json b/library.json index b640cd8..5ce2c3a 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "owner" : "sta", "name": "sta-rtos", - "version": "0.1.0", + "version": "1.0.0", "dependencies": [ { "url": "git@gitlab.com:sta-git/alpaka/sta-core.git", From 652aea896f0372a4831788f6cd152c1459e3a15f Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Sun, 22 Jan 2023 00:10:42 +0100 Subject: [PATCH 22/26] Require watchdogEventHandler impl from user --- src/system/watchdog.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index 2cdac7c..32ebd65 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -69,9 +69,6 @@ namespace sta STA_ASSERT_MSG(watchdogTaskHandle != nullptr, "System watchdog not initialized"); osThreadFlagsSet(watchdogTaskHandle, flags); } - - STA_WEAK void watchdogEventHandler(void * arg, uint32_t flags) - {} } // namespace rtos } // namespace sta From ad6c4fd297865cb697037052d3b354b6d2405fe1 Mon Sep 17 00:00:00 2001 From: dario Date: Wed, 30 Aug 2023 21:13:35 +0200 Subject: [PATCH 23/26] Adapted include paths to latest sta-core changes --- include/sta/rtos/handle.tpp | 2 +- src/system/events.cpp | 2 +- src/system/startup.cpp | 4 ++-- src/system/watchdog.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/sta/rtos/handle.tpp b/include/sta/rtos/handle.tpp index 6c6927c..cd10f3e 100644 --- a/include/sta/rtos/handle.tpp +++ b/include/sta/rtos/handle.tpp @@ -5,7 +5,7 @@ # error "Internal header. Use instead." #endif // !STA_RTOS_HANDLE_HPP -#include +#include namespace sta diff --git a/src/system/events.cpp b/src/system/events.cpp index 4bbd808..6383047 100644 --- a/src/system/events.cpp +++ b/src/system/events.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include diff --git a/src/system/startup.cpp b/src/system/startup.cpp index dc48014..9636bd7 100644 --- a/src/system/startup.cpp +++ b/src/system/startup.cpp @@ -2,12 +2,12 @@ #include -#include +#include #include #include #include #include -#include +#include #include diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index 32ebd65..66fde9c 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -1,7 +1,7 @@ #include #ifdef STA_RTOS_SYSTEM_WATCHDOG_ENABLE -#include +#include #include #include #include From bd9d1c0424c3fc2155a7dfd156f70d5ae9a714ec Mon Sep 17 00:00:00 2001 From: CarlWachter Date: Thu, 7 Sep 2023 19:30:58 +0200 Subject: [PATCH 24/26] Made watchdog enable naming consitent --- include/sta/rtos/system/watchdog.hpp | 6 +++--- src/system/watchdog.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/sta/rtos/system/watchdog.hpp b/include/sta/rtos/system/watchdog.hpp index f7f2def..1e3a9e4 100644 --- a/include/sta/rtos/system/watchdog.hpp +++ b/include/sta/rtos/system/watchdog.hpp @@ -20,7 +20,7 @@ * * @ingroup STA_RTOS_BuildConfig */ -# define STA_RTOS_SYSTEM_WATCHDOG_ENABLE +# define STA_RTOS_WATCHDOG_ENABLE #endif // DOXYGEN @@ -36,7 +36,7 @@ #include -#ifdef STA_RTOS_SYSTEM_WATCHDOG_ENABLE +#ifdef STA_RTOS_WATCHDOG_ENABLE #include @@ -87,6 +87,6 @@ namespace sta } // namespace sta -#endif // STA_RTOS_SYSTEM_WATCHDOG_ENABLE +#endif // STA_RTOS_WATCHDOG_ENABLE #endif // STA_RTOS_SYSTEM_WATCHDOG_HPP diff --git a/src/system/watchdog.cpp b/src/system/watchdog.cpp index 66fde9c..373b349 100644 --- a/src/system/watchdog.cpp +++ b/src/system/watchdog.cpp @@ -1,5 +1,5 @@ #include -#ifdef STA_RTOS_SYSTEM_WATCHDOG_ENABLE +#ifdef STA_RTOS_WATCHDOG_ENABLE #include #include @@ -97,4 +97,4 @@ void watchdogTimerCallback(void *) -#endif // STA_RTOS_SYSTEM_WATCHDOG_ENABLE +#endif // STA_RTOS_WATCHDOG_ENABLE From 7ea8bb839e5a72e48b80ba9d646bbf6db3e50bd5 Mon Sep 17 00:00:00 2001 From: "@CarlWachter" Date: Tue, 12 Sep 2023 13:38:42 +0200 Subject: [PATCH 25/26] Added Events wrapper --- include/sta/rtos/event.hpp | 35 +++++++++++++++++++++++++++++++++++ src/event.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 include/sta/rtos/event.hpp create mode 100644 src/event.cpp diff --git a/include/sta/rtos/event.hpp b/include/sta/rtos/event.hpp new file mode 100644 index 0000000..95d1c89 --- /dev/null +++ b/include/sta/rtos/event.hpp @@ -0,0 +1,35 @@ +/** + * @file + * @brief RTOS event implementation. + */ + +#ifndef STA_RTOS_EVENT_HPP +#define STA_RTOS_EVENT_HPP + +#include +#include + +namespace sta +{ + /** + * @brief Implementation of Event using CMSIS RTOS2. + * + * @ingroup STA_RTOS_API + */ + class RtosEvent : public Event + { + public: + RtosEvent(); + ~RtosEvent(); + + void set(uint32_t flags) override; + void clear(uint32_t flags) override; + uint32_t get() override; + uint32_t wait(uint32_t flags, uint32_t timeout = osWaitForever) override; + + private: + osEventFlagsId_t event_id; /**< CMSIS RTOS2 Event Flag */ + }; +} // namespace sta + +#endif // STA_RTOS_EVENT_HPP \ No newline at end of file diff --git a/src/event.cpp b/src/event.cpp new file mode 100644 index 0000000..c6795cd --- /dev/null +++ b/src/event.cpp @@ -0,0 +1,29 @@ +#include + +namespace sta { + RtosEvent::RtosEvent() { + osEventFlagsAttr_t attr = { 0 }; + event_id = osEventFlagsNew(&attr); + } + + RtosEvent::~RtosEvent() { + osEventFlagsDelete(event_id); + } + + void RtosEvent::set(uint32_t flags) { + osEventFlagsSet(event_id, flags); + } + + void RtosEvent::clear(uint32_t flags) { + osEventFlagsClear(event_id, flags); + } + + uint32_t RtosEvent::get() { + return osEventFlagsGet(event_id); + } + + uint32_t RtosEvent::wait(uint32_t flags, uint32_t timeout) { + return osEventFlagsWait(event_id, flags, osFlagsWaitAny, timeout); + } + +} // namespace sta \ No newline at end of file From 5b8c97cf5c4b57702c25c0f7e7bcaea4575a6f7d Mon Sep 17 00:00:00 2001 From: "@CarlWachter" Date: Tue, 12 Sep 2023 14:30:58 +0200 Subject: [PATCH 26/26] Added Timer Wrapper --- include/sta/rtos/timer.hpp | 34 ++++++++++++++++++++++++++++++++++ src/timer.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/sta/rtos/timer.hpp create mode 100644 src/timer.cpp diff --git a/include/sta/rtos/timer.hpp b/include/sta/rtos/timer.hpp new file mode 100644 index 0000000..b576078 --- /dev/null +++ b/include/sta/rtos/timer.hpp @@ -0,0 +1,34 @@ +/** + * @file + * @brief RTOS timer implementation. + */ + +#ifndef STA_RTOS_TIMER_HPP +#define STA_RTOS_TIMER_HPP + +#include +#include + +namespace sta +{ + /** + * @brief Implementation of Timer using CMSIS RTOS2. + * + * @ingroup STA_RTOS_API + */ + class RtosTimer : public Timer + { + public: + RtosTimer(void (*callback)(void *arg), void *arg); + ~RtosTimer(); + + void start(uint32_t millis) override; + void stop() override; + + private: + osTimerId_t timer_id_; /**< CMSIS RTOS2 Timer */ + osTimerAttr_t timer_attr_; /**< CMSIS RTOS2 Timer attributes */ + }; +} // namespace sta + +#endif // STA_RTOS_TIMER_HPP \ No newline at end of file diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000..398cdd3 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,28 @@ +#include +#include + +namespace sta { + RtosTimer::RtosTimer(void (*callback)(void *arg), void *arg) { + timer_attr_.name = "Timer"; + timer_attr_.attr_bits = osTimerOnce; + timer_attr_.cb_size = sizeof(osTimerAttr_t); + + timer_id_ = osTimerNew(callback, osTimerOnce, arg, &timer_attr_); + } + + RtosTimer::~RtosTimer() { + osTimerDelete(timer_id_); + } + + void RtosTimer::start(uint32_t millis) { + osStatus_t status = osTimerStart(timer_id_, millis); + + if (status != osOK) STA_DEBUG_PRINTLN("Timer start failed"); + } + + void RtosTimer::stop() { + osStatus_t status = osTimerStop(timer_id_); + + if (status != osOK) STA_DEBUG_PRINTLN("Timer stop failed"); + } +} // namespace sta \ No newline at end of file