本文檔介紹了如何可以幫助HCS12X編譯器來生成更優化的程式碼來進行數據存取。 它將涵蓋以下主題
Variables allocated in direct addressing area · Variables allocated in extended addressing area
· Variables allocated in banked addressing area – Using Logical Addresses · Variables allocated in banked addressing area – Using Global Addresses · Banked Constant allocation
· Logical Addresses vs. Global Addresses 對於上面列舉的各變數類型,我們將描述:
· How to define a variable · How to declare a variable · Code generated to access the variable · How to define a pointer pointing to such a variable · Code generated to access the pointer and access the variable. · Placement in PRM file.
下面的方法只適用於SMALL (-Ms) 和BANKED (-Mb) Memory model,不適用於LARGE (-Ml) memory model.
同時,freescale推薦小於32k code使用SMALL,大於32k code使用BANKED,不推薦使用LARGE。 RAM:
Variables allocated in Direct Addressing Area
為了告訴編譯器,一個變數被分配直接頁面上,你必須定義並宣告它在一個特定的與屬性__ SHORT_SEG的區段。
· Defining & Accessing Data on Direct Addressing Area: 1. Variable definition is done as follows:
#pragma DATA_SEG __SHORT_SEGMyShortData unsigned char rub_short_var;
#pragma DATA_SEG DEFAULT 2. Variable declaration is done as follows:
#pragma DATA_SEG __SHORT_SEGMyShortData extern unsigned char rub_short_var; #pragma DATA_SEG DEFAULT
3. Access to the variable will generate following code: 37: rub_short_var = 2; 00E08002 C602 [1] LDAB #2 00E08004 5B08 [2] STAB $08
4. There is no special pointer type for variables allocated in the direct page 1. A pointer pointing to such a variable will be defined as follows: unsigned char* ptr_on_short_var;
5. Initializing and accessing the pointed object will then generate the code below: 46: ptr_on_short_var = &rub_short_var; 00E0801F 180320102102 MOVW #8208,$2102 47: (*ptr_on_short_var)++;
00E08025 62FBA0D9 INC [$A0D9,PC] /* [ptr_on_short_var,PCR] */
6. For variable defined in a SHORT section, SEGMENT and PLACEMENT will be done as follows in the PRM file SEGMENTS
DIRECT_PAGE = READ_WRITE 0x2010 TO 0x20FF; /* Other segment definition here*/ END PLACEMENT
MyShortData INTO DIRECT_PAGE; /* Other placement definition here*/ END Note:
區段定義的logical addresses區塊所包含變數應使用direct addressing模式存取分配。
Configuring Direct Addressing Area:
HCS12X,直接頁面可以移動,不是硬編碼為0x00..0xFF的(因為它是在HCS12)。 編譯器確實需要一個特殊的設置,以支持這一點:
The compiler and assembler option -CpDirect must be used with the starting address of the Direct
accessible area if the DIRECT register contains anything but the default value 0.
編譯器和彙編器選項-CpDirect如果直接暫存器包含任何東西,但預設值0,必須使用直接存取區域的起始地址。例如如果直接初始化0X21 n的直接窗口是從0x2000到0x20FF和編譯器和彙編器選項CpDirect0x2000。此選項添加到編譯器和彙編器設置。
直接暫存器必須由用戶程式初始化。預設啟動程式不直接初始化
在prm文件中,MyShortData部分要被分配到相應的該區域(例如從0x2000到0x20FF)。 Be careful, there is no linker diagnostic message for an incorrect allocation of the direct section (say if MyShortData is not allocated correctly).
For the HCS12, the linker issues a fixup overflow. But for the HCS12X this is no longer possible as the direct page can be mapped.
要小心,沒有鏈接的診斷消息是不正確的分配直接部分說,(如果沒有正確分配MyShortData)。
對於HCS12鏈接問題修正溢出。但為HCS12X這不再是可能直接頁面可以映射。
Variables allocated in Extended Addressing Area
為了通知編譯器extended address空間分配一個變數,你只需一般的方式定義(宣告) 1. Variable definition is done as follows: unsigned char rub_var;
2. Variable declaration is done as follows: extern unsigned char rub_var;
3. Access to the variable will generate following code: 39: rub_var =7;
00E08002 C607 [1] LDAB #7 00E08004 7B2001 [3] STAB $2001
4. A pointer pointing to such a variable can be defined as follows: unsigned char * ptr_on_var;
5. Initializing and accessing the pointed object will then generate the code below: 57: ptr_on_var = &rub_var;
00E0805F 18032100210C MOVW #8448,$210C 58: (*ptr_on_var)++;
00E08065 62FBA0A3 INC [$A0A3,PC] /* [ptr_on_var,PCR] */
6. Variable defined this way are allocated in predefined section DEFAULT_RAM. In the PRM file, SEGMENT and PLACEMENT definition for this section will be done as follows: SEGMENTS
RAM = READ_WRITE 0x2100 TO 0x3FFF; /* Other segment definition here*/ END PLACEMENT
DEFAULT_RAM INTO RAM; /* Other placement definition here*/ END Note:
Section containing variables accessed using extended addressing mode should be allocated in segment defined with logical addresses.
區段定義logical addresses區塊應包含變數存取使用擴展尋址模式分配。
Variables allocated in Banked Addressing Area 使用banked RAM有兩種方法:
1. 使用local address
2. 使用global address(尋址方式更大) 先看一下local address方式: 首先,我們要在.c中定義一個變量:
#pragma DATA_SEG __RPAGE_SEG PAGED_RAM /* the description of PAGED_RAM is in prm file */ unsigned char banked_var; #pragma DATA_SEG DEFAULT 接著,我們同樣在.h中聲明這個變量:
#pragma DATA_SEG __RPAGE_SEG PAGED_RAM/* the description of PAGED_RAM is in prm file */ extern unsigned char banked_var; #pragma DATA_SEG DEFAULT 這樣,我們就可以使用這個變量了。
例如:我可以給值給這個變量-> banked-var = 0x5;但是,如果想使用指標指向這個變量的話,需要如下操作:
unsigned char * __rptrptr_var;/* 這個指針的定義不需要定義在PAGED_RAM,需要確認這個變量定義在哪裡? */ ptr_var = &banked_var; 注意點:
prm文件的SEGMENTS必須寫為local address,如下: SEGMENTS
RAM_FB = READ_WRITE 0xFB1000 TO 0xFB1FFF; RAM_FC = READ_WRITE 0xFC1000 TO 0xFC1FFF; RAM_FD = READ_WRITE 0xFD1000 TO 0xFD1FFF; /* Other segment definition here*/ END PLACEMENT
PAGED_RAM INTO RAM_FB, RAM_FC, RAM_FD; /* Other placement definition here*/ END
最後看一下global address的方式: 首先,我們要在.c中定義一個變量:
#pragma DATA_SEG __GPAGE_SEG PAGED_RAM /* the description of PAGED_RAM is in prm file */ unsigned char banked_var; #pragma DATA_SEG DEFAULT 接著,我們同樣在.h中聲明這個變量:
#pragma DATA_SEG __GPAGE_SEG PAGED_RAM /* the description of PAGED_RAM is in prm file */ extern unsigned char banked_var; #pragma DATA_SEG DEFAULT 這樣,我們就可以使用這個變量了。
例如:我可以賦值給這個變量-> banked-var = 0x5;但是,如果想使用指針指向這個變量的話,需要如下操作:
unsigned char * __far ptr_var;/* 這個指針的定義不需要定義在PAGED_RAM,需要確認這個變量定義在哪裡? */ ptr_var = &banked_var; 注意點:
prm文件的SEGMENTS可以local address或者也是global address.
EEPROM/FLASH:(操作const變量) 1. local address形式
使用#pragma CONST_SEG __EPAGE_SEG PAGED_CONST /#pragma CONST_SEG __PPAGE_SEG PAGED_CONST定義
指標定義用const unsigned char *__eptrptr_eeprom; /const unsigned char *__pptrptr_eeprom; 2. global address形式
使用#pragma CONST_SEG __GPAGE_SEG PAGED_CONST 指針用const unsigned char *__far ptr;
分頁常數分配
常數可以被分配在bankedEEPROM或banked FLAH,可以存取使用 · Logical addresses in EEPROM(using EPAGE)or · Logical addresses in FLASH (using PPAGE) or · Global addresses
Using Logical Addresses in EEPROM
為了告訴編譯器,您想要存取一個常數在EEPROM中使用他的邏輯地址,你必須使用下面的符號: 1. Constant definition is done as follows:
#pragma CONST_SEG __EPAGE_SEG PAGED_CONST const unsigned char cub_far_const=1; #pragma CONST_SEG DEFAULT 2. Constant declaration is done as follows:
#pragma CONST_SEG __EPAGE_SEG PAGED_CONST externconst unsigned char cub_far_const=1; #pragma CONST_SEG DEFAULT
3. A pointer pointing to such a variable will be defined as follows: const unsigned char *__eptrptr_on_far_const; Note:
常數分配EPAGE的區段,也可以使用far指標進行存取。
const unsigned char *__far ptr_on_far_const;
在這種情況下,global addressing模式將被用來存取指向對象。 Using Logical Addresses in FLASH
Using Logical Addresses in FLASH is supported by the compiler only for code which is not allocated in any paged area.
在FLASH使用Logical Addresses支持由編譯器僅用於在任何分頁區域代碼的沒有被分配。 As this is often not the case, we recommend to use Global addressing for all data objects in FLASH.
因為這往往是沒有的情況下,在FLASH中我們建議所有數據對象使用Global addressing。 To implement using logical addresses, use the segment qualifier __PPAGE_SEG and the pointer qualifier __pptr.
要實現使用logical addresses,使用區段限定的__ PPAGE_SEG和指針限定符__pptr。 Using Global Addresses
1. Constant definition is done as follows:
#pragma CONST_SEG __GPAGE_SEG PAGED_CONST const unsigned char cub_far_const=1; #pragma CONST_SEG DEFAULT 2. Constant declaration is done as follows:
#pragma CONST_SEG __GPAGE_SEG PAGED_CONST externconst unsigned char cub_far_const= 1; #pragma CONST_SEG DEFAULT
3. A pointer pointing to such a variable will be defined as follows: const unsigned char *__far ptr_on_far_const; Logical Addresses vs. Global Addresses
對於不大於4K(一個Banked RAM窗口大小)的變數,使用logical addresses的效率比使用global
addresses好。
如果變數大於4K,鏈接器將分配整個Banked的邊界。在這種情況下,我們建議使用global addresses
來存取變數。
我們建議使用global addresses模式的來存取分配在FLASH中的常數或字串常數。 我們推薦使用logical addresses的所有對象,在運行時使用的邏輯地址。
這包括堆疊、程式碼、直接變數、擴展變數及I / O暫存器。
為了定義一個分頁變數,確定使用DATA_SEG編譯指示。本著這一宗旨,不要試圖使用__ far關
鍵字。
__ far關鍵字指示編譯器應該如何存取一個變量,它不會改變變量的方式進行分配。
文章最後還要注意的是:
1. 要在complier的option中加入-D__FAR_DATA
2. 所有定義的指針的地址在DEFAULT_ROM,但是指向的地址是banked區域的。都佔3個byte(需要確認)
3. global address方式沒有local address執行指令快,除非需要尋址空間大,最好不要使用global address. 4. 該文章針對HCS12X系列CPU,HCS12沒有global address的說法。
以上的內容參考freescale技術手冊:TN238/TN240及freescale工程中的datapage.c
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务