From 53ea27370375c3730868c11989f3a3984c016019 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 16:25:55 +0200 Subject: [PATCH 01/10] Fix unused parameters in sketch Signed-off-by: Frederic Pillon --- examples/frBlinkPrint/frBlinkPrint.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/frBlinkPrint/frBlinkPrint.ino b/examples/frBlinkPrint/frBlinkPrint.ino index 96f6e8f..a818f69 100644 --- a/examples/frBlinkPrint/frBlinkPrint.ino +++ b/examples/frBlinkPrint/frBlinkPrint.ino @@ -12,6 +12,7 @@ TaskHandle_t blink; //------------------------------------------------------------------------------ // high priority for blinking LED static void vLEDFlashTask(void *pvParameters) { + UNUSED(pvParameters); pinMode(LED_PIN, OUTPUT); // Flash led every 200 ms. @@ -31,6 +32,7 @@ static void vLEDFlashTask(void *pvParameters) { } //------------------------------------------------------------------------------ static void vPrintTask(void *pvParameters) { + UNUSED(pvParameters); while (1) { // Sleep for one second. vTaskDelay(configTICK_RATE_HZ); From 4eca9f9694c13b94d996594d719c99b07fd9fefe Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 10:34:28 +0200 Subject: [PATCH 02/10] Add heap_useNewlib_ST.c from Dave Nadler to support newlib 3.1 https://nadler.com/embedded/newlibAndFreeRTOS.html https://github.com/DRNadler/FreeRTOS_helpers Signed-off-by: Frederic Pillon --- portable/MemMang/heap_useNewlib_ST.c | 284 +++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 portable/MemMang/heap_useNewlib_ST.c diff --git a/portable/MemMang/heap_useNewlib_ST.c b/portable/MemMang/heap_useNewlib_ST.c new file mode 100644 index 0000000..cf30cb5 --- /dev/null +++ b/portable/MemMang/heap_useNewlib_ST.c @@ -0,0 +1,284 @@ +/** + * \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) { + #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) { + #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) { + 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 4b76cae7f0cea717ebc1dec44fde62571e689ca5 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 16:25:09 +0200 Subject: [PATCH 03/10] Update to use the heap_useNewlib_ST.c from Dave Nadler Signed-off-by: Frederic Pillon --- README.md | 2 +- portable/MemMang/heap_useNewlib.c | 166 ------------------------------ src/FreeRTOSConfig_Default.h | 6 +- src/heap.c | 4 +- 4 files changed, 6 insertions(+), 172 deletions(-) delete mode 100644 portable/MemMang/heap_useNewlib.c diff --git a/README.md b/README.md index 3203f7f..ae6aee2 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ By default, the `heap_useNewlib.c` is used. It can be changed thanks a define in ``` /* Define memory allocation implementations to use: * 1 to 5 for heap_[1-5].c - * -1 for heap_useNewlib.c + * -1 for heap_useNewlib_ST.c * Default -1 see heap.c */ ``` diff --git a/portable/MemMang/heap_useNewlib.c b/portable/MemMang/heap_useNewlib.c deleted file mode 100644 index 7c62f5c..0000000 --- a/portable/MemMang/heap_useNewlib.c +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file heap_useNewlib.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 2-July-2017 - * - * \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, 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, ALL ORIGINAL COMMENTS, and the following disclaimer. - * - * - 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. - */ - -#include // maps to newlib... -#include // mallinfo... -#include // ENOMEM - -#include "newlib.h" -#if (__NEWLIB__ != 2) || (__NEWLIB_MINOR__ != 5) - #warning "This wrapper was verified for newlib version 2.5.0; 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, strtok, etc..." - // If you're *really* sure you don't need FreeRTOS's newlib reentrancy support, remove this warning... -#endif -#include "task.h" - -// ================================================================================================ -// External routines required by newlib's malloc (sbrk/_sbrk, __malloc_lock/unlock) -// ================================================================================================ - -#ifndef NDEBUG - static int totalBytesProvidedBySBRK = 0; -#endif -extern char _end; // Defined in the linker script -static int heapBytesRemaining = -1; // configTOTAL_HEAP_SIZE is not constant will be init later - -//! sbrk/_sbrk version supporting reentrant newlib (depends upon above symbols defined by linker control file). -char * sbrk(int incr) { - static char *currentHeapEnd = &_end; - vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started - if (heapBytesRemaining == -1) { - heapBytesRemaining = configTOTAL_HEAP_SIZE; - } - char *previousHeapEnd = currentHeapEnd; - if (currentHeapEnd + incr > &_end + configTOTAL_HEAP_SIZE) { - #if( configUSE_MALLOC_FAILED_HOOK == 1 ) - { - extern void vApplicationMallocFailedHook( void ); - vApplicationMallocFailedHook(); - } - #elif 0 - // If you want to alert debugger or halt... - while(1) { __asm("bkpt #0"); }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop forever) - #else - // If you prefer to believe your application will gracefully trap out-of-memory... - _impure_ptr->_errno = ENOMEM; // newlib's thread-specific errno - xTaskResumeAll(); - #endif - return (char *)-1; // the malloc-family routine that called sbrk will return 0 - } - currentHeapEnd += incr; - heapBytesRemaining -= incr; - #ifndef NDEBUG - totalBytesProvidedBySBRK += incr; - #endif - xTaskResumeAll(); - return (char *) previousHeapEnd; -} -//! Synonym for sbrk. -char * _sbrk(int incr) { return sbrk(incr); }; - -#if (__NEWLIB__ >= 3) -void __malloc_lock(struct _reent *ptr __attribute__((__unused__))) { vTaskSuspendAll(); }; -void __malloc_unlock(struct _reent *ptr __attribute__((__unused__))) { (void)xTaskResumeAll(); }; -#else -void __malloc_lock() { vTaskSuspendAll(); }; -void __malloc_unlock() { (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). -// ToDo: Move __env_lock/unlock to a separate newlib helper file. -void __env_lock() { vTaskSuspendAll(); }; -void __env_unlock() { (void)xTaskResumeAll(); }; - -/// /brief Wrap malloc/malloc_r to help debug who requests memory and why. -/// Add to the linker command line: -Xlinker --wrap=malloc -Xlinker --wrap=_malloc_r -// Note: These functions are normally unused and stripped by linker. -void *__wrap_malloc(size_t nbytes) { - extern void * __real_malloc(size_t nbytes); - void *p = __real_malloc(nbytes); // Solely for debug breakpoint... - return p; -}; -void *__wrap__malloc_r(void *reent __attribute__((__unused__)), size_t nbytes) { - extern void * __real__malloc_r(size_t nbytes); - void *p = __real__malloc_r(nbytes); // Solely for debug breakpoint... - return p; -}; - - -// ================================================================================================ -// 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(); - if (heapBytesRemaining == -1) { - heapBytesRemaining = configTOTAL_HEAP_SIZE; - } - return mi.fordblks + heapBytesRemaining; -} - -// GetMinimumEverFree is not available in newlib's malloc implementation. -// So, no implementation provided: size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; - -//! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks -void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; diff --git a/src/FreeRTOSConfig_Default.h b/src/FreeRTOSConfig_Default.h index b76cc09..61560a9 100644 --- a/src/FreeRTOSConfig_Default.h +++ b/src/FreeRTOSConfig_Default.h @@ -44,7 +44,7 @@ /* Begin custom definitions for STM32 */ /* Define memory allocation implementations to use: * 1 to 5 for heap_[1-5].c - * -1 for heap_useNewlib.c + * -1 for heap_useNewlib_ST.c * Default -1 see heap.c */ /*#define configMEMMANG_HEAP_NB 3*/ @@ -82,7 +82,7 @@ #define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configTOTAL_HEAP_SIZE ((size_t)(15 * 1024)) - +#define configISR_STACK_SIZE_WORDS (0x100) #else extern char _end; /* Defined in the linker script */ extern char _estack; /* Defined in the linker script */ @@ -97,7 +97,7 @@ extern char _Min_Stack_Size; /* Defined in the linker script */ */ #define configMINIMAL_STACK_SIZE ((uint16_t)((uint32_t)&_Min_Stack_Size/8)) #define configTOTAL_HEAP_SIZE ((size_t)(&_estack - _Min_Stack_Size - &_end)) - +#define configISR_STACK_SIZE_WORDS ((uint32_t)&_Min_Stack_Size/4) #endif /* configUSE_CMSIS_RTOS_V2 */ #define configUSE_PREEMPTION 1 diff --git a/src/heap.c b/src/heap.c index 6a25e7a..238afbf 100644 --- a/src/heap.c +++ b/src/heap.c @@ -2,7 +2,7 @@ * @file heap.c * @author Frederic Pillon for STMicroelectronics. * @brief Provide Memory allocation implementations included in the FreeRTOS source - * heap_useNewlib - thread-safe memory manager using C runtime (Newlib) + * heap_useNewlib_ST - thread-safe memory manager using C runtime (Newlib) * heap_1 - the very simplest, does not permit memory to be freed * heap_2 - permits memory to be freed, but not does coalescence adjacent free blocks. * heap_3 - simply wraps the standard malloc() and free() for thread safety @@ -16,7 +16,7 @@ #endif #if (configMEMMANG_HEAP_NB == -1) -#include "../portable/MemMang/heap_useNewlib.c" +#include "../portable/MemMang/heap_useNewlib_ST.c" #elif (configMEMMANG_HEAP_NB == 1) #include "../portable/MemMang/heap_1.c" #elif (configMEMMANG_HEAP_NB == 2) From 778bf9db98886e38fe469b1a67120e422a46162c Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 17:47:10 +0200 Subject: [PATCH 04/10] Fix unused parameters warning in heap_useNewlib_ST.c Signed-off-by: Frederic Pillon --- portable/MemMang/heap_useNewlib_ST.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/portable/MemMang/heap_useNewlib_ST.c b/portable/MemMang/heap_useNewlib_ST.c index cf30cb5..1fb3987 100644 --- a/portable/MemMang/heap_useNewlib_ST.c +++ b/portable/MemMang/heap_useNewlib_ST.c @@ -209,6 +209,7 @@ char * _sbrk(int incr) { return sbrk(incr); }; 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 @@ -218,6 +219,7 @@ void __malloc_lock(struct _reent *r) { #endif }; void __malloc_unlock(struct _reent *r) { + (void)(r); #if defined(MALLOCS_INSIDE_ISRs) DRN_EXIT_CRITICAL_SECTION(malLock_uxSavedInterruptStatus); #else @@ -250,6 +252,7 @@ void __env_unlock() { (void)xTaskResumeAll(); }; 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++; From 6e74eb4606c0c39d01f9faf7e5931b5f0528f0bb Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 19:34:56 +0200 Subject: [PATCH 05/10] Fix for CM0 with heap_useNewlib_ST Signed-off-by: Frederic Pillon --- src/portmacro.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/portmacro.h b/src/portmacro.h index f3ff239..e0b2cbd 100644 --- a/src/portmacro.h +++ b/src/portmacro.h @@ -14,6 +14,8 @@ #if (__CORTEX_M == 0x00U) #include "../portable/GCC/ARM_CM0/portmacro.h" +/* Stub for heap_useNewlib_ST */ +inline __attribute__(( always_inline )) static BaseType_t xPortIsInsideInterrupt( void ) { return pdFALSE; } #endif #if (__CORTEX_M == 0x03U) From 23ba1f9efad201b26d69bfcaa6f2fd0ceb69d7a3 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Apr 2021 19:39:35 +0200 Subject: [PATCH 06/10] Update newlib version check Tested with newlib 3.3 of the xPack GNU Arm Embedded GCC v9.3.1-1.3 Signed-off-by: Frederic Pillon --- portable/MemMang/heap_useNewlib_ST.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portable/MemMang/heap_useNewlib_ST.c b/portable/MemMang/heap_useNewlib_ST.c index 1fb3987..e957f56 100644 --- a/portable/MemMang/heap_useNewlib_ST.c +++ b/portable/MemMang/heap_useNewlib_ST.c @@ -73,8 +73,8 @@ #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!" +#if ((__NEWLIB__ == 2) && (__NEWLIB_MINOR__ < 5)) ||((__NEWLIB__ == 3) && (__NEWLIB_MINOR__ > 3)) + #warning "This wrapper was verified for newlib versions 2.5 - 3.3; please ensure newlib's external requirements for malloc-family are unchanged!" #endif #include "FreeRTOS.h" // defines public interface we're implementing here From 4adcfbd52bbe43261e75ba1ab5d3e48d23b0f4d3 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Sat, 17 Apr 2021 14:27:05 +0200 Subject: [PATCH 07/10] Review size definition Fix issue raised in issue comment: https://github.com/stm32duino/STM32FreeRTOS/issues/39#issuecomment-815126173 when configMEMMANG_HEAP_NB is equal to 1, 2 or 4 Signed-off-by: Frederic Pillon --- src/FreeRTOSConfig_Default.h | 19 ++++++++++++------- src/heap.c | 6 ++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/FreeRTOSConfig_Default.h b/src/FreeRTOSConfig_Default.h index 61560a9..7bc0793 100644 --- a/src/FreeRTOSConfig_Default.h +++ b/src/FreeRTOSConfig_Default.h @@ -79,26 +79,31 @@ * which is not suitable for the new CMSIS-RTOS v2 priority range */ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 - +/* Require to be a value as used in cmsis_os2.c as array size */ +#ifndef configMINIMAL_STACK_SIZE #define configMINIMAL_STACK_SIZE ((uint16_t)128) -#define configTOTAL_HEAP_SIZE ((size_t)(15 * 1024)) -#define configISR_STACK_SIZE_WORDS (0x100) +#endif #else +#define configMAX_PRIORITIES (7) +#endif /* configUSE_CMSIS_RTOS_V2 */ + extern char _end; /* Defined in the linker script */ extern char _estack; /* Defined in the linker script */ extern char _Min_Stack_Size; /* Defined in the linker script */ - -#define configMAX_PRIORITIES (7) - /* * _Min_Stack_Size is often set to 0x400 in the linker script * Use it divided by 8 to set minmimal stack size of a task to 128 by default. * End user will have to properly configure those value depending to their needs. */ +#ifndef configMINIMAL_STACK_SIZE #define configMINIMAL_STACK_SIZE ((uint16_t)((uint32_t)&_Min_Stack_Size/8)) +#endif +#ifndef configTOTAL_HEAP_SIZE #define configTOTAL_HEAP_SIZE ((size_t)(&_estack - _Min_Stack_Size - &_end)) +#endif +#ifndef configISR_STACK_SIZE_WORDS #define configISR_STACK_SIZE_WORDS ((uint32_t)&_Min_Stack_Size/4) -#endif /* configUSE_CMSIS_RTOS_V2 */ +#endif #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 diff --git a/src/heap.c b/src/heap.c index 238afbf..5f1e676 100644 --- a/src/heap.c +++ b/src/heap.c @@ -15,6 +15,12 @@ #define configMEMMANG_HEAP_NB -1 #endif +#if configMEMMANG_HEAP_NB != -1 +/* Need to be redefined as a value as it used in some heap_*.c as array size */ +#undef configTOTAL_HEAP_SIZE +#define configTOTAL_HEAP_SIZE ((size_t)(15 * 1024)) +#endif + #if (configMEMMANG_HEAP_NB == -1) #include "../portable/MemMang/heap_useNewlib_ST.c" #elif (configMEMMANG_HEAP_NB == 1) From 8b196df3561920c02f311cb2d0bb77d1921911ab Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 25 Jun 2021 11:13:25 +0200 Subject: [PATCH 08/10] fix: cast linker value for configTOTAL_HEAP_SIZE Fixes #42 --- src/FreeRTOSConfig_Default.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FreeRTOSConfig_Default.h b/src/FreeRTOSConfig_Default.h index 7bc0793..562c768 100644 --- a/src/FreeRTOSConfig_Default.h +++ b/src/FreeRTOSConfig_Default.h @@ -99,7 +99,7 @@ extern char _Min_Stack_Size; /* Defined in the linker script */ #define configMINIMAL_STACK_SIZE ((uint16_t)((uint32_t)&_Min_Stack_Size/8)) #endif #ifndef configTOTAL_HEAP_SIZE -#define configTOTAL_HEAP_SIZE ((size_t)(&_estack - _Min_Stack_Size - &_end)) +#define configTOTAL_HEAP_SIZE ((size_t)((uint32_t)&_estack - (uint32_t)&_Min_Stack_Size - (uint32_t)&_end)) #endif #ifndef configISR_STACK_SIZE_WORDS #define configISR_STACK_SIZE_WORDS ((uint32_t)&_Min_Stack_Size/4) From c7733596e872984211ccd844e95a88985b4c7546 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 10 Feb 2022 18:39:04 +0100 Subject: [PATCH 09/10] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index f535e0e..fbfd696 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=STM32duino FreeRTOS -version=10.2.1 +version=10.2.2 author=Richard Barry maintainer=stm32duino sentence=Real Time Operating System implemented for STM32 From c319f990390149a3cb9e160afccfcafde0317d2b Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 10 Feb 2022 18:39:24 +0100 Subject: [PATCH 10/10] Update library.json --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index 6a437d1..50d5a75 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "STM32duino FreeRTOS", - "version": "10.2.1", + "version": "10.2.2", "keywords": "rtos, timing, thread, task, mutex, semaphore", "description": "Real Time Operating System implemented for STM32", "repository": { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy