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 <sys/types.h>
12 #include <errno.h>
13 #include "bsp_api.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 /***********************************************************************************************************************
32  * Exported global functions (to be accessed by other files)
33  **********************************************************************************************************************/
34 
35 /***********************************************************************************************************************
36  * Private global variables and functions
37  **********************************************************************************************************************/
38 caddr_t _sbrk(int incr);
39 
40 /*******************************************************************************************************************//**
41  * @addtogroup BSP_MCU
42  * @{
43  **********************************************************************************************************************/
44 
45 /*******************************************************************************************************************//**
46  * FSP implementation of the standard library _sbrk() function.
47  * @param[in]   inc  The number of bytes being asked for by malloc().
48  *
49  * @note This function overrides the _sbrk version that exists in the newlib library that is linked with.
50  *       That version improperly relies on the SP as part of it's allocation strategy. This is bad in general and
51  *       worse in an RTOS environment. This version insures that we allocate the byte pool requested by malloc()
52  *       only from our allocated HEAP area. Also note that newlib is pre-built and forces the pagesize used by
53  *       malloc() to be 4096. That requires that we have a HEAP of at least 4096 if we are to support malloc().
54  * @retval        Address of allocated area if successful, -1 otherwise.
55  **********************************************************************************************************************/
_sbrk(int incr)56 caddr_t _sbrk (int incr)
57 {
58     extern char _Heap_Begin __asm("__HeapBase");  ///< Defined by the linker.
59 
60     extern char _Heap_Limit __asm("__HeapLimit"); ///< Defined by the linker.
61 
62     uint32_t      bytes            = (uint32_t) incr;
63     static char * current_heap_end = 0;
64     char        * current_block_address;
65 
66     if (current_heap_end == 0)
67     {
68         current_heap_end = &_Heap_Begin;
69     }
70 
71     current_block_address = current_heap_end;
72 
73     /* The returned address must be aligned to a word boundary to prevent hard faults on cores that do not support
74      * unaligned access. We assume the heap starts on a word boundary and make sure all allocations are a multiple
75      * of 4. */
76     bytes = (bytes + 3U) & (~3U);
77     if (current_heap_end + bytes > &_Heap_Limit)
78     {
79         /** Heap has overflowed */
80         errno = ENOMEM;
81 
82         return (caddr_t) -1;
83     }
84 
85     current_heap_end += bytes;
86 
87     return (caddr_t) current_block_address;
88 }
89 
90 #endif
91 
92 /******************************************************************************************************************//**
93  * @} (end addtogroup BSP_MCU)
94  *********************************************************************************************************************/
95