如何分配變數到指定的地址

來源:互聯網
上載者:User

轉自:http://www.waveshare.net/article/STM8-3-1-10.htm

舉例:
unsigned char temp_A@0x00; //定義無符號變數temp_A,強制其地址為0x00
unsigned char temp_B@0x100; //定義無符號變數temp_B,強制其地址為0x100
@tiny unsigned char temp_C; //定義無符號變數temp_C,由編譯器自動在地址小於0x100的RAM中為其分配一個地址
@near unsigned char temp_D; //定義無符號變數temp_D,由編譯器自動在地址大於0xFF的RAM中為其分配一個地址
另外也可以採用偽指令"pragma"將函數或者變數定義到指定的section中,例如:
#pragma section [name] // 將下面定義的未初始設定變數定義到.name section中
Unsigned char data1;
Unsigned int data2;
……(任何需要定義在.name section中的變數)
……
#pragma section [] // 返回到正常的section.
注意:pragma偽指令可以用來定位函數,初始設定變數或者未初始設定變數。這三者用不同的括弧區分。
(name):代碼
[name] :未初始設定變數
{name}:初始設定變數

如何在COSMIC C檔案中使用組合語言
在COSMIC C檔案中使用組合語言常見的方法有如下兩種:使用#asm …#endasm組合格式
或_asm("…"); 單行格式。
舉例1:
unsigned char temp_A;
Void func1(void)
{
...
#asm
PUSH A
LD A,(X)
LD _temp_A,A
POP A
#endasm
...
}
註:在C嵌彙編環境下使用全域變數,要在該全域變數名稱前加底線"_"。
舉例2:
Void func1(void)
{
...
_asm("rim");
_asm("nop");
...
}

如何觀察RAM/FLASH/EEPROM的最終分配情況

在Project->settings->linker選項頁中,將Category選為Output,再勾選Generate Map File。
點擊OK按鍵後,再次編譯連結該項目,如果成功則會在項目輸出目錄中(本例是在C:\STM8_NewProject1\debug 目錄下)產生 .map 檔案。該檔案詳細地列出RAM/FLASH/EEPROM的分配使用方式。

如何產生hex格式的輸出檔案
在Project->settings->PostBuild選項頁中,在commands欄內加入下行命令:
chex –fi -o $(OutputPath)$(TargetSName).hex $(OutputPath)$(TargetSName).sm8
再次編譯連結該項目,如果成功則會在項目輸出目錄中(本例是在C:\STM8_NewProject1\debug 目錄下)產生 .hex 檔案。

什麼是MEMORY MODEL
STM8的C編譯器支援多種儲存空間模式。使用者可以根據應用的需要選擇最適合的配置。可以根據需要選擇採用2個位元組的定址方式(僅適用於64k以內的程式)或者3位元組的定址方式。也可以規定將變數預設為定義在儲存空間的哪一地區:zero page內,還是zero page 外。下面對幾種供選擇的MEMORY MODEL做簡單說明。
在Project->settings->C Complier選項頁中,將Category選為General,裡面有一個Memory Models選項欄如下:

在下拉式功能表中共有4種MEMORY MODEL可供選擇:

  • 程式地址空間在64K以內(即程式容量小於32K)
    mods0,
    modsl0
  • 程式地址哦那個鍵在64K以上(即程式容量大於32K)
    mods
    modsl
  MODS0 MODSL0 MODS MODSL
名稱 Stack Short
短堆棧模式
Stack Long
長堆棧模式
Stack Short
短堆棧模式
Stack Long
長堆棧模式
程式地址空間 程式所用到的地址空間在64K範圍內 程式所用到的地址空間超出64K範圍
指標預設類型 函數指標和資料指標預設為@near (2 bytes) 函數指標預設為@far(地址為3位元組);
資料指標預設為@near
全域變數預設類型 所有全域變數的地址預設為1個位元組。對於地址超出1個位元組的變數,必須用@near定義 所有全域變數預設為Long型。若要將變數地址定義為1個位元組,必須用@tiny定義 所有全域變數的地址預設為1個位元組。對於地址超出1個位元組的變數,必須用@near定義 所有全域變數預設為Long型。若要將變數地址定義為1個位元組,必須用@tiny定義

.lkf 檔案的作用
.lkf檔案在程式連結時決定如何具體分配RAM/ROM的空間。在Project Settings – Linker – Category(Input)選項頁中,當"Auto"選擇框被選中時,由系統自動產生.LKF檔案,否則由使用者指定。

當"Auto"選擇框被勾選時,.lkf檔案會自動產生在項目主目錄下的 debug/ 和 release/ 目錄中。下面以所示 at45DBXX Project的 lkf 檔案為例,來進一步理解.lkf 。
在.lkf中,以"#"開頭的行是注釋行,為方便使用者理解,將原注釋刪除,代之以中文注釋如下:
# 定義(+seg)一個常量段(.const),開始(b)於0x8080,最大分配(m)0x1ff80個位元組(即不超過
# 0x27FFF),為該段起名(n)為.const(和常量段的保留字同名),需要初始化的變數的初始值存
# 放於此段(-it)
+seg .const -b 0x8080 -m 0x1ff80 -n .const -it
# 定義(+seg)一個程式段(.text),緊跟(-a)在.const段後面(和.const 共同位於0x8080 –
# 0x27FFF),為該段起名(n)為. text (和程式段的保留字同名)。
+seg .text -a .const -n .text
# 定義(+seg)一個EEPROM段(.eeprom),開始(b)於0x4000,最大分配(m)0x800個位元組(即不超
#過0x47FF),為該段起名(n)為. eeprom (和EEPROM段的保留字同名)。
+seg .eeprom -b 0x4000 -m 0x800 -n .eeprom
# .bsct段服務於定義在0頁(地址小於0x100)以內需要初始化的全域變數(如@tiny char a = 9;)
+seg .bsct -b 0x0 -m 0x100 -n .bsct
# .ubsct段服務於定義在0頁(地址小於0x100)以內不需要初始化的全域變數(如@tiny char b;)
+seg .ubsct -a .bsct -n .ubsct
# .bit表示位域段,定義後即可在程式中使用_Bool變數(如_Bool c = 1;),-id表示該段需要初始化。
+seg .bit -a .ubsct -n .bit -id
# 這是ST7時代(STM8是基於ST7發展而來的)由於物理堆棧小,速度慢,使用記憶體來類比堆棧的變通手段。
+seg .share -a .bit -n .share -is
# .data段服務於定義在0頁(地址大於0xFF)以外需要初始化的全域變數(如@near char d = 8;)
+seg .data -b 0x100 -m 0x1300 -n .data
# .bss段服務於定義在0頁(地址大於0xFF)以內不需要初始化的全域變數(如@ near char e;)
+seg .bss -a .data -n .bss
# 段定義結束,下面放置的庫及Obj檔案中的變數、常量、程式就按照上面的規定進行分配。
#初始化程式
crtsi0.sm8
#使用者程式
Debug\main.o

# 一些必要的cosmic庫
libis0.sm8
libm0.sm8
# 重定義常量段,開始於0x8000,用於放置中斷向量表(STM8硬體決定此位置)
# –k 用於程式冗餘代碼最佳化,詳情可參考cosmic使用者手冊。
+seg .const -b 0x8000 –k
# 中斷向量
Debug\stm8_interrupt_vector.o
#定義了三個變數,用於系統初始化
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # end of bss segment
+def __stack=0x17ff # 不同的晶片__stack內容不同,由系統自動產生

如何?位操作
Cosmic C 編譯器支援位變數的操作,可以將其定義成 _Bool類型。_Bool類型的變數只包含兩種值true(1)或者false(0)。若將一個運算式賦值給_Bool變數,則編譯器會將運算式與0做比較,然後將布爾值賦給_Bool變數。因此,任何整型或者運算式的值都可以賦給_Bool變數。但是,布爾變數不能定義位元組,只能定義成結構體或者聯合。而且,_Bool變數會被打包成位元組的形式。
編譯器會將所有的全域_Bool變數打包成位元組形式,存放在.bit section中。局部_Bool變數也會被打包成位元組形式。但是_Bool類型的參數會被擴充成一個單位元組。

具體的關於位變數的定義和使用可參考如下例子:
定義位變數:
_Bool in_range;
_Bool p_valid;
char *ptr;
使用位變數:
in_range = (value >= 10) && (value <= 20);
p_valid = ptr; /* p_valid is true if ptr not 0 */
if (p_valid && in_

在使用位變數時,若程式編譯時間提示如下錯誤:
#error clnk Debug\example.lkf:1 no default placement for segment .bit
The command: "clnk -l"C:\Program Files\COSMIC\CXSTM8_16K_4.2.10\Lib" -o Debug\example.sm8 -mDebug\example.map -sa Debug\example.lkf " has failed, the returned value is: 1
exit code=1.
實際上是由於,在項目中沒有定義.bit section。可按照如下步驟,手工添加.bit section:
開啟項目連結配置視窗:Project - Settings - Linker,選擇 Input 目錄項

在Zero page 或者 Ram 裡面定義一個.bit section.

然後重新編譯一下就可以了。

進一步掌握STVD/COSMIC

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.