1、data、idata、xdata 和 pdata 差別
從資料存儲類型來說,8051 系列有片内、片外程式存儲器,片内、片外資料存儲器,片内程式存儲器還分直接尋址區和間接尋址類型,分别對應code、data、xdata、idata以及根據51系列特點而設定的pdata類型。
使用不同的存儲器,将使程式執行效率不同,在編寫C51程式時,最好指定變量的存儲類型,這樣将有利于提高程式執行效率(此問題将在後面專門講述)。
與ANSI-C稍有不同,它隻分SAMLL、COMPACT、LARGE模式,各種不同的模式對應不同的實際硬體系統,也将有不同的編譯結果。
在51系列中data,idata,xdata,pdata的差別:
1)data
固定指前面0x00-0x7f的128個RAM,可以用 acc 直接讀寫的,速度最快,生成的代碼也最小。
2)idata
固定指前面0x00-0xff的256個RAM,其中前128和data的128完全相同,隻是因為通路的方式不同。
idata 是用類似C中的指針方式 通路的。
彙編中的語句為:mox ACC,@Rx
3)xdata
外部擴充RAM,一般指外部0x0000-0xffff空間,用DPTR通路。
4)pdata
外部擴充RAM的低256個位元組,位址出現在A0-A7的上時讀寫,用movx ACC,@Rx讀寫。
程式可以簡單的分為code(程式)區,和data (資料)區,code區在運作的時候是不可以更改的,data區放全局變量和臨時變量,是要不斷的改變的。
cpu從code區讀取指令,對data區的資料進行運算處理,是以code區存儲在什麼媒體上并不重要,code區也可以放在rom裡面,也可以放在ram裡面,也可以放在flash裡面(但是運作速度要慢很多,主要讀flash比讀ram要費時間)。
是以一般的做法是要将程式放到flash裡面,然後load到ram裡面運作的,DATA區就沒有什麼選擇了,肯定要放在RAM裡面,放到rom裡面改動不了。
2、Heap 布局
1)堆記憶體的大小可以通過INT_HEAP_LEN來配置;
2)可以在工程選項裡定義OSALMEM_METRICS=TRUE,通過該宏使能的代碼檢視堆記憶體實時的使用情況,進而以此為指導配置出适合自己系統的堆大小;
3)如果需要詳細的掌握stack裡堆記憶體的管理細節,可以參考官方文檔 Heap_Memory_Management.pdf。
示例:
INT_HEAP_LEN=3072
對于3K的大小是否适合我們的系統呢?
下面分析堆記憶體布局和目前系統堆記憶體使用率這兩個方面,來進一步解答這個問題:
堆記憶體布局
首先,我們需要明确的是堆記憶體位于實體媒體SRAM當中。
CC254x 是哈佛結構,代碼空間與資料空間是獨立尋址的。
SRAM 位于資料空間中,其映射方式下圖:
SRAM被映射到xdata space的前8K(目前所用的CC2541 SRAM大小為8K),位址範圍是0x0000 - 0x1FFF。
我們的heap配置的是3K大小,那它到底位于SRAM的哪裡呢?
在OSAL_Memory.c中,找到下面的代碼:
static osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ];
static osalMemHdr_t *ff1; // First free block in the small-block bucket
這個數組就是整個的堆記憶體空間,隻要找到theHeap的位址就能知道對記憶體的位址範圍。
要擷取theHeap的位址最簡單的方法就是檢視編譯後生成的.map檔案。下面是我當時摘取map檔案中關于theHeap的片段:
XDATA_Z
Relative segment, address: XDATA 00000A79 - 00001678 (0xc00 bytes), align: 0
Segment part 7. Intra module refs: osal_mem_alloc
osal_mem_init
LOCAL ADDRESS
===== =======
theHeap 00000A79
十六進制的0xc00等于3072,剛好是我們配置的堆記憶體大小,其位址範圍是0x0A79 - 0x1678。
到目前就知道了如下兩點:
heap位于ram當中;
heap的位址範圍是0x0A79 - 0x1678,這個範圍在每次修改程式後都有可能改變;
refer:
https://blog.csdn.net/w13687130701/article/details/50916112