天天看點

【IoT】CC254x 中 data、idata、xdata 和 pdata 差別以及堆 Heap 記憶體布局

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 位于資料空間中,其映射方式下圖:

【IoT】CC254x 中 data、idata、xdata 和 pdata 差別以及堆 Heap 記憶體布局

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

繼續閱讀