STM32 - Dynamic Memory Allocation Implementation,如何正确实现_sbrk函数?

STM32 - Dynamic Memory Allocation Implementation, how to correctly implement the _sbrk function?

我正在 STM32F401RE 开发板上用 C++ 编写裸机编程项目,我需要实现 malloc()free() 函数。

我知道嵌入式系统上的动态内存分配不是一个好主意,但我需要它。

据我了解,为了使用 C 标准库的 mallocfree 函数,我需要手动实现一个名为 _sbkr() 的函数,并且为了为此,我创建了一个具有此单一功能的库,并将其添加到 main.cpp 源代码的包含项中。

问题是它不起作用,当我尝试动态分配一个变量时,它 returns 一个 NULL 指针。

用gcc生成main的汇编代码,好像_sbrk函数没有在最终目标文件中实现

如何正确实现这个功能?

sbrk 是一个在具有 MMU 运行 保证单独进程的单独内存空间的操作系统的系统上有意义的函数。

你好像什么都没有。所以,要求 sbrk 的功能完全没有意义。

要实现它,您需要做的是首先实现一个使用您的硬件没有的 MMU 的操作系统——它有一个 MPU。

所以,总而言之,不,这不会成功。 sbrk 不是没有 OS 和 MMU 的东西。

如果你真的想在你的STM32上进行动态内存分配,你将不得不使用一个实现内存池的库(或者自己写一个),然后你可以做malloc/free(或者你想怎样称呼他们)你自己。

I'm working on a bare-metal programming project written in C++ on a STM32F401RE board, and I need to implement malloc() and free() functions.

呃哦;裸机和动态内存分配?

现实地:你有一个很好的微控制器,你会想要 运行 一个 RTOS 在上面。没有任何借口,真的——它不会让任何事情变得更慢,而且使用的内存也可以忽略不计,但会让你的编程更安全、更容易。

大多数现代 RTOSes 都有内存堆和分配器。 ChibiOS 肯定会,maybe you'll want to read FreeRTOS documentation 在自己开始任何事情之前进行内存管理。

假设您使用的是 Newlib(在独立系统上与 GCC 一起使用的常用 C 库),那么 C 库的目标特定移植层(“系统调用”)定义在 https://sourceware.org/newlib/libc.html#Syscalls

此处给出了适用于独立(无 OS)环境的最小实现作为示例:

caddr_t sbrk(int incr) {
  extern char _end;     /* Defined by the linker */
  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) {
    write (1, "Heap and stack collision\n", 25);
    abort ();
  }

  heap_end += incr;
  return (caddr_t) prev_heap_end;
}

另请注意,如果您使用的是 RTOS 或线程库,您还需要使用 RTOS/thread 库 [=13] 来实现 __malloc_lock()__malloc_unlock() =] 呼叫.

另请注意,如果您使用 ST STM32CubeIDE,它使用 GCC 和 Newlib,并且已经实现了系统调用层。

Using STM32CubeMX (e.g. integrated in STM32CubeIDE),生成的代码将根据动态内存分配的需要包含 _sbrk() 的实现。这是在文件 sysmem.c.

中找到的