(十二)进一步掌握STVD/COSMIC
| ? | 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.
然后重新編譯一下就可以了。
轉載于:https://www.cnblogs.com/zhangshenghui/p/7447400.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的(十二)进一步掌握STVD/COSMIC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Stanford CoreNLP使用需要
- 下一篇: ACM Smallest Differe