擺脫MDK,用cmake改造嵌入式軟件開發體驗

爲何要改造

最近看了一些資料,關於工程和項目方面的,其中一方面是關於持續集成和持續部署方面的,以爲有必要學習一下並運用到實際中,無奈編譯那部分沒法搞定,由於咱們作單片機的基本上都是用MDK作爲開發工具,不得不說,MDK開發嵌入式確實挺好,各類板子的配置,debug方面很出色,內存佔用也很小,可是有幾點不喜歡:linux

  • 綁定了專屬編譯器,編譯腳本固定,輸出目標的可操做地方少,具體的編譯細節弄不清楚
  • 做爲編輯器相關功能太差了,有時候連代碼智能提示都沒有,搞的開發的效率很低沒由於不少變量名長了加上有大小寫下劃線不容易記住,恰恰又提示不出來
  • 項目管理方面的功能不夠

改造以後的效果

改造以後就能夠脫離MDK來進行程序的編寫,編譯以及運行,不只能夠學習到整個工程編譯過程(怎麼從源碼變成elf文件再變成hex和bin文件)的還能夠實現持續集成相關任務,經過cmd或者linux終端便可實現程序的編譯,下載.c++

不過每次都到命令行敲指令畢竟很麻煩,我們更多的仍是使用圖形化的IDE界面,能夠經過點擊按鈕就實現程序編譯下載等等,我比較喜歡Clion和Qtcreater兩款IDE,可是Clion佔用內存比Qtcreater大並且須要收費(也能夠破解和買tb激活碼,可是畢竟盜版了),加上從業以來一直喜歡用qtcreater,最終選擇了qtvreater,可是最終的效果是同樣的,你們弄懂了其中原理也能夠改造到本身喜歡的編輯器裏去,好比vs code,sublime等等,不列舉了

準備工做

開始以前須要瞭解的知識儲備大體以下,沒必要深究細節,理解爲主,老鳥自動忽略便可編程

1.編譯工具鏈(gcc llvm armcc armclang)
2.編譯的四步驟(預處理,彙編,編譯,連接)
3.什麼叫elf文件(可執行文件)
4.elf和hex,bin文件什麼關係(固件)
5.make(makefile)和cmake有什麼關係
若是對於以上幾個概念沒有什麼基礎,你們去百度上搜索相關資料,這裏我就很少作介紹,真要提及來,一匹布那麼長......

安裝make工具

windows平臺上下載mingw-make工具並添加到系統路徑下(cmd調出make指令不會提示未找到指令),linux平臺直接就能用,具體的安裝方法上網搜索之,這裏就不浪費篇幅,以windows爲例,達到如下效果便可:segmentfault

clipboard.png

安裝cmake

cmake的安裝也很簡單,上網搜索就能夠了,安裝後添加系統路徑,cmd能找到指令就好了,以下圖所示:windows

clipboard.png

安裝Qtcreater或者Clion

這兩個ide是否安裝全憑喜愛,不習慣或者有別的順手的傢伙也能夠不裝,經過命令行敲命令的方式能夠能夠的.具體的安裝過程這裏也不贅述ide的安裝過程,總之安裝好了以後桌面上會出現圖標,點擊打開便可,新安裝的clion可能會提示激活,不要緊咱們免費用30天,30天到期以後是破解仍是買激活碼各童鞋本身選擇便可.app

開始改造之旅

接下來就是真正動手的環節了,大致步驟:重頭戲--編輯cmake文件,導入cmake生成makefile,編譯,下載等等,具體的工程是使用我如今用的芯片nrf52832,sdk12.3,編譯鏈選擇的是armclang,個童鞋也能夠用gcc來編譯.編程語言

cmake文件和工具鏈選擇

cmake使用一個叫作CMakeLists.txt的文件進行編譯管理,這個名字大多數狀況下是固定的,由於不少IDE依靠這個名稱進行cmake識別
1.使用armclang或者armgcc須要的文章的cmake文件分爲兩個,一個是tollchain.cmake,一個就是CMakeLists.txt,這兩個文件的做用不太同樣,一個是定義編譯工具, 一個就是具體的編譯規則
2.使用MDK自帶的armcc工具鏈只須要一個文件就是CMakeLists.txt,注意,cmake3.5在版本在3.5版本以後才增長了armcc的支持,目前cmake最新版本是3.15,建議你們都用最新版本或者次新版本(防止先版本有bug)
本文屬於拋磚引玉型文章,由於大多數的工程仍是用的armcc編譯鏈來進行編譯的,這裏先按照從易到難先從armcc的方式給你們理解一下cmakelists文件的編寫.關於armclang由於有許多的芯片庫sdk在armclang下會出問題(定義的__GUN__可是又不能使用.ld文件,會形成不少麻煩,固然有解決辦法,比較複雜)編輯器

cmake文件的組成部分

1.定義cmake版本以及工程名稱ide

cmake_minimum_required(VERSION 3.12) ##支持的cmake最低版本
project("S350N_M8" C)  ##定義項目名稱和源碼語言(新)
enable_language(ASM) ##啓用匯編語言

2.定義編譯,連接工具
用於給makefile文件指定交叉編譯工具,簡單來講就是讓makefile知道用什麼工具去幹活,很重要,那麼工具鏈在哪呢,咱們打開文件管理器定位到mdk的安裝目錄,以下圖所示目錄:函數

clipboard.png
代碼以下:

set(TOLLCHAIN_PATH "D:/keil_v5/armcc/bin")  ##先設置一個贊成的路徑,用set語法至關於編程語言的定義一個字符串
set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}/armcc.exe")  ##設置c語言編譯鏈,c++爲CMAKE_CXX_COMPILER 
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_PATH}/armasm.exe")  ##設置彙編編譯工具
set(CMAKE_C_LINK_EXECUTABLE "${TOOLCHAIN_PATH}/armlinke.exe") ##設置連接工具

3添加工程源文件和頭文件/路徑
設置完編譯鏈以後就能夠添加代碼源文件了,這個有好幾個方法,你們也能夠本身百度一下cmake的語法或者找一個教程來實踐一下,拿我本身的文件舉例說明一下:

##file語法,前一個參數是固定的 後面一個參數本身定義
##添加文件的時候注意 相對路徑和絕對路徑
file(GLOB_RECURSE C_FILES
        src/*.c
        src/*.h
        src/drivers/*.c
        src/drivers/*.h
        src/sm9/*.h
        rtt_src/rtconfig.h
        rtt_src/board.c
)
##好比我使用的rtthread的相關文件不想擠在一塊兒,還能夠這樣
file(GLOB_RECURSE KENEL_FILES

    ${RTTHREAD_SDK}/src/*.c
    ${RTTHREAD_SDK}/libcpu/arm/cortex-m4/context_rvds.s
    ${RTTHREAD_SDK}/libcpu/arm/cortex-m4/cpuport.c

    )
##cmake語法比較靈活,空格還有換行這些比較隨意,相比之下makefile就死板不少,常常出現修改以後makefile文件就報錯了
##而後就能夠把文件歸屬爲源碼
set(SOURCE_FILES  ${C_FILES} ${KENEL_FILES})  ##上面file定義了標識符,有幾個寫幾個就好了,靈活配置
##接下來就是包含頭文件路徑,好比某些庫函數這些,直接設置頭文件就行,由於咱們通常不會去改他,包含就行
include_directories(

       ${TOOLCHAIN_DIR}/include

       ## rtthread kenel include
       ${RTTHREAD_SDK}/include
       src
       src/drivers
        src/interface
        src/sm9
        rtt_src
        ./RTE/_nrf52832_xxaa
        ${SDK_ROOT}/components/softdevice/common
        ${SDK_ROOT}/components/libraries/strerror
        ${SDK_ROOT}/components/drivers_nrf/comp
)

4.定義編譯,連接參數
編譯連接參數一樣很重要,影響到編譯的文件的生成,好比說,設置這個有個捷徑,咱們能夠直接從mdk裏面拷貝,這裏以圖片展現好比下面的圖片:
c/c++編譯選項
clipboard.png

clipboard.png
彙編編譯選項
clipboard.png

clipboard.png
連接選項
clipboard.png

clipboard.png
注意連接選項這裏有一個分散加載文件,路徑不要搞錯了,通常是從mdk工程裏面直接拷過來就行,願意研究這個文件的能夠本身研究

而後cmake裏面還有一個語法能夠定義編譯選項:
5.編譯其餘選項

link_libraries("${CMAKE_CURRENT_SOURCE_DIR}/path/to/xxx.lib") #加載靜態庫
#添加可執行文件,依賴上面定義的sourcefile 若是是編譯成靜態庫用add_library()函數,可自行研究
add_executable(${TARGETS} ${SOURCE_FILES} )

至此,就能夠用cmake生成makefile文件而後生成elf文件,生成elf文件以後用fromelf文件轉換成hex文件就好了,在fromelf的目錄用cmd打開,就獲得下面這個指令使用說明:

clipboard.png
固然,不可能每次都手動去敲命令來進行轉換,cmake已經替咱們想到了:

set(ELF_FILE ${TARGETS}.elf)
set(HEX_FILE ${TARGETS}.hex)
set(APP_FILE app_${TARGETS}.hex)
set(BIN_FILE ${TARGETS}.bin)
set(elfPath D:/Keil_v5/ARM/ARMCC/bin/fromelf.exe)
add_custom_command(TARGET ${TARGETS}  POST_BUILD
            COMMAND ${elfPath} --i32 --output=${APP_FILE} ${TARGETS}.exe
)

關於這個指令,網上有不少解釋,能單獨成一篇文章了,這裏只是簡單展現用法,在目標(TARGET )建立以後(POST_BUILD)調用這些指令(COMMAND)具體用法讀者自行理解吧
同時,不少同窗在使用mdk的時候會用過用戶自定義指令,好比:

clipboard.png
不用擔憂,cmake也有,仍是上面那個指令,在hex生成那裏本身添就好了,並且MDK只有兩條,咱們用cmake想寫多少就寫多少

運行cmake編譯固件

至此咱們的cmake就編寫完成了,下面就是在cmakelists.txt文件的目錄運行指令生成目標,好比:
cmake --build .--target all
能夠運行指令後看一看生成的文件
此文完,後續介紹Qtcreater和clion相操做與設置:https://segmentfault.com/a/11...

相關文章
相關標籤/搜索