Keil的堆設定

2021-07-12 00:48:52 字數 2501 閱讀 8351

【原文 使用keil的microlib時自動設定堆大小】

keil編譯專案,如果使用微庫microlib,就可以使用malloc。微庫內部位置乙個堆管理模組。

晶元的ram大小是固定了的,前面分為全域性變數,後面分給堆和棧,這是一般開發方式。

但是我們在開發專案的過程中,市場遇到各種各樣問題,棧穿透到堆裡面,或者堆不夠大,相當煩人!

有時候就在想,何不讓全域性變數以外的所有ram給堆疊共用?

因為堆從低到高分配,而棧從高到低分配,理論上是可行的!

但是堆的分配由__heap_base和__heap_limit兩個標籤決定,不是變數又不能改!

因為我們使用很多種晶元,每一種晶元的ram大小都有可能不同。

而smartos追求跨平台,不想為不同晶元做太多設定。

之前我們已經實現了通過修改msp把棧頂移到ram最高處,這樣子棧可以得到最大利用!

但是堆還是不好搞!

今晚再次遇到堆不夠用的情況,__heap_limit如果分配過大,在小容量晶元就會出錯。

忍無可忍,決定分析一下微庫是怎麼管理堆的。

首先開啟專案編譯後生成的鏈結位址對映檔案linker address map,我們這裡是smartosf0_debug.map

找到符號表段global symbols

__heap_base                              0x200005a0   data           0  startup_stm32f0xx.o(heap)

__heap_limit                             0x200005a0   data           0  startup_stm32f0xx.o(heap)

__initial_sp                             0x200005c0   data           0  startup_stm32f0xx.o(stack)

從這裡可以看出,堆疊已經分配好了。

堆分配使

用的是malloc函式,上圖找到它位於keil庫檔案mc_p.l中

我的目錄是d:\keil\arm\armcc\lib\armlib

輪到法寶ida上陣,選擇malloc.o,太簡單了,只有malloc/free兩個函式

彙編圖形介面如下:

手頭的ida沒有arm外掛程式,否則乙個f5就可以得到malloc的c源**。

好好工作賺錢賣arm外掛程式吧。。。

沒有工具輔助,那就自己來寫吧!

上面是手工寫的c**,被注釋的是最原始的彙編寫法,然後逐步精簡優化。

大概摸清楚了malloc的機制,關鍵點在於初始化那裡,用到了__heap_limit

而__heap_limit作為常量被編譯到flash裡面去了,記憶體裡面無法動態修改。

實在沒辦法,只好位元組寫**來接替它初始化整個堆了。

我寫的初始化**如下:

附上malloc/free**,不完整,只能大概了解它的機制:

void free(void* p)      if(!r2)         r3->node = p;     else          } } typedef struct  node; __microlib_freelist:     node* _freelist; __microlib_freelist_initialised:     int _freelist_initialised = 0; void* malloc(int size)      //r2 = __microlib_freelist;     r0 = _freelist;     while(true)     */         //r0 = *r2;         if(!r0) return 0;         //r3 = *r0;         r3 = r0->size;         if(r3 <= r1) break;                  //r2 = r0 + 4;         //r2 = r0->next;         r0 = *(r0->next);     }     if(r3 <= r1)          else               return r0; }

關於Android堆記憶體的設定

關於android堆記憶體的設定 c c code 關於android堆記憶體的設定 已編輯 選項 將帖子標記為未讀 將此主題新增到書籤 訂閱此主題 訂閱此主題的 rss 提要 高亮顯示此貼 列印此貼 通過電子郵件將此主題傳送給好友 舉報此貼 修改時間 08 30 201012 2108 30 20...

關於Android堆記憶體的設定

關於android堆記憶體的設定 c c code 關於android堆記憶體的設定 已編輯 選項 將帖子標記為未讀 將此主題新增到書籤 訂閱此主題 訂閱此主題的 rss 提要 高亮顯示此貼 列印此貼 通過電子郵件將此主題傳送給好友 舉報此貼 修改時間 08 30 201012 2108 30 20...

關於Android堆記憶體的設定

大家都知道android的上層應用是基於 dalvik virtual machine的。dalvik vm的特點是基於暫存器,相比sun的jvm 基於堆疊,沒有暫存器 來說,理論上完成同樣的功能需要的指令條數少,但是指令集複雜。到了android2.2,dalvik終於實現了jit just in...