sysmem.c
 1  /**
 2   ******************************************************************************
 3   * @file      sysmem.c
 4   * @author    Generated by STM32CubeIDE
 5   * @brief     STM32CubeIDE System Memory calls file
 6   *
 7   *            For more information about which C functions
 8   *            need which of these lowlevel functions
 9   *            please consult the newlib libc manual
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2025 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   */
22  
23  /* Includes */
24  #include <errno.h>
25  #include <stdint.h>
26  
27  /**
28   * Pointer to the current high watermark of the heap usage
29   */
30  static uint8_t *__sbrk_heap_end = NULL;
31  
32  /**
33   * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
34   *        and others from the C library
35   *
36   * @verbatim
37   * ############################################################################
38   * #  .data  #  .bss  #       newlib heap       #          MSP stack          #
39   * #         #        #                         # Reserved by _Min_Stack_Size #
40   * ############################################################################
41   * ^-- RAM start      ^-- _end                             _estack, RAM end --^
42   * @endverbatim
43   *
44   * This implementation starts allocating at the '_end' linker symbol
45   * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
46   * The implementation considers '_estack' linker symbol to be RAM end
47   * NOTE: If the MSP stack, at any point during execution, grows larger than the
48   * reserved size, please increase the '_Min_Stack_Size'.
49   *
50   * @param incr Memory size
51   * @return Pointer to allocated memory
52   */
53  void *_sbrk(ptrdiff_t incr)
54  {
55    extern uint8_t _end; /* Symbol defined in the linker script */
56    extern uint8_t _estack; /* Symbol defined in the linker script */
57    extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
58    const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
59    const uint8_t *max_heap = (uint8_t *)stack_limit;
60    uint8_t *prev_heap_end;
61  
62    /* Initialize heap end at first call */
63    if (NULL == __sbrk_heap_end)
64    {
65      __sbrk_heap_end = &_end;
66    }
67  
68    /* Protect heap from growing into the reserved MSP stack */
69    if (__sbrk_heap_end + incr > max_heap)
70    {
71      errno = ENOMEM;
72      return (void *)-1;
73    }
74  
75    prev_heap_end = __sbrk_heap_end;
76    __sbrk_heap_end += incr;
77  
78    return (void *)prev_heap_end;
79  }