project文件不僅包含開發者指定的input信息,還包含很多其他輔助調試的input/output信息,算是嵌入式開發中承前啟後的文件。而本文側重點在於project文件中與開發者應用相關的input信息,僅當得到了這些input信息,再加上前面介紹的source和linker文件,那麼你就已經... ...
大家好,我是豹哥,獵豹的豹,犀利哥的哥。今天豹哥給大家講的是嵌入式開發里的project文件。
前面兩節課里,豹哥分別給大家介紹了嵌入式開發中的兩種典型input文件:source文件、linker文件。豹哥要再次提問了,還有沒有input文件呢?答案確實是有,但這次真的是有且僅有了,本文要介紹的主角project文件也屬於半個input文件。為什麼說是半個?因為project文件不僅包含開發者指定的input信息,還包含很多其他輔助調試的input/output信息,算是嵌入式開發中承前啟後的文件。而本文側重點在於project文件中與開發者應用相關的input信息,僅當得到了這些input信息,再加上前面介紹的source和linker文件,那麼你就已經得到了application所有的信息,你可以用它們來可以生成無歧義的可執行image binary。
隨著嵌入式軟體工程的發展,為了應對日益複雜的需求,現代IDE的功能也越來越強大了,IDE版本更迭讓人應接不暇,Keil MDK已然踏入5.0時代,IAR EWARM更是進入了8.0時代,IDE各有千秋,但本文要講的內容卻是每個IDE必須具有的基本功能,還是繼續以IAR EWARM為例開始今天的內容:
一、標準IDE功能
在開始今天的主題之前,豹哥覺得有必要先簡要給大家科普一下標準IDE應該具有的功能。現代IDE基本都是由組件構成,嵌入式開發中的每個階段都對應著相應的組件,由這些組件去實現各階段的需求。
1.1 IDE組件
標準嵌入式開發應該至少包括以下6個階段,而IAR里對於每個階段都有1個或多個組件:
- 輸入(IAR Editor):編輯源文件代碼。
- 編譯(ICCARM、IASMARM):編譯源文件代碼生成可執行二進位機器碼。
- 分析(C-STAT、MISRA-C):編譯過程中檢查代碼中潛在的問題。
- 鏈接(ILINK):鏈接可執行二進位機器碼到指定ARM存儲空間地址。
- 下載(I-jet、flashloader):將鏈接好的可執行二進位機器碼下載進晶元內部非易失性存儲器。
- 調試(C-SPY、C-RUN):線上調試代碼在晶元中執行情況。
project文件主要用來記錄整合上述6個階段的所有開發需求。
1.2 IDE文件類型
既然IDE有很多組件,那麼同時也會存在不同類型的文件以存儲這些組件的所需要的信息。IAR里支持的文件擴展類型非常多,豹哥在這裡僅列舉你所創建的工程根目錄下的與工程同名的擴展文件,相信你一定會覺得眼熟。
Ext: Type of file:
.eww Workspace file
.ewp IAR Embedded Workbench project
.ewd Project settings for C-SPY
.ewt Project settings for C-STAT and C-RUN
.dep Dependency information
本文要講的內容都包含在.ewp文件里,ewp文件記錄了開發者為應用指定的不可缺少的input信息,沒有這些信息,application工程是不完整的。換句話說,如果你得到了application的所有source文件和linker文件,但沒有ewp文件的話,可能導致最終生成的image binary文件是不同的。
Note:更多IAR支持的擴展文件類型請查閱IAR軟體安裝目錄下\IAR Systems\Embedded Workbench xxx\arm\doc\EWARM_IDEGuide.ENU.pdf文檔里的File types一節。
二、解析project(ewp)文件
前面豹哥鋪墊了很多IDE/project基礎概念,該是直奔主題的時候了,本文主角ewp工程文件到底包含哪些開發者指定的input信息?豹哥從下麵2個方面為大家揭秘:
2.1 源文件組織
一個稍微複雜一點的嵌入式工程,應用代碼行數應該是以百行/千行為單位計算的(此處僅指的是由開發者自己創建的文件與代碼),我們在組織代碼的時候肯定不會只創建一個.c文件,單文件會導致代碼功能模塊結構不清晰,不方便工程的管理與維護。
當我們為工程創建多個文件時,就會涉及到一個必然問題:路徑問題。當源文件數目較多時,通常我們會創建不同文件夾把相同功能的源文件都放在一起,當編譯器開始編譯.c源文件時會搜索include語句所包含的頭文件。熟悉C語言的朋友肯定清楚下麵兩種不同include語句的用法:
#include <file.h> // 引用編譯器類庫下的頭文件(系統路徑)
#include "file.h" // 引用當前工程下的頭文件(project路徑)
所以在ewp文件里會包含路徑信息,所有路徑都應該列在Options->C/C++ Compiler->Preprocessor下有Additional include directories里,這個路徑既可以是當前PC的絕對路徑,也可以是以ewp文件為基準的相對路徑,為了保證工程可以在任意PC任意位置下正常編譯,推薦使用如下相對路徑方式列出所有路徑:
ewp當前路徑:$PROJ_DIR$/
ewp下級路徑:$PROJ_DIR$/xxFolder/
ewp上級路徑:$PROJ_DIR$/../
說到路徑問題,豹哥在這裡順便給大家介紹一種經典的嵌入式工程文件目錄組織方式:
\projectDir
\doc --放置工程文檔
\bsp --放置bsp相關的source file
\linker --工程linker文件
\src --工程板級相關的源文件(比如pinout,clock等)
\builds\xxBuild\.ewp --工程ewp文件
.eww --工程workspace文件
\src --放置bsp無關的source file
\platform --晶元頭文件及CMSIS文件
\drivers --晶元各模塊driver
\include --要被所有source引用的頭文件
\startup --標準的startup code
\utilities --標準的通用函數
\components --應用組件
\application --應用代碼
2.2 編譯選項
編譯選項包含了編譯器所需要的所有信息,代碼需經過編譯器編譯才能生成二進位機器碼,不同的編譯器選項配置會生成不同的機器碼,那麼需要指定哪些選項呢?打開project的Options選項卡,分別設置下表item:
Position | Item | Description |
---|---|---|
General Options->Target-> | Processor variant->Core | 指定ARM內核版本 |
Endian mode | 指定內核大小端模式 | |
Floating point settings->FPU | 指定內核支持的FPU版本 | |
General Options->Library Configuration-> | Library | 選擇C/C++動態鏈接庫版本 |
General Options->Library Option 2-> | Heap selection | 選擇HEAP實現版本 |
C/C++ Compiler-> | Language 1->Language | 指定編程語言類型 |
Language 1->C dialect | 指定C語言標準 | |
Language 1->Language conformance | 選擇對標準C/C++的遵循程度 | |
Language 2->Plain 'char' is | 選擇對char的符號性預設處理方法 | |
Language 2->Floating-point semantics | 選擇對浮點數的處理遵循C標準的程度 | |
Code->Process mode | 指定內核指令集模式 | |
Code->Position-independence | 選擇要生成位置無關代碼的對象 | |
Optimizations->Level | 選擇優化等級 |
Note:更多ewp文件中option解釋請查閱IAR軟體安裝目錄下\IAR Systems\Embedded Workbench xxx\arm\doc\EWARM_IDEGuide.ENU.pdf文檔里的General Options和Compiler Options倆小節。
當在project中組織好源文件並設置好正確的編譯選項,那麼恭喜你,你的application設計工作已經基本完成了。
番外一、幾個小技巧
小技巧待續
至此,嵌入式開發里的project文件豹哥便介紹完畢了,掌聲在哪裡~~~