1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes   <System Includes> , "Project Includes"
9  **********************************************************************************************************************/
10 #if defined(__GNUC__) && !defined(__ARMCC_VERSION)
11 #include "bsp_api.h"
12 #include <sys/types.h>
13 #include <errno.h>
14 
15 /***********************************************************************************************************************
16  * Macro definitions
17  **********************************************************************************************************************/
18 
19 /***********************************************************************************************************************
20  * Typedef definitions
21  **********************************************************************************************************************/
22 
23 /***********************************************************************************************************************
24  * Private function prototypes
25  **********************************************************************************************************************/
26 
27 /***********************************************************************************************************************
28  * Exported global variables (to be accessed by other files)
29  **********************************************************************************************************************/
30 
31 caddr_t _sbrk(int incr);
32 
33 /***********************************************************************************************************************
34  * Private global variables and functions
35  **********************************************************************************************************************/
36 
37 /*******************************************************************************************************************//**
38  * @addtogroup BSP_MCU
39  * @{
40  **********************************************************************************************************************/
41 
42 /*******************************************************************************************************************//**
43  * FSP implementation of the standard library _sbrk() function.
44  * @param[in]   inc  The number of bytes being asked for by malloc().
45  *
46  * @note This function overrides the _sbrk version that exists in the newlib library that is linked with.
47  *       That version improperly relies on the SP as part of it's allocation strategy. This is bad in general and
48  *       worse in an RTOS environment. This version insures that we allocate the byte pool requested by malloc()
49  *       only from our allocated HEAP area. Also note that newlib is pre-built and forces the pagesize used by
50  *       malloc() to be 4096. That requires that we have a HEAP of at least 4096 if we are to support malloc().
51  * @retval        Address of allocated area if successful, -1 otherwise.
52  **********************************************************************************************************************/
53 
_sbrk(int incr)54 caddr_t _sbrk (int incr)
55 {
56     extern char _Heap_Begin __asm("__HeapBase");  ///< Defined by the linker.
57 
58     extern char _Heap_Limit __asm("__HeapLimit"); ///< Defined by the linker.
59 
60     uint32_t      bytes            = (uint32_t) incr;
61     static char * current_heap_end = 0;
62     char        * current_block_address;
63 
64     if (current_heap_end == 0)
65     {
66         current_heap_end = &_Heap_Begin;
67     }
68 
69     current_block_address = current_heap_end;
70 
71     /* The returned address must be aligned to a word boundary to prevent hard faults on cores that do not support
72      * unaligned access. We assume the heap starts on a word boundary and make sure all allocations are a multiple
73      * of 4. */
74     bytes = (bytes + 3U) & (~3U);
75     if ((current_heap_end + bytes) > &_Heap_Limit)
76     {
77         /** Heap has overflowed */
78         errno = ENOMEM;
79 
80         return (caddr_t) -1;
81     }
82 
83     current_heap_end += bytes;
84 
85     return (caddr_t) current_block_address;
86 }
87 
88 #endif                                 /* defined__GNUC__ && !defined__ARMCC_VERSION */
89 
90 /******************************************************************************************************************//**
91  * @} (end addtogroup BSP_MCU)
92  *********************************************************************************************************************/
93