gpt4 book ai didi

c++ - 外部 RAM 中的动态 vector 分配

转载 作者:行者123 更新时间:2023-12-03 07:04:25 24 4
gpt4 key购买 nike

我目前正在使用 GCC 在 C++ 中的 STM32F7 cortex-m7 微 Controller 上开展自己的大型项目。我需要在外部 SDRAM(16 MB)中存储一个宽数组,其中包含注释结构的 vector (每个 12 个字节)。我已经创建了一个工作 FMC 和一个自定义 ram 区域

/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
SDRAM (xrw) : ORIGIN = 0xC0000000, LENGTH = 16M
}

/* Define output sections */
SECTIONS
{
/* Section créée pour l'allocation dans la SDRAM externe*/
.fmc :
{
. = ALIGN(8);
*(.fmc)
*(.fmc*)
. = ALIGN(8);
} >SDRAM

我的数组声明如下:
std::vector<SequencerNoteEvent> NotesVectorArray[kMaxPpqn] __attribute__((section(".fmc")));

到目前为止还可以。我在我的外部 RAM 中创建了一个 vector 数组。我如何才能继续创建我的 vector 元素
NotesVectorArray[position].push_back(note);

动态发生在同一个外部 RAM 中?我目前只能使用 __attribute__(section) 声明静态数据

我读了很多关于 C++ 分配器、内存池的东西,但我不知道在 vector 代码中分配的位置以及我应该如何替换它......我“只是”需要与通常的分配系统相同但在我内存的另一部分中,这种精确的类型。

似乎有可能有多个堆。分散文件和有效内存分配之间的联系在哪里?

提前致谢,

最佳答案

我遇到了同样的问题,并通过重新定义 operator new 得到了一个可行的解决方案.与使用自定义分配器相比,这样做的好处是 全部 动态分配将自动在 SDRAM 中,因此您可以自由使用 std::function 或任何需要堆的 STL 容器,而不必每次都传递自定义分配器参数。
我做了以下事情:

  • 通过添加 -nostdlib 删除标准库到编译标志。我还将它添加到链接器标志中。同时删除和--specs=...从您的编译器和链接器标志。奖励:您将节省约 60-80k 的代码空间!
  • operator new 编写自己的替换, operator delete .我创建了一个名为 new.cpp 的新文件添加了以下内容:(取自 https://arobenko.gitbooks.io/bare_metal_cpp/content/compiler_output/dyn_mem.html )
  • //new.cpp
    #include <cstdlib>
    #include <new>

    void *operator new(size_t size) noexcept { return malloc(size); }
    void operator delete(void *p) noexcept { free(p); }
    void *operator new[](size_t size) noexcept { return operator new(size); }
    void operator delete[](void *p) noexcept { operator delete(p); }
    void *operator new(size_t size, std::nothrow_t) noexcept { return operator new(size); }
    void operator delete(void *p, std::nothrow_t) noexcept { operator delete(p); }
    void *operator new[](size_t size, std::nothrow_t) noexcept { return operator new(size); }
    void operator delete[](void *p, std::nothrow_t) noexcept { operator delete(p); }
  • 在链接描述文件中定义一个与最低 SDRAM 地址(堆的开始)相对应的变量。这不是绝对必要的,因为您可以在第 4 步中的代码中使用常量 (0xC0000000),但是将 SDRAM 地址保存在一个位置会使事情变得更容易。只需添加一行:PROVIDE( _fmc_start = . );
  • //linker script

    [snip]

    /* Section créée pour l'allocation dans la SDRAM externe*/
    .fmc :
    {
    . = ALIGN(8);
    PROVIDE( _fmc_start = . );
    *(.fmc)
    *(.fmc*)
    . = ALIGN(8);
    } >SDRAM

  • new 的新实现直接调用malloc() ,它将调用 _sbrk()当它需要堆中的一 block 内存时。
    所以你必须定义_sbrk()跟踪堆指针,只需将指针从您刚刚在链接描述文件中定义的最低 SDRAM 地址开始。
    这是我所做的:
  • //sbrk.cpp, or append this to new.cpp
    #include <cstdlib>

    extern "C" size_t _sbrk(int incr)
    {
    extern char _fmc_start; // Defined by the linker
    static char *heap_end;
    char *prev_heap_end;

    if (heap_end == 0)
    heap_end = &_fmc_start;
    prev_heap_end = heap_end;
    //Optionally can check for out-of-memory error here
    heap_end += incr;
    return (size_t)prev_heap_end;
    }
  • 此时,如果您尝试编译,您可能会遇到很多链接器错误。确切的错误将取决于您的项目使用的标准库的哪些部分,除了 new 和 delete。就我而言,我使用的是 std::function并且编译器提示它没有 __throw_bad_function_call() .您可能还会看到诸如 _init() 之类的错误。和 _fini()__errno .基本策略是为每一个创建自己的空函数 stub 或变量声明。值得快速搜索其中的每一个以查看它们的用途,您可能会发现您的项目或您包含的库正在使用一些您不知道的功能!创建 stub 时,您需要正确匹配函数签名,因此也需要搜索 Internet。许多 stub 用于处理错误/异常,因此您可以决定如何在函数体中处理它(或忽略错误)。

  • 例如,这里有一些关于(已过时,但需要) _init() 的信息和 _fini()功能: https://tldp.org/HOWTO/Program-Library-HOWTO/miscellaneous.html
    这里有一些关于 __dso_handle 的信息: https://lists.debian.org/debian-gcc/2003/07/msg00057.html
    __cxa_pure_virtual(): What is the purpose of __cxa_pure_virtual?
    这是我的项目需要的工作:
    //syscalls.cpp
    extern "C" {
    void _init(void) {}
    void _fini(void) {}
    int __errno;
    void *__dso_handle = (void *)&__dso_handle;
    }
    namespace std
    {
    //These are error handlers. They could alternatively restart, or log an error
    void __throw_bad_function_call() { while (1); }
    void __cxa_pure_virtual() { while (1); }
    } // namespace std
    毕竟,它最终会编译,如果您使用调试器,您会看到 vector 的地址从 0xC0000000 开始。 !

    关于c++ - 外部 RAM 中的动态 vector 分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55025634/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com