2015-04-01 27 views
5

這裏是我的應用程序的上下文:我正在使用來自不同設備的RAM的嵌入式系統。微控制器的內部RAM中有一部分(128kB),另一部分是外部RAM(1MB)。這些存儲器被映射到微控制器的地址空間,但是在不連續的區域。是否可以使用operator new從堆中分配?

內部RAM用於系統堆棧,任務堆棧和Heap。 外部RAM用於靜態分配數據(池,緩衝區和所有「static ...」的東西)

我想實現一個簡單的內存管理結構,並作爲其中的一部分能夠創建一個allocator可能使用operator new的分配算法,但是使用另一個內存源,而不是系統堆,而是其他地方的內存區域。你知道這是可能的嗎?

一個使用的例子可能是保留100kB的外部RAM並創建一個分配器來管理它,然後將它提供給需要這個存儲器的指定任務。

static const uint8_t* ramBase = reinterpret_cast<uint8_t*>(0x80000000); 
static const uint32_t ramAreaSize = 0x19000; //100kB 
BufferAllocator allocator(ramBase, ramAreaSize); 

//... 
//Assuming operator new is overloaded to use BufferAllocator 
MyObject * obj = new (allocator) MyObject(some, parameter); 
//... 

的問題是:如何(如果這甚至有可能),我可以爲了使用operator new管理原始內存區域執行BufferAllocator

void* BufferAllocator::allocate(uint32_t bytes) 
{ 
    //I would like to write something like this 
    //and so let the responsibility to manage this memory area to "new" 
    //so I don't have to reimplement (or reuse) a different custom 
    // allocator 
    return ::operator new(ramBase, ramAreaSize, bytes) 
} 
+2

是的,這是可能的,這是正確的語法。你不能只使用'delete'來釋放對象。另一種選擇是爲'MyObject'類型重載'operator new'和'operator delete',所以你不需要使用placement new語法。 – 2015-04-01 16:40:33

+0

這個問題:http://stackoverflow.com/questions/7194127/how-should-i-write-iso-c-standard-conformant-custom-new-and-delete-operators是一個很好的開始閱讀的地方。 – 2015-04-01 17:23:53

+0

如果你打算使用放置新的' - >〜()'來刪除。 – jiveturkey 2015-04-01 17:37:46

回答

0

我面臨同樣的問題還有,我能找到的唯一解決辦法是寫我自己的mallocfree。我並不需要任何特別的東西,所以我只是在K & R的C語言編程語言(他們有一個簡單的例子記錄)之後模擬了我的代碼。

然後我創建了兩個堆:一個用於內部存儲器,一個用於外部存儲器。我的堆棧位於完全不同的內存塊(STM32F4上的CCRAM),因此我不需要擔心sbrk。但是,我必須根據數據和bss段的大小知道內部SRAM堆的起始地址。這是從連接器腳本注入的extern符號確定的。

我有足夠的關於我的堆的信息來了解它的當前大小,可用空間量以及是否有足夠的連續內存來執行分配。如果內部SRAM不夠,它會嘗試外部SRAM。如果在那裏沒有足夠的內存,那麼與默認的內存不足malloc沒有區別。

我使用的GNU工具鏈,所以我能聘請--wrap選項覆蓋C標準庫的默認mallocfreerealloccalloc(其實malloc_rfree_rrealloc_rcalloc_r因爲我使用newlib )。由於newdelete最終致電malloc和朋友,我能夠使其工作(至少對我的需要)。

我對這種方法並不十分自信,但這是我能力範圍內最好的。仔細考慮一下。

我想知道更簡單的解決方案。

+0

我想我會尋求一種類似於你的解決方案,因爲它似乎無法做我想做的事。 ..我正在使用MDK ARM工具鏈開發Cortex-M3(EFM32GG)。 '-wrap'選項並不是一個好的解決方案,因爲預期的行爲依賴於構建命令行,我打算將這些代碼編寫爲項目之間的共享(它將成爲框架的一部分)。來自ARM的一些有趣鏈接可以在運行時擴展堆:[在運行時擴展堆大小](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0475c/CHDFCIFC。 HTML) – Inounx 2015-04-09 07:59:31

0

有沒有標準的方式來提供一個內存區域operator newmalloc()。在類POSIX系統中,malloc()調用brk(),sbrk()和可能mmap()來獲取該區域,因此您可能會「捕獲」這些調用並提供您自己的實現,但這不是便攜式的(並且對於mmap()有問題)。

根據你的工具鏈,你可能能夠向malloc()和/或operator new「解釋」它應該處理兩個或多個不同的內存區域,在某些鏈接描述文件或某些類似的東西中。但是沒有保證。

除此之外,我能想到的唯一一般解決方案是在項目中使用不同的通用內存管理器(如jemalloc),並找到一種方法來配置它以達到您的目的。

相關問題