大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是MCUXpresso IDE下將原始碼製作成Lib庫方法及其與IAR,MDK差異。
程式函數庫是一個包含已經編譯好程式碼和資料的函數集合,這個庫檔案裡的函數可以供其他程式呼叫。被放進庫檔案裡的程式碼通常具有一定通用性,是經過高度抽象的,這樣可以避免重複造輪子。程式函數庫設計可以使得程式的開發工作更加模組化,更容易重新編譯,也更方便升級。
嵌入式開發裡有時候也會需要涉及函數庫檔案,除了模組化開發以及方便升級特點外,有時候也是為了對原始碼進行保密,畢竟庫檔案是編譯後的檔案。今天痞子衡就跟大家聊聊 MCUXpresso IDE 下生成 Lib 庫檔案的方法及其與 IAR, MDK 有何差異。
- Note: 痞子衡測試的MCUXpresso IDE版本是v11.4.0_6224。
我們先來看看其它 IDE 下是如何生成和使用 Lib 庫檔案的。我們以 \SDK_2.10.0_MIMXRT1170-EVK\boards\evkmimxrt1170\demo_apps\hello_world\cm7 目錄下的工程檔案為例。這個 hello_world 例程主要就是利用 LPUART 外設驅動( fsl_lpuart.c )實現串列埠列印功能,這裡我們就嘗試將 fsl_lpuart.c 檔案製作成 Lib 庫(這裡特指靜態連結庫 - Static Library)。
使用 IAR 開啟 hello_world_demo_cm7.eww 檔案,編譯預設工程可以得到工程可執行檔案和映象檔案,這是經過編譯和連結之後的可直接執行的純機器碼資料。由於我們只需要將 fsl_lpuart.c 檔案製作成 Lib 庫,所以要對工程進行一些改動:
1. 將工程裡除 fsl_lpuart.c 之外的其它 .c 檔案全部移除,並且僅需保留 fsl_lpuart.c 所依賴的相關標頭檔案。
2. 在工程選項 General Options / Output / Output file 裡切換到 Library。
3. 在工程選項 Library Builder / Output / Output file 裡命名生成的庫檔案(比如 lpuart_drv.a )。
這時候重新編譯工程便可以得到我們想要的 lpuart_drv.a 庫檔案,如果要使用這個庫檔案的話,也非常簡單,只要在原始的 hello_world 工程裡將 fsl_lpuart.c 檔案替換成 lpuart_drv.a 即可。
MDK 下製作和使用 Lib 庫方法與 IAR 差不多,就是工程設定差異。使用 MDK 開啟 hello_world_demo_cm7.uvprojx 檔案,同樣對工程進行一些改動:
1. 將工程裡除 fsl_lpuart.c 之外的其它 .c 檔案全部移除,並且僅需保留 fsl_lpuart.c 所依賴的相關標頭檔案。
2. 在工程選項 Output / 裡切換到 Create Library。
3. 在工程選項 Output / Name of Executable 裡命名生成的庫檔案(比如 lpuart_drv.lib )。
瞭解了 IAR, MDK 下製作和使用 Lib 庫方法,我們再來看本文的主角 MCUXpresso IDE 下製作 Lib 庫的方法。首先是按照 《MCUXpresso IDE下SDK工程匯入與workspace管理機制》 一文匯入一個 hello_world 工程,在匯入嚮導介面,我們能看到 SDK 裡的例程型別是 C Project,旁邊雖然有 C Static Library 選項,但是不可設定。
我們先使用 SDK 包裡匯出的預設工程(C Project),按照之前 IAR, MDK 上的經驗,在這個工程裡做如下改動。重新編譯工程,發現生成的檔案似乎跟原始工程生成的可執行檔案(Artifact Type 為 Executable )差不多,顯然 Shared Library 並不是我們想要的靜態 Lib 庫。
1. 將工程裡除 fsl_lpuart.c 之外的其它 .c 檔案全部移除,並且僅需保留 fsl_lpuart.c 所依賴的相關標頭檔案。
2. 在工程選項 C/C++ Build / Settings / Build Artifact / Artifact Type 裡切換到 Shared Library。
3. 在工程選項 C/C++ Build / Settings / Tool Settings / MCU Linker / Shared Library Settings 裡 Shared 選項勾選上。
那麼 MCUXpresso IDE 下如何生成靜態 Lib 庫呢?很遺憾,你必須在新建工程之初就確定工程型別為 C Static Library,工程型別確定之後無法僅通過工程選項來切換 C Project 和 C Static Library (這是和 IAR, MDK 不一樣的第一個地方)。在建立 C Static Library 時儘量在嚮導裡將多餘的原始檔選項全部去掉,僅保留我們感興趣的 lpuart 驅動。
新建了 C Static Library 工程後發現工程裡還是殘留了多餘的 .c 檔案(Debug Console 和 device 初始化相關檔案),這時候再手動移除這些 .c 檔案,然後開啟工程選項 C/C++ Build / Settings / Build Artifact / Artifact Type,此時僅有 Static Library 一種選擇。編譯工程可得到 liblpuart_drv.a 檔案(MCUXpresso IDE 特意在使用者設定的庫名加了 lib 字首,這是刻意設計的,後面使用該庫檔案時會用到這個設計),即是我們需要的靜態 Lib 庫檔案。
回到官方 SDK 包裡原始的 hello world 例程裡,此時我們嘗試使用這個 liblpuart_drv.a 檔案,我們將工程目錄下的 fsl_lpuart.c 檔案替換成 liblpuart_drv.a 檔案,直接編譯發現報錯,無法找到 LPUART 相關驅動,顯然工程並沒有直接識別庫檔案(這是跟 IAR, MDK 不一樣的第二個地方),這時候需要更新下工程選項,在 C/C++ Build / Settings / Tool Settings / MCU Linker / Libraries 裡新增 liblpuart_drv.a 庫(包括名字和路徑),這裡特別注意庫名字僅需要填 lpuart_drv,不需要 lib 字首(這就是前面所說的 MCUXpresso IDE 特意設計)。此時再編譯工程,就一切正常了。
在 MCUXpresso IDE 下我們接觸到了兩種庫 Static Library 和 Shared Library,最後再簡單介紹下它倆的差異。
靜態庫是一些 .o 目標檔案的集合,一般以 .a/.lib 形式結尾。靜態庫在程式連結階段使用,連結器將程式要用到的函數從庫中提取出來,並整合到程式中,程式執行不再使用靜態庫了。由於每個程式要用到函數都從庫提取並整合在一起,所以可執行檔案會比較大。
共用庫即動態連結庫,在 Linux 中以 .so(share object) 為字尾,在 Windows 中以 .dll 為字尾。程式開始啟動執行時,載入所需的函數,程式執行時也需要共用庫的支援。共用庫連結出來的檔案比靜態庫要小得多。
所以這其實就是連結方式的差異,連結(Link)是程式被裝載到記憶體執行之前需要完成的一個步驟。連結本身分為靜態連結(Static Link)和動態連結(Dynamic Link)兩種方式。而在嵌入式 MCU 世界裡,我們通常都是用靜態連結這種方式。
至此,MCUXpresso IDE下將原始碼製作成Lib庫方法及其與IAR,MDK差異痞子衡便介紹完畢了,掌聲在哪裡~~~
文章會同時釋出到我的 部落格園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維條碼,就可以在手機上第一時間看了哦。
最後歡迎關注痞子衡個人微信公眾號【痞子衡嵌入式】,一個專注嵌入式技術的公眾號,跟著痞子衡一起玩轉嵌入式。
衡傑(痞子衡),目前就職於恩智浦MCU系統部門,擔任嵌入式系統應用工程師。
專欄內所有文章的轉載請註明出處:http://www.cnblogs.com/henjay724/
與痞子衡進一步交流或諮詢業務合作請發郵件至 https://www.cnblogs.com/henjay724/p/[email protected]
可以關注痞子衡的Github主頁 https://github.com/JayHeng,有很多好玩的嵌入式專案。
關於專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回覆免費(劃重點)答疑。
痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。