Nordic有2套并存的SDK
1、老的nRF5 SDK
2、新的NCS SDK
兩套SDK相互獨(dú)立,
大家選擇其中一套進(jìn)行開發(fā)即可。
一般而言,如果你選擇的芯片是nRF51或者nRF52系列,那么推薦使用nRF5 SDK
如果你選擇的是Nordic最新產(chǎn)品系列,比如nRF53或者nRF9160,那么請選擇NCS SDK
還有一種特殊情況,雖然你選擇的是nRF52芯片,但需要使用最新的一些射頻技術(shù),比如藍(lán)牙測向,藍(lán)牙Mesh v1.1,低功耗藍(lán)牙音頻,那么也需要使用NCS SDK。
換句話說,最新的射頻技術(shù),Nordic都只會在NCS上進(jìn)行開發(fā),而nRF5 SDK將進(jìn)入維護(hù)階段不再增加新的特性(如發(fā)現(xiàn)bug,會對其進(jìn)行修復(fù)的)。
目錄
1、NCS SDK介紹
2、NCS SDK 安裝
2.1 - 百度網(wǎng)盤下載 (僅適用于Windows)
2.2 - 通過nRF connect桌面版直接下載GitHub下載(Windows/ Linux/ macOS)
2.3 - nRF command line tools安裝
3、NCS SDK開發(fā)環(huán)境說明
3.1 - SES 開發(fā)環(huán)境搭建
3.1.1. nRF52項(xiàng)目示例
3.1.2.nRF53項(xiàng)目示例
3.1.3.nRF9160項(xiàng)目示例
3.1.4. 自定義項(xiàng)目裝載示例
3.2 - 命令行方式開發(fā)環(huán)境搭建
3.2.1.nRF52項(xiàng)目示例
3.2.2. nRF53項(xiàng)目示例
3.2.3. nRF9160項(xiàng)目示例
3.3 - 命令行方式開發(fā)環(huán)境搭建
4、NCS SDK項(xiàng)目的配置或選項(xiàng)
4.1 - NSC項(xiàng)目配置介紹(autoconf.h和devicetree_unfixed.h)
4.1.1.Kconfig (Kconfig, prj.conf及autoconf.h)
4.1.2.Device Tree (*.dts, *.overlay及devicetree_unfixed.h)
4.1.3. 配置程序起始地址和大小
4.2 - 圖形化查看Kconfig選項(xiàng)
4.2.1.SES查看
4.2.2.命令行方式查看
5、NCS SDK中幾個(gè)比較重要的目錄
5.1- 例子目錄
5.2 - API目錄
5.3 板子定義目錄
6、開發(fā)你的第一個(gè)NCS程序
6.1- 修改hello_world main.c文件
6.2 - 在項(xiàng)目中添加一個(gè)新的文件blinky.c
6.3 修改blinky.c文件
6.4 編譯和運(yùn)行你的第一個(gè)hello_world程序
6.5 使用prj.conf和
7、開發(fā)你的第一個(gè)multi-image(多image)應(yīng)用
7.1 - 分區(qū)管理 (Partition Manager)
7.2 多image的hello_world程序開發(fā)
8、NCS編譯系統(tǒng)幾個(gè)要注意的點(diǎn)
8.1 - NCS幾個(gè)重要的編譯系統(tǒng)變量
8.2 - conf文件命名規(guī)則及編譯順序
8.3 - overlay 文件命名規(guī)則及編譯順序
nRF5 SDK的介紹
關(guān)于nRF5 SDK的介紹,請參考這篇博文之前的博文,基本上都是基于nRF5 SDK進(jìn)行闡述的,尤其是這篇:
Nordic nRF51/nRF52開發(fā)環(huán)境搭建
詳細(xì)講解了nRF5 SDK開發(fā)環(huán)境的搭建,這里不再贅述。下面將只對NCS SDK進(jìn)行闡述,以期讓大家快速了解這個(gè)Nordic最新SDK,并盡快熟悉和上手。
1、NCS SDK介紹
NCS全稱nRF Connect SDK,是Nordic最新的SDK平臺,該平臺將支持Nordic所有產(chǎn)品線,包括低功耗藍(lán)牙,蜂窩網(wǎng),2.4G,藍(lán)牙Mesh,Zigbee,Thread,CHIP等。
換句話說,由于短距離無線網(wǎng)絡(luò)和長距離無線網(wǎng)絡(luò)共用同一個(gè)SDK,將使得你同時(shí)具備兩種網(wǎng)絡(luò)的開發(fā)經(jīng)驗(yàn),因?yàn)樗麄兊目蚣苁且粯拥模?qū)動是一樣的,網(wǎng)絡(luò)協(xié)議棧的編寫風(fēng)格也是相仿的。
只要你熟悉了其中一種網(wǎng)絡(luò)的開發(fā),那么相關(guān)的經(jīng)驗(yàn)可以迅速復(fù)制到新網(wǎng)絡(luò)平臺上。
NCS SDK內(nèi)嵌Zephyr RTOS,并沿用了Zephyr project的編譯系統(tǒng)。Zephyr Project是Linux基金會推出的一個(gè)Apache2.0開源項(xiàng)目,版權(quán)非常友好,適合用于商業(yè)項(xiàng)目開發(fā)。
°Zephyr Project
Zephyr Project是一個(gè)合作社區(qū),其產(chǎn)品就是Zephyr,具體包括Zephyr RTOS,Zephyr組件以及Zephyr編譯系統(tǒng)等
Zephyr很多地方都模擬了Linux,比如使用了DeviceTree和Kconfig,對Linux很熟的同學(xué),閱讀Zephyr代碼會感到很親切的
經(jīng)常有人問:為什么NCS要使用Zephyr RTOS?
其實(shí)答案就蘊(yùn)含在Zephyr Project的愿景中:The Zephyr Project strives to deliver thebest-in-class RTOS for connected resource-constrained devices, built be secureand safe
Zephyr的愿景跟Nordic的產(chǎn)品策略高度吻合,這也是為什么Nordic要選Zephyr的主要原因
NCS SDK和Zephyr Project兩者最大的區(qū)別有3個(gè):
owner不同,NCS SDK由Nordic負(fù)責(zé),Zephyr SDK由Linux基金會負(fù)責(zé)。NCS開發(fā)中碰到的所有問題,Nordic都將負(fù)責(zé)解決
產(chǎn)品管理不一樣,NCS SDK將由Nordic完成所有相關(guān)測試和考核,并符合Nordic產(chǎn)品開發(fā),測試,發(fā)布和質(zhì)量控制流程,因此NCS有自己的版本,并跟Zephyr版本控制解耦
NCS具有很多增強(qiáng)特性,比如Nordic特有的藍(lán)牙鏈路層等
所以,從產(chǎn)品角度看,NCS SDK和Zephyr SDK是兩套完全不同的SDK。但是,如果從代碼角度看,那么NCS SDK和Zephyr SDK又基本上是一樣的。
在本文章的下面部分,在不引起混淆的情況下,經(jīng)常會把NCS和Zephyr兩個(gè)概念換著使用,因?yàn)楸举|(zhì)上他們是一個(gè)東西。
°NCS使用了CMake編譯系統(tǒng)
并使用了大量Python腳本以輔助生成一些頭文件,代碼和hex,這些都大大增加開發(fā)的可移植性和便利性。
°NCS SDK放在GitHub上
里面包含多個(gè)代碼庫,其主代碼庫(Manifest)是nrf,同時(shí)還包含Zephyr,MCUBoot,mbedtls,nrfxlib等其他代碼庫。NCS SDK可以同時(shí)在Windows,macOS和Linux上運(yùn)行。
°于Zephyr和NCS的build系統(tǒng)是一樣的
于Zephyr和NCS的build系統(tǒng)是一樣的,如果你正在學(xué)習(xí)Zephyr RTOS,那么也可以參考本篇文章,從NCS SDK開始學(xué)習(xí)Zephyr。由于NCS SDK新增了很多特性,比如圖形化的DEBUG,豐富的例程,你會發(fā)現(xiàn)從NCS SDK學(xué)習(xí)Zephyr是一條便捷通道。
2、NCS SDK安裝
NCS SDK開發(fā)包比較大,目前大概4G(后續(xù)有可能會更大),由于GitHub網(wǎng)絡(luò)帶寬的問題,很多人下載的時(shí)候會出現(xiàn)超時(shí)錯(cuò)誤,為此我們提供如下兩種安裝方案。
如果你能在早上6點(diǎn)左右起床,請參考2.2方案(GitHub直接下載);如果你不想早點(diǎn)起來,請參考2.1方案(百度網(wǎng)盤下載)。
°2.1 百度網(wǎng)盤下載(僅適用于Windows)
代碼鏈接
地址如下所示:
下載鏈接:https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog
提取碼:y8fb
進(jìn)入目錄“開發(fā)你的第一個(gè)NCS(Zephyr)應(yīng)用程序”,選擇相應(yīng)的版本,推薦使用最新版本。本篇博文完成之時(shí)最新量產(chǎn)tag為:
ncs_v1.4.1
后續(xù)還會有ncs_v1.5.0,ncs_v1.6.0等。
直接把相應(yīng)的壓縮包下載下來并解壓到本地目錄,SDK即算安裝完成。
注意,這個(gè)壓縮包只能在Windows系統(tǒng)上運(yùn)行,不能在Linux和macOS上運(yùn)行。
*注:ncs_v1.4.99-dev1是專為nRF53準(zhǔn)備的一個(gè)臨時(shí)開發(fā)版本,量產(chǎn)版本需要等到v1.5.0或者更新。
°2.2 通過nRF connect桌面版直接GitHub下載(同時(shí)支持Windows, Linux和macOS)
采用這個(gè)方案,你必須早上6:00左右起床,切記!
首先,下載桌面版nRF connect (同時(shí)支持Windows/macOS/Linux平臺)。下載鏈接為:
https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Connect-for-desktop/Download#infotabs,選擇你的平臺和版本。
桌面版nRF connect安裝成功后,將如下所示:
在nRF connect桌面版中有2個(gè)app都可以完成NCS SDK安裝:
一個(gè)是Toolchain Manager
一個(gè)是Getting Started Assistant
如果你是GitHub老手,可以按照Getting Started Assistant的步驟一步一步來安裝。如果你嫌一步一步安裝麻煩,那么建議你使用Toolchain Manager一鍵安裝。
下面將會以Toolchain Manager的方式(支持Windows和macOS)來講解安裝過程(Getting Started Assistant的方式自己有興趣可以自己去摸索,而且Linux系統(tǒng)目前只能采用這種方式)。
首先install Toolchain Manager,然后open,進(jìn)入settings界面,選擇安裝目錄,如下:
然后重新選擇SDK ENVIRONMENTS頁面,并選擇SDK相應(yīng)版本進(jìn)行安裝,如下所示:
根據(jù)網(wǎng)速不同,這個(gè)過程持續(xù)時(shí)間變化很大,我這邊網(wǎng)絡(luò)大概需要20分鐘完成所有下載和安裝,安裝成功后你將得到如下目錄內(nèi)容:
°2.3nRF command line tools安裝
下載完SDK壓縮包,再下載 “nRF-Command-Line-Tools_10_11_1_Installer.exe”, 即nRF command line tools,nRFcommand line tools包括Jlink驅(qū)動以及Nordic自己開發(fā)的一些命令行工具,如nrfjprog,nrfutil以及mergehex等,這些工具對開發(fā)非常有幫助。nRF command line tools下載鏈接為: https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools/Download#infotabs
3、NCS SDK開發(fā)環(huán)境說明
NCS支持的工具鏈有2套:
一套是SEGGER Embedded Studio,簡稱SES,圖形化的IDE
一套是命令行方式(沿用了Zephyr工具鏈),其實(shí)就是GCC工具鏈
兩套工具鏈選其一即可,推薦大家使用SES,因?yàn)樗膁ebug功能非常好使。(GCC工具鏈的debug功能使用起來就比較復(fù)雜了)。
下面將分別對SES和命令行方式兩種開發(fā)環(huán)境進(jìn)行介紹,大家可以參考其中一種或者兩種結(jié)合一起使用。
°3.1SES開發(fā)環(huán)境搭建
通過百度網(wǎng)盤或者Toolchain Manager安裝的SDK,必須進(jìn)入如下目錄:install folder oolchain并雙擊SEGGER Embedded Studio.cmd以打開SES,而不能在其他地方直接打開SES,如下所示:
SES啟動成功后,進(jìn)入Tools->Options,我們需要先對IDE進(jìn)行配置。
如下兩種方式的配置有可能都能工作起來,選擇一種適合你的(一般來說,推薦配置二,這個(gè)配置方式可以適用任何電腦環(huán)境)。
°配置一:
°配置二:
配置好了之后,我們就可以打開一個(gè)工程進(jìn)行編譯了。進(jìn)入File->Open nRF Connect SDK Project。
在NCS中,項(xiàng)目是通過CMakeLists.txt表示的,如下:
而開發(fā)板一般是在如下目錄的:
選擇開發(fā)板,就是選擇芯片,除此之外,開發(fā)板還規(guī)定了芯片的一些外設(shè)使能情況,以及一些基本外圍電路連接情況,這個(gè)跟Keil如下選擇Device的操作是異曲同工的,而且NCS這種做法更靈活,功能也更多,擴(kuò)展性也更好。
如下為hello_world項(xiàng)目的裝載圖:
下面將對nRF52/nRF9160/nRF53項(xiàng)目,以及客戶自定義項(xiàng)目,分別進(jìn)行闡述,以詳細(xì)說明如何裝載一個(gè)項(xiàng)目,編譯一個(gè)項(xiàng)目,下載一個(gè)項(xiàng)目和debug一個(gè)項(xiàng)目。 °3.1.1nRF52項(xiàng)目示例 以nrfapplications rf_desktop項(xiàng)目為例,開發(fā)板選擇支持LLPM的gaming mouse:nrf52840gmouse_nrf52840
裝載成功后,編譯,如下所示:
然后下載,如下所示:
如果要Debug,按如下界面進(jìn)入:
°3.1.2nRF53項(xiàng)目示例 Nordic第一個(gè)支持nRF53的tag是v1.4.99-dev1,v1.5.0將正式支持nRF53的量產(chǎn)開發(fā),如果你需要開發(fā)nRF53,請使用v1.4.99以上版本。 由于nRF53包括兩個(gè)核:
app核:用來運(yùn)行應(yīng)用程序
network核:network核用來運(yùn)行射頻協(xié)議棧
所以每次下載的時(shí)候需要同時(shí)把兩個(gè)核的hex都下載進(jìn)去,但是SES只支持一次下載一個(gè)核(west可以同時(shí)下載兩個(gè)核,具體請參考第3.2節(jié))。 在使用SES開發(fā)nRF53的時(shí)候,項(xiàng)目裝載/編譯/下載/debug跟其他芯片是一樣的,但這些操作只是針對一個(gè)核(一般來說都是app核),此時(shí)如果還需要network核配合的話,那么需要你手動先把network核的image下載進(jìn)去,這個(gè)可以通過nrfjprog或者west來完成。
這里要強(qiáng)調(diào)一點(diǎn)的是,當(dāng)你選擇一個(gè)藍(lán)牙項(xiàng)目,這個(gè)項(xiàng)目默認(rèn)會同時(shí)把a(bǔ)pp核和network核對應(yīng)的工程都進(jìn)行編譯,然后生成各自的hex文件,然后你通過nrfjprog或者west把network核的image下載進(jìn)去,通過SES本身的Target->Download菜單把a(bǔ)pp核的image下載進(jìn)去。 以nrfsamplesluetoothperipheral_uart藍(lán)牙透傳項(xiàng)目為例:
編譯如下所示:
編譯成功后,先下載network核里面的image,我們以west flash來下載。進(jìn)入目錄: nrfsamplesluetoothperipheral_uartuild_nrf5340dk_nrf5340_cpuapphci_rpmsg,然后在cmd輸入: west flash 即可將image下載到network核里面,如下所示:
如果west flash在你的環(huán)境跑不通,那么你可以直接使用nrfjprog來下載network核的image,進(jìn)入目錄: nrfsamplesluetoothperipheral_uartuild_nrf5340dk_nrf5340_cpuapphci_rpmsg,然后在cmd輸入如下命令: nrfjprog -f NRF53 --coprocessor CP_NETWORK --sectorerase--program merged_CPUNET.hex --verify
然后下載app核image,app核image可以直接通過SES下載,如下:
如需debug,按如下界面進(jìn)入:
°3.1.3 nRF9160項(xiàng)目示例 以nrfsamples rf9160mqtt_simple項(xiàng)目為例:
編譯如下所示:
下載如下所示:
如需debug,按如下界面進(jìn)行:
°3.1.4 自定義項(xiàng)目裝載示例 如果是你的自定義項(xiàng)目或者Zephyr項(xiàng)目或者不使用toolchain自帶的SES,此時(shí)就不能使用SES自帶的快捷方式來裝載項(xiàng)目,而需要自己去相應(yīng)的目錄找到項(xiàng)目工程和開發(fā)板,比如我們裝載Zephyr的blinky例子。先選擇項(xiàng)目工程CMakeLists.txt所在的目錄,如下:
再選擇相應(yīng)的開發(fā)板,如下:
然后項(xiàng)目就裝載成功了,如下:
后面編譯,下載和調(diào)試,和之前一樣,就不再贅述。 °3.2 命令行方式開發(fā)環(huán)境搭建 NCS或者Zephyr項(xiàng)目命令行編譯的時(shí)候,一般使用west命令,west語法可以通過west –help獲得,如下:
如果你能看到上面的界面,那么你的環(huán)境基本上就沒問題了。 一個(gè)典型的west命令如下所示: west build -bnrf52840dk_nrf52840 *注:-b指定開發(fā)板,這里使用nRF52840開發(fā)板 通過百度網(wǎng)盤或者Toolchain Manager安裝的SDK,必須進(jìn)入如下目錄:install folder oolchain并雙擊git-cmd.cmd以打開命令行,而不能直接打開CMD,如下所示:
git-cmd.cmd會自動把環(huán)境變量設(shè)好,否則后續(xù)編譯會有問題。 下面分別以nRF52/nRF53/nRF9160開發(fā)為例,展示相應(yīng)的編譯和下載命令。 °3.2.1 nRF52項(xiàng)目示例
下面以編譯nrfapplications rf_desktop項(xiàng)目為例來講解。首先進(jìn)入項(xiàng)目所在的目錄
cd nrfapplications rf_desktop 界面將如下所示:
由于已經(jīng)進(jìn)入了項(xiàng)目所在的目錄,編譯的時(shí)候就無需再指定項(xiàng)目目錄了,由于nrf_desktop支持多個(gè)開發(fā)板,我們還需要指定用哪一個(gè)開發(fā)板,如下所示: west build -bnrf52840gmouse_nrf52840 或者 west build -bnrf52840gmouse_nrf52840 -p *注:-p用來清除build目錄緩存
由于上面沒有指定build目錄,上面的命令會自動生成一個(gè)build目錄(名字就是build),然后所有的編譯文件會自動放在該build目錄下: build目錄如下所示:
編譯成功后,就可以燒寫了,使用如下命令進(jìn)行燒寫: west flash 或者 west flash –erase
°3.2.2nRF53項(xiàng)目示例 以nrfsamplesluetoothperipheral_uart為例來講解。首先進(jìn)入目錄:nrfsamplesluetoothperipheral_uart,然后輸入如下編譯命令: west build -bnrf5340dk_nrf5340_cpuapp--build-dir build_nrf5340dk_nrf5340_cpuapp -p *注:-b指定開發(fā)板,--build-dir指定編譯目錄,-p清除老的編譯目錄內(nèi)容
編譯成功后,就可以燒寫了,使用如下命令進(jìn)行燒寫:
west flash--build-dir build_nrf5340dk_nrf5340_cpuapp
°3.2.3nRF9160項(xiàng)目示例
以nrfsamples rf9160mqtt_simple為例來講解。首先進(jìn)入目錄: nrfsamples rf9160mqtt_simple 然后輸入如下編譯命令: west build -bnrf9160dk_nrf9160ns --build-dir build_nrf9160dk_nrf9160ns -p *注:-b指定開發(fā)板,--build-dir指定編譯目錄,-p清除老的編譯目錄內(nèi)容
編譯成功后,就可以燒寫了,使用如下命令進(jìn)行燒寫: west flash--build-dir build_nrf9160dk_nrf9160ns
°3.3 NCS SDK版本說明 NCS SDK開發(fā)包目錄如下所示:
可以看出,NCS SDK包含nrf,zephyr,bootloader,nrfxlib,modules等多個(gè)代碼庫,其中nrf代碼庫就是NCS SDK的主代碼庫(manifest),nrf代碼庫的版本就是NCS SDK的版本,所以要查看NCS SDK當(dāng)前版本號,進(jìn)入nrf目錄,輸入git branch,如下:
熟悉git的同學(xué)都知道,一個(gè)SDK如果包含多個(gè)代碼庫,那么每個(gè)代碼庫都有自己的版本,而且代碼庫版本之間是相互關(guān)聯(lián)的。 以NCS SDK為例,當(dāng)nrf版本切換為v1.4.0時(shí),其他代碼庫的版本也需要做相應(yīng)切換。 那么對應(yīng)nrf v1.4.0的Zephyr代碼庫版本是多少呢?mcuboot代碼庫版本是多少呢?
如果直接使用git工具,那么你需要一個(gè)一個(gè)記,然后一個(gè)一個(gè)checkout。在NCS或者Zephyr中,引入了west工具,這樣通過管理nrf代碼庫版本就可以間接管理其他代碼庫的版本,比如我們現(xiàn)在把NCS SDK版本切換到v1.4.0,指令如下所示: git checkout v1.4.0 然后通過west update命令,就可以讓其他代碼庫版本自動跟v1.4.0 nrf代碼庫同步,這樣你不需要記住或者管理其他代碼庫版本,只需管理nrf代碼庫版本即可。 west update
4、NCS 項(xiàng)目的配置或選項(xiàng)
°4.1 NCS項(xiàng)目配置介紹(autoconf.h和devicetree_unfixed.h)
每一個(gè)NCS或者Zephyr項(xiàng)目都包含了非常多的配置項(xiàng)或選項(xiàng),總數(shù)有可能達(dá)幾千項(xiàng)之多,然而絕大多數(shù)配置項(xiàng)我們都不需要去管他們,只需要使用默認(rèn)值即可,所以開發(fā)一個(gè)簡單的NCS應(yīng)用程序,有可能我們不需做任何配置,就可以跑起來。
當(dāng)你開發(fā)復(fù)雜的應(yīng)用程序的時(shí)候,你又會體會到NCS配置的靈活性和方便性了,這其實(shí)也是NCS一個(gè)很大的優(yōu)勢。
本章我們先講如何查看配置項(xiàng),后面一章我們再以例子來說明如何更改配置項(xiàng)。
NCS或者Zephyr里面主要包含兩種配置項(xiàng):
Kconfig:主要負(fù)責(zé)軟件的配置
DeviceTree:主要負(fù)責(zé)板子硬件的配置
兩者最終都會生成一個(gè).h文件,其Kconfig生成的頭文件為:autoconf.h,而DeviceTree生成的頭文件為devicetree_unfixed.h,他們都在如下目錄:
autoconf.h文件示例如下:
devicetree_unfixed.h文件示例如下:
如果大家開發(fā)過nRF5 SDK的話,一定記得里面有個(gè):sdk_config.h,從機(jī)理上,sdk_config.h和上面的autoconf.h/devicetree_unfixed.h并沒有本質(zhì)區(qū)別,他們都是完成同樣的功能。 但是很多人都覺得Kconfig和DeviceTree很復(fù)雜,其實(shí)他們復(fù)雜之處在于如何生成這兩個(gè)頭文件,但是頭文件本身并不復(fù)雜。 在nRF5 SDK中,用戶可以直接修改sdk_config.h文件,由于sdk_config.h文件太大,所以Nordic使用了CMSIS_Configuration_Wizard來格式化這個(gè)頭文件,以形成如下的圖形化界面方便大家去修改它:
在NCS或者Zephyr里面,由于autoconf.h/devicetree_unfixed.h是由Python腳本自動生成的,所以用戶不能直接修改autoconf.h/devicetree_unfixed.h這兩個(gè)頭文件。 用戶只能去修改生成這兩個(gè)頭文件的輸入,以達(dá)到間接修改他們的目的。這樣做的好處是:更靈活,而且不容易出錯(cuò)(Python會自動幫你找出配置不合理的地方或者語法錯(cuò)誤)。 可以說,一旦你熟悉了這套配置機(jī)制,你就會愛上它。 下面分別對autoconf.h和devicetree_unfixed.h兩者的生成過程進(jìn)行闡述。 °4.1.1 Kconfig(Kconfig, prj.conf及autoconf.h) 我們先把生成autoconf.h文件的整體流程圖貼出來,后面再對這個(gè)圖進(jìn)行解釋:
autoconf.h文件是由許許多多的Kconfig文件生成的(注:其實(shí)Kconfig來源于Linux系統(tǒng),NCS或者Zephyr對其進(jìn)行了繼承和定制),基本上每個(gè)模塊都有自己的Kconfig文件,比如藍(lán)牙controller模塊:
使用文本編輯器打開Kconfig,你將會看到它的內(nèi)容大概如下所示:
除了系統(tǒng)模塊可以定義Kconfig文件,你自己的項(xiàng)目模塊也可以定義自己的Kconfig文件。 如何定義? 依葫蘆畫瓢,仿照例子來即可。 記住,在NCS或者Zephyr里面,只要可以用文本編輯器打開的文件,他們的語法都是直接可讀的,不需要你另外去學(xué)習(xí)他們,直接仿照例子,你就可以定制自己的內(nèi)容。 除了Kconfig,autoconf.h還有一個(gè)輸入來源: 本項(xiàng)目的配置文件。 前面說過,Kconfig文件都是模塊自帶的,模塊為每一個(gè)選項(xiàng)都設(shè)了一個(gè)默認(rèn)值。 如果你想修改這個(gè)默認(rèn)值,怎么辦? 你不需要跑到模塊下面直接把Kconfig文件改了(這樣不方便,而且也會影響到其他項(xiàng)目工程的運(yùn)行)。為此NCS或者Zephyr引入了prj.conf文件,prj.conf文件內(nèi)容大概如下所示:
通過prj.conf,大家就可以更改默認(rèn)的Kconfig選項(xiàng)了,而且這個(gè)更改是永久的,并只適用于本項(xiàng)目。 所有的Kconfig和prj.conf結(jié)合,先生成一個(gè).conf文件,最后再生成autoconfig.h。.conf文件在如下目錄:
其內(nèi)容大概如下所示:
可以看出,.config文件格式更接近Kconfig和prj.conf,起到了一個(gè)中間橋梁作用。 .config和autoconfig.h兩者內(nèi)容是可以一一對應(yīng)的,因此大部分圖形配置系統(tǒng)都是直接調(diào)用.config文件來完成圖形化配置Kconfig的,后面我們會講解如何使用SES和menuconfig來圖形化配置.config文件。 .config是一個(gè)臨時(shí)文件,編譯系統(tǒng)默認(rèn)會以它為基準(zhǔn)來生成autoconfig.h,所以一旦你的Kconfig或者prj.conf更新了,記得一定要重新裝載項(xiàng)目,以更新.config文件,從而生成新的autoconfig.h文件。 °4.1.2Device Tree (*.dts, *.overlay及devicetree_unfixed.h) 同樣我們先把生成devicetree_unfixed.h的整體流程圖列出來,后面再對其進(jìn)行解釋:
DeviceTree也是Linux里面的概念,NCS或者Zephyr對其進(jìn)行了繼承和定制。在DeviceTree里面,每一種硬件比如芯片或者板子,都可以使用DeviceTree語言進(jìn)行描述。 DeviceTree使用了樹形結(jié)構(gòu),按照層級關(guān)系把板子包含的組件一一描述清楚,每塊板子都會定義一個(gè)dts文件,比如nrf52840dk_nrf52840開發(fā)板,它對應(yīng)的dts文件是nrf52840dk_nrf52840.dts,其內(nèi)容如下所示:
可以看到板子dts文件包含了一個(gè)nrf52840_qiaa.dtsi,nrf52840_qiaa.dtsi對應(yīng)的就是nRF52840這顆芯片本身的dts文件。nrf52840 dtsi里面定義的內(nèi)容,nRF52840dk開發(fā)板直接包含進(jìn)來,然后在此基礎(chǔ)上進(jìn)行定制。 比如dtsi里面將UART0配置為關(guān)閉,nRF52840dk可以將其改配為使能;另一種需要修改的情況,nRF52840dk增加了一些其他組件 比如LED/Button/外部Flash等,這些設(shè)備都可以成為nrf52840dk_nrf52840.dts里面的一個(gè)節(jié)點(diǎn)。
nrf52840dk_nrf52840.dts是一種比較簡單的板子,因此一個(gè)dts文件就可以將其表達(dá)清楚。我們還會碰到一種情況,幾塊板子大部分特性都是相同的,只有少數(shù)組件不一樣,這個(gè)時(shí)候,我們會把相同的地方拎出來組成一個(gè)common.dts,然后這幾塊板子再引用這個(gè)common.dts文件,比如目錄: zephyroardsarm rf9160dk_nrf9160,里面包含兩塊開發(fā)板:
nrf9160dk_nrf9160ns
nrf9160dk_nrf9160
兩塊開發(fā)板內(nèi)容基本上是一樣的,所以在這里把相同的內(nèi)容拎出來組成了一個(gè):
nrf9160dk_nrf9160_common.dts
然后nrf9160dk_nrf9160ns.dts和nrf9160dk_nrf9160.dts
再引用nrf9160dk_nrf9160_common.dts
這樣拆分一下,邏輯關(guān)系更清晰,將使系統(tǒng)變得更靈活,擴(kuò)展性更好。
除了
通過
其內(nèi)容大概如下所示:
可以看出zephyr.dts就是
在NCS或者Zephyr中,如果是一個(gè)單image應(yīng)用,程序的起始地址和大小是在DeviceTree中配置的,如下:
對于單image應(yīng)用,最有用的就是上面三個(gè)紅框標(biāo)出來的地方,其他配置選項(xiàng)你可以忽略不管,一般來說能改的就一項(xiàng): storage_partition的起始地址和大小, storage_partition就是分配給用戶用來存儲數(shù)據(jù)的區(qū)域。 一般來說,無線IoT應(yīng)用都是要求具有固件升級功能,為了升級固件,BootLoader就必不可少,此時(shí)一個(gè)應(yīng)用至少有兩個(gè)image:BootLoader對應(yīng)的image,以及app對應(yīng)的image,對于這種多image應(yīng)用,程序起始地址和大小配置一般不通過DeviceTree直接來修改,而是交由partition manager(PM)模塊來管理,具體請參考第7章:開發(fā)你的第一個(gè)multi-image(多image)應(yīng)用。
°4.2圖形化查看Kconfig選項(xiàng) 上面說了,大家可以通過.config文件去查看最終的Kconfig配置,然后通過zephyr.dts文件去查看最終的DeviceTree配置。 zephyr.dts文件不是很大,因此推薦使用這種方法去查看。但是.config文件有點(diǎn)長,直接查看它有點(diǎn)累,而且容易搞錯(cuò),為此NCS推出了兩個(gè)圖形化查看工具:SES配置和基于命令行方式的menuconfig或者guiconfig °4.2.1SES查看項(xiàng) 進(jìn)入Project->Configure nRF Connect SDK Project,如下所示:
由于一個(gè)項(xiàng)目的配置項(xiàng)太多,我們一般在右上角搜索配置項(xiàng)名字,找到它,然后查看它的說明。同時(shí)我們可以去嘗試修改它,修改成功后,點(diǎn)擊“Configure”,配置才能生效。 通過圖形化界面進(jìn)行修改,我們可以很快找到合適的配置選項(xiàng),當(dāng)大家對系統(tǒng)還不是很熟的時(shí)候,推薦使用這種方式去試錯(cuò)。這里強(qiáng)調(diào)一下,通過這種方式所做的修改是臨時(shí)的,一旦項(xiàng)目重啟或者緩存刷新了,這里的更改就會失效,所以我們一般推薦使用上面的prj.conf去永久修改配置項(xiàng)。
對于multi-image(多image)應(yīng)用,點(diǎn)擊Project->Configure nRF Connect SDK Project,會同時(shí)出現(xiàn)所有image的配置菜單,其中“menuconfig”對應(yīng)的是主應(yīng)用的配置項(xiàng)(其他menuconfig對應(yīng)的是子image的配置項(xiàng),具體請參考第7章:開發(fā)你的第一個(gè)multi-image(多image)應(yīng)用),如下:
°4.2.2命令行方式查看項(xiàng) 命令行方式使用如下命令查看項(xiàng)目配置: west build -tmenuconfig 執(zhí)行上述命令后,將顯示如下界面:
注:上述命令需要先安裝windows-curses ,即在cmd中執(zhí)行如下命令:pip install windows-curses –user,此命令的執(zhí)行需要聯(lián)網(wǎng)。如果你的電腦無法聯(lián)網(wǎng),建議使用guiconfig查看工程配置,其對應(yīng)的命令為: west build -tguiconfig 執(zhí)行上述命令后顯示的界面如下所示:
由于一個(gè)項(xiàng)目的配置項(xiàng)太多,我們一般使用Jump to進(jìn)行搜索,找到它,然后查看它的說明。同時(shí)我們可以去嘗試修改它,修改成功后,選擇“Save”,配置才能生效。 通過圖形化界面進(jìn)行修改,我們可以很快找到合適的配置選項(xiàng),當(dāng)大家對系統(tǒng)還不是很熟的時(shí)候,推薦使用這種方式去試錯(cuò)。這里強(qiáng)調(diào)一下,通過這種方式所做的修改是臨時(shí)的,一旦項(xiàng)目重啟或者緩存刷新了,這里的更改就會失效,所以我們一般推薦使用上面的prj.conf去永久修改配置項(xiàng)。 5、NCS SDK中幾個(gè)比較重要的目錄
如前所述,NCS SDK中包括了多個(gè)代碼庫,每個(gè)代碼庫都是相互獨(dú)立的,而且每個(gè)代碼庫包含的代碼都很多,如果一行一行代碼讀下去,那將是一個(gè)無底洞。所以實(shí)際開發(fā)中,我們都是參考例子,按照例子去做,碰到不懂的API,再去看API說明,循環(huán)往復(fù),最終完成自己的開發(fā)。 °5.1例子目錄 我們先說說例子所在的目錄。NCS中商業(yè)級的應(yīng)用程序是放在如下目錄: nrfapplications
如果你的應(yīng)用跟上面的應(yīng)用相似,那么推薦使用上面的例子,因?yàn)樗麄兓旧蠈儆趖urn-key級的方案,跟成熟的商業(yè)應(yīng)用差不多,你需要的開發(fā)工作量最少。 其次是如下例子目錄nrfsamples,這個(gè)都是Nordic自己開發(fā)的一些例程:
然后就是Zephyr自帶的例子zephyrsamples:
大家有時(shí)候會覺得NCS或者Zephyr例子還是不夠多,比如很多驅(qū)動API怎么用,好像沒有例子。其實(shí)Zephyr所有API的的使用,都可以在zephyr ests下面找到示例,所以當(dāng)你找不到例子的時(shí)候,不妨在這里找一找:
°5.2API目錄 NCS里面這么多API,到底該使用哪些API?API說明又在哪里? 一般而言,我們只使用代碼庫里面的include目錄下的API,API說明也在那里。 比如nrf代碼庫的include目錄: nrfinclude
Zephyr標(biāo)準(zhǔn)API的include目錄zephyrinclude:
其他代碼庫也是遵守這個(gè)規(guī)范的,比如Nordic開發(fā)的底層驅(qū)動API(與RTOS無關(guān)): moduleshal ordic rfxdriversinclude
*注:有些人會問:
moduleshal ordic rfxdriversinclude
zephyrincludedrivers
兩個(gè)目錄里面的驅(qū)動API,我到底該使用哪個(gè)呢?
zephyrincludedrivers這個(gè)是Zephyr標(biāo)準(zhǔn)的驅(qū)動API,按照Zephyr標(biāo)準(zhǔn)來定義的,它調(diào)用了底層API:
moduleshal ordic rfxdriversinclude
moduleshal ordic rfxdriversinclude這里面的API都是Nordic自己實(shí)現(xiàn)的,跟平臺無關(guān)。
所以說,一般推薦使用zephyrincludedrivers這里面的API,只有這里面沒有或者實(shí)現(xiàn)不了的功能(比如將同一個(gè)引腳動態(tài)分配給UART和SPI,Zephyr標(biāo)準(zhǔn)API就無能為力),這個(gè)時(shí)候才使用moduleshal ordic rfxdriversinclude這里面的API。 °5.3 板子定義目錄 通過在cmd輸入: west boards 就可以查看目前Zephyr支持哪些標(biāo)準(zhǔn)板子:
上面這些板子都是在如下目錄定義的:
zephyroardsarm。 由于Cortex-M33內(nèi)核支持secure和non-secure(ns)兩種應(yīng)用,所以每一個(gè)Cortex-M33內(nèi)核都包含兩種硬件定義:安全和非安全。 比如nrf9160dk,雖然物理上只有一塊板子,邏輯上我們把它劃分成兩塊板子:
nrf9160dk_nrf9160是跑安全應(yīng)用
而nrf9160dk_nrf9160ns是跑非安全應(yīng)用
同樣nRF5340dk,雖然物理上只有一塊板子,但是它有兩個(gè)核都可以供用戶使用,其中app核既可以跑安全應(yīng)用又可以跑非安全應(yīng)用,而網(wǎng)絡(luò)核只能跑一種應(yīng)用類型,所以nrf5340dk在邏輯上就劃分成三塊板子:
nrf5340dk_nrf5340_cpuapp(app核,跑安全應(yīng)用)
nrf5340dk_nrf5340_cpuappns(app核,跑非安全應(yīng)用)
以及nrf5340dk_nrf5340_cpunet(network核,跑非安全應(yīng)用)
除了這些標(biāo)準(zhǔn)Zephyr板子,NCS還有一些自定義板子,他們在如下目錄: nrfoardsarm
如果你要自定義自己的板子,可以參考上面例子來。 6、開發(fā)你的第一個(gè)NCS 程序
現(xiàn)在我們開始我們第一個(gè)NCS程序或者Zephyr程序的開發(fā),在NCS中,有如下兩個(gè)現(xiàn)成的例子:
zephyrsampleshello_world:hello_world例子就是在串口中打印一串字符串
zephyrsamplesasiclinky:而blinky例子就是讓開發(fā)板的LED1一閃一閃
這兩個(gè)程序直接就可以編譯和運(yùn)行,而且應(yīng)該所有的Zephyr開發(fā)板都可以跑這兩個(gè)程序。現(xiàn)在我們把這兩個(gè)程序合成一個(gè)程序,即既打印字符串給串口助手,又讓開發(fā)板LED1一閃一閃,同時(shí)我們把字符串打印變成循環(huán)打印,并將字符串同時(shí)輸出到串口助手和RTT viewer。 下面我們一步一步給大家演示這個(gè)開發(fā)過程。
開發(fā)NCS程序
本章所有代碼可以到如下百度網(wǎng)盤鏈接獲取,進(jìn)入“開發(fā)你的第一個(gè)NCS(Zephyr)應(yīng)用程序”->“hello_world”,下載hello_world_ncsv140.rar:
下載鏈接:
https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog
提取碼:y8fbz
°6.1 修改hello_world main.c文件 首先,我們以hello_world例子為基礎(chǔ),將這個(gè)例子拷到一個(gè)其他目錄下(任何目錄都可(不要有中文和空格等),只要你的環(huán)境變量都設(shè)好了,所有NCS例子的目錄可以隨意更改,這個(gè)真是非常方便!),這里讓大家拷貝到其他目錄,只是為了演示NCS編譯路徑的依賴性做得非常好,沒有別的意思。 如果你不想拷貝,也沒關(guān)系,咱們可以直接在原始目錄上進(jìn)行修改,NCS自帶git管理系統(tǒng),非常方便你進(jìn)行版本管理。我們做如下修改,以循環(huán)打印同一條日志:
°6.2 在項(xiàng)目中添加一個(gè)新文件blinky.c 然后把blinky代碼加到hello_world,這里面就會用到添加一個(gè)新文件的技能。我們先把zephyrsamplesasiclinkysrc里面的main.c改名為blinky.c,然后拷貝到hello_worldsrc目錄下。 如何把blinky.c添加到項(xiàng)目中來呢? 推薦的方法是修改CMakelists.txt文件,通過它加入新的編譯文件或者庫,或者包含新的目錄。我們做如下修改,就可以把blinky.c加進(jìn)來了:
這種方式不管是NCS項(xiàng)目還是Zephyr項(xiàng)目,都能工作成功,而且是我們首推的方式。 至于CMakeLists的語法怎么理解和使用? 還是那句話: 參考例子,不要專門去學(xué)習(xí)。除了修改CMakeLists方法外,NCS還引入了一種圖形化方法,使用SES來添加文件,如下所示:
這種方式只有nrfsamples這個(gè)目錄下的例子才支持,zephyrsamples這個(gè)目錄下的例子默認(rèn)不支持這種方式。 其實(shí)通過SES添加文件,本質(zhì)上跟修改CMakeLists方法一樣,它只不過在CMakeLists文件里面預(yù)先放入如下兩行標(biāo)識,這樣SES就可以把新添加的文件塞到這兩行標(biāo)識之間:
我們把這兩行標(biāo)識放在我們的hello_world例子里面,這樣我們也可以通過SES添加文件了。blinky.c文件添加成功后,相應(yīng)的CMakelists文件也更新了,如下所示:
°6.3 修改blinky.c文件 好了,現(xiàn)在blinky.c文件已經(jīng)添加成功了,我們再對其進(jìn)行修改,修改代碼如下所示:
如上,我們直接把blinky代碼變成另外一個(gè)線程以達(dá)到我們的目的(當(dāng)然你也可以把blinky代碼變成一個(gè)模塊,以供hello_world的main調(diào)用,這里就不演示這種方式了)。 °6.4編譯和運(yùn)行你的第一個(gè)hello_world程序 上述修改結(jié)束后,我們可以使用任何Zephyr標(biāo)準(zhǔn)板運(yùn)行這個(gè)例子,以nrf52840dk為例,SES工程裝載如下所示,然后編譯和下載。
或者使用west命令進(jìn)行編譯和下載,命令如下所示: west build -b nrf52840dk_nrf52840 -dbuild_nrf52840dk_nrf52840 -p west flash --build-dirbuild_nrf52840dk_nrf52840 不管是SES下載完程序還是west下載完程序,可以看到程序正常執(zhí)行,串口助手在循環(huán)打印“Hello World! nrf52840dk_nrf52840”,然后開發(fā)板上LED1在一閃一閃。串口截圖如下:
我們第一個(gè)hello_world程序算是 正式大功告成了。 °6.5 使用prj.conf和
一是修改sdk_config.h文件
二是添加相應(yīng)文件
但是在NCS SDK里面,你只需在prj.conf里面做如下修改即可達(dá)到同樣的目的:
運(yùn)行后結(jié)果如下所示:
按道理說,上面的例子已經(jīng)把日志輸出改為RTT Viewer了,這時(shí)去測量nrf52840dk電流,應(yīng)該很低才對,但實(shí)際上此時(shí)電流大概為500多微安。 這是什么原因呢? 我們看一下zephyr.dts文件,如下:
可以看出,uart0和uart1都處于使能狀態(tài),從而導(dǎo)致功耗偏高。我們通過nrf52840dk_nrf52840.overlay文件,將uart0和uart1關(guān)閉,修改如下所示:
同時(shí)在prj.conf把serial模塊關(guān)掉(注:serial模塊在所有項(xiàng)目默認(rèn)是打開的),如下: CONFIG_SERIAL=n 實(shí)際上,serial模塊只使用了uart0模塊,所以只需把uart0關(guān)掉即可,如下:
重新編譯和下載,這時(shí)我們再去測量nrf52840dk電流,此時(shí)電流只有幾微安,符合預(yù)期。 7、開發(fā)multi-image應(yīng)用
°第一個(gè)multi-image(多image)應(yīng)用
有時(shí)一個(gè)應(yīng)用會包含多個(gè)image,最典型的情況有兩種:
一是BootLoader+app,BootLoader一個(gè)image,app一個(gè)image
二是spm+app,spm一個(gè)image,app一個(gè)image
*注:spm是Nordic為Cortex-M33非安全應(yīng)用設(shè)計(jì)的一個(gè)引導(dǎo)程序,像nRF9160/nRF5340這種M33內(nèi)核,所有非安全應(yīng)用都會默認(rèn)使能spm。 在NCS SDK中,編譯一個(gè)項(xiàng)目,會同時(shí)生成多個(gè)不同image,這種應(yīng)用就稱為multi-image應(yīng)用。單image應(yīng)用其生成的hex名為:zephy.hex,multi-image應(yīng)用其生成的hex名為:merged.hex merged.hex意味著這個(gè)項(xiàng)目會生成多個(gè)image,然后將他們合并(merge)成一個(gè)hex: merged.hex 因此multi-image應(yīng)用對用戶來說,最終也只有一個(gè)image,用戶只需下載這個(gè)image即可。 nrfsamples rf9160http_application_update為例,這是一個(gè)典型的多image應(yīng)用,它包含3個(gè)image:
BootLoader image
spm image
以及app image
這三個(gè)image都是在nrfsamples rf9160http_application_update編譯目錄下生成的,編譯成功后,我們將同時(shí)看到三個(gè)image的編譯目錄,如下所示:
°7.1 分區(qū)管理(Partition Manager) 傳統(tǒng)的SDK,如果一個(gè)產(chǎn)品包含多個(gè)image,那么每個(gè)image都會對應(yīng)一個(gè)項(xiàng)目,用戶需要同時(shí)維護(hù)多個(gè)項(xiàng)目,而且需要同時(shí)維護(hù)這幾個(gè)項(xiàng)目的版本關(guān)聯(lián)關(guān)系。 NCS中引入了partition manager(PM)模塊(注:PM和前面的SPM是兩個(gè)完全不同的模塊,二者之間沒有任何聯(lián)系),由PM完成對多個(gè)image的管理,以及存儲劃分。 在PM中,主應(yīng)用稱為parent應(yīng)用,其他應(yīng)用稱為child應(yīng)用,通過使能parent應(yīng)用的某些Kconfig,可以自動裝載child應(yīng)用,然后自動編譯child應(yīng)用,然后生成child應(yīng)用的hex,并將child應(yīng)用的hex和parent應(yīng)用的hex合并在一起生成前文所述的merged.hex,這一切都發(fā)生在parent應(yīng)用的build目錄中。
PM是如何工作的呢? PM首先假定有一個(gè)app image,也就是我們的parent應(yīng)用,這個(gè)應(yīng)用對應(yīng)的hex就是前文所述的zephyr.hex。 那么app image放在Flash什么地方呢? 這個(gè)是由PM動態(tài)決定的,PM將根據(jù)各個(gè)image的相對位置,來決定最終的image排列。 一般來說,parent應(yīng)用是默認(rèn)應(yīng)用,它不需要特別去指定自己的位置,而child應(yīng)用則需要告訴PM自己的位置在哪里,這個(gè)是通過child應(yīng)用目錄下面的pm.yml文件來實(shí)現(xiàn)的,pm.yml會告訴PM本child應(yīng)用會放在那里,pm.yml文件內(nèi)容大概如下所示:
pm.yml是按照相對位置來決定本child應(yīng)用的位置的,而且里面會用到Kconfig或者DeviceTree的宏定義,所以前面的
而且一般開發(fā)過程中,大家也不需要關(guān)心child應(yīng)用目錄下的文件,大家只需關(guān)心parent應(yīng)用目錄下的相關(guān)PM文件即可。 那么parent應(yīng)用目錄下有哪些PM文件呢? 首先就是build根目錄下多image最終布局的partitions.yml文件,以nrfsamples rf9160http_application_update為例,其partitions.yml文件如下所示:
partitions.yml文件是由PM模塊自動生成的,用戶不能直接修改。 然后就是pm.config 和pm_config.h文件,這兩個(gè)文件一一對應(yīng),pm.config和partitions.yml放在同一個(gè)目錄下,其內(nèi)容大概如下所示:
而pm_config.h是C語言代碼直接引用的文件,它在buildzephyrincludegenerated目錄下。 nrfsamples rf9160http_application_update為例,其pm_config.h文件如下所示:
一般來說,使用PM自動生成的存儲layout就可以了,只有一個(gè)配置有可能需要改: settings_storage的大小。 這個(gè)可以通過Kconfig選項(xiàng)CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE直接修改就可以了。 如果需要人為指定某個(gè)image的位置,也就是說需要對自動生成的partitions.yml進(jìn)行修改, 怎么辦呢?
其實(shí)很簡單,把partitions.yml這個(gè)文件拷出來,放在項(xiàng)目的根目錄下,然后將其重新命名為: pm_static.yml 然后大家就可以按照自己的需求將里面的值進(jìn)行修改。這里補(bǔ)充一下PM的另一個(gè)工作機(jī)理,當(dāng)PM檢測到parent應(yīng)用目錄下面有pm_static.yml文件,它就不會再自動去分配存儲空間,而是直接使用這個(gè)靜態(tài)的存儲空間layout。 °7.2 多image的hello_world程序開發(fā)
多image的hello_world程序開發(fā)
本節(jié)所有代碼可以到如下百度網(wǎng)盤鏈接獲取,進(jìn)入“開發(fā)你的第一個(gè)NCS(Zephyr)應(yīng)用程序”->“hello_world”,下載hello_world_ncsv140.rar:
下載鏈接: https://pan.baidu.com/s/1FKTfY3Q_zBVvviO7KC7Gyg#list/path=%2Fblog
提取碼:y8fb
我們現(xiàn)在將第6章的hello_world程序跑在多image環(huán)境下。 現(xiàn)在我們以nrf9160dk_nrf9160ns為例,重新編譯一下前述的hello_world程序,由于nrf9160dk_nrf9160ns為非安全應(yīng)用,前面也說過,所有Cortex-M33非安全應(yīng)用都會默認(rèn)使能spm模塊,所以spm image將會自動加載進(jìn)來并進(jìn)行編譯。
裝載成功后,你可以看到build和download的target都變成: merged.hex,而不是以前的zephyr.hex,如下:
而且build目錄也會多一個(gè)spm的build目錄,如下所示:
程序跑起來后,log如下所示:
跟第6章一樣,我們再定義一個(gè)overlay文件,以將uart0關(guān)掉,此時(shí)我們?nèi)y9160dk的電流,應(yīng)該只有幾微安,但實(shí)際上我們測下來還是500多微安。 這是為什么呢? 因?yàn)閟pm還使能了serial和uart0,這個(gè)可以從spm的.config和zephyr.dts文件得到驗(yàn)證,如下:
所以uart0在spm中打開了,然后程序跳到app,uart0還是處于打開狀態(tài),從而導(dǎo)致功耗偏高。 那么我們怎么可以便捷的關(guān)閉spm里面的serial模塊和uart0?
方法一,大家跑到spm例子里面,然后定義前述的prj.conf和
方法二,我們在parent應(yīng)用中定義spm的prj.conf和
為了將parent應(yīng)用中的conf和overlay文件傳給spm,需要用到NCS編譯系統(tǒng)的編譯變量,給相應(yīng)的變量賦值,從而可以將相關(guān)文件傳遞給spm,具體請參考第8章。 我們對CMakelists文件做如下修改:
通過設(shè)置spm_CONF_FILE和spm_DTC_OVERLAY_FILE兩個(gè)變量,我們將spm.conf和spm.overlay兩個(gè)文件傳給了spm image編譯過程,從而達(dá)到控制spm image編譯配置目的。 spm.conf我們定義如下選項(xiàng):
spm.overlay我們定義如下節(jié)點(diǎn):
我們再重新裝載hello_world程序,可以看到在spm中,serial和uart0都關(guān)閉了,如下:
此時(shí)再去測量9160dk電流,就降到幾微安了。 上面日志要不打印到串口助手,要不打印到RTT viewer,而且都是堵塞式打印。 我們現(xiàn)在將打印改成異步的,而且同時(shí)打印到串口助手和RTT viewer。為此我們將logging模塊打開,同時(shí)設(shè)置如下Kconfig:
只需做上述修改,就可以達(dá)到我們前述的目的,非常方便(無需添加文件,無需修改include目錄,這就是NCS!)。這次大家可以使用nrf5340dk_nrf5340_cpuapp跑一下試試。 *注:上述日志配置直接從nrf_desktop拷貝過來,大家以后也可以參考它來使能自己的log模塊。 8、NCS 編譯系統(tǒng)幾個(gè)要注意的點(diǎn)
°8.1 NCS幾個(gè)重要的編譯系統(tǒng)變量 在NCS或者Zephyr編譯系統(tǒng)中,有幾個(gè)變量非常重要,每個(gè)人最好掌握他們,把他們使用好,會讓你的編譯變得得心應(yīng)手,這幾個(gè)變量是:
ZEPHYR_BASE:用來指示你的Zephyr代碼庫的絕對目錄,比如取值:C:NordicNCSSDK agv1.4.0zephyr
BOARD:用來指定編譯用的板子,比如取值:nrf52840dk_nrf52840
CONF_FILE:用來指定項(xiàng)目的conf文件,如果沒有指定,默認(rèn)用prj.conf,詳細(xì)說明見8.1節(jié)
DTC_OVERLAY_FILE:用來指定項(xiàng)目的overlay文件,如果沒有指定,默認(rèn)用
PM_STATIC_YML_FILE:用來指定parent應(yīng)用,即app的pm_static文件,如果沒有指定,默認(rèn)用pm_static.yml,詳細(xì)說明見7.1節(jié)
CMAKE_BUILD_TYPE:命令行可以通過這個(gè)變量傳遞一個(gè)參數(shù)給CMakelists.txt文件或者其他build過程
°上述變量量不分大小寫
所以CONF_FILE和conf_file是一樣的,其他類同。因?yàn)檫@些變量是針對每一個(gè)image的,所以每一個(gè)image都有自己的board,conf_file,dtc_overlay_file等。
對于單image應(yīng)用,這個(gè)好理解也好區(qū)分。 那如果是多image應(yīng)用,該如何區(qū)分每個(gè)image的conf_file和dtc_overlay_file呢? 這可以通過使用image專用變量來實(shí)現(xiàn)。如前所述,conf_file這個(gè)變量本身是作用于app image的,實(shí)際上你可以把這個(gè)變量看成:app_conf_file,只不過默認(rèn)都是app image,所以就把a(bǔ)pp_省略了。
當(dāng)你需要在parent應(yīng)用中去設(shè)置child應(yīng)用的conf_file,你就不能直接使用conf_file這個(gè)變量了(因?yàn)樗怯脕碓O(shè)置parent應(yīng)用本身的conf文件),而需使用childImageName_conf_file。 比如上面的hello_world程序,我們使用了spm_conf_file這個(gè)變量,用來設(shè)置子image spm的conf_file。跟conf_file變量一樣,dtc_overlay_file變量使用了同樣的規(guī)則。NCS中目前主要有如下4個(gè)child image:
mcuboot。可升級的BootLoader
b0。不可升級的BootLoader
spm。Cortex-M33非安全應(yīng)用的引導(dǎo)程序,Nordic自己開發(fā)的
tfm。trusted-firmware-m,作用跟spm相似,但是符合PSA標(biāo)準(zhǔn),由第三方開發(fā)
除了上述child image,在編譯nRF5340 app核的時(shí)候,我們也可以自動包含如下network核的child image:
b0n。nRF5340 network核的b0程序
hci_rpmsg。nRF5340 network核的藍(lán)牙controller
802154_rpmsg。nRF5340 network核的802.15.4 controller
通過上面的childImage名字加上前面的編譯系統(tǒng)變量,就可以通過parent應(yīng)用去控制child應(yīng)用的編譯過程,大大方便了多image的開發(fā)流程。 關(guān)于上述編譯系統(tǒng)變量的使用,大家可以參考:
nrfapplications rf_desktop
nrf_desktop雖然只有一個(gè)CMakeLists.txt,但實(shí)際上這個(gè)CMakeLists.txt包含了20多個(gè)項(xiàng)目。 它是怎么做到的呢? 它就是通過board和cmake_build_type這兩個(gè)變量來實(shí)現(xiàn)的。比如要設(shè)置某一塊板子對應(yīng)的某一個(gè)項(xiàng)目的conf文件,它使用了如下語句:
比如說: $BOARD=nrf52840dk_nrf52840,$CMAKE_BUILD_TYPE=ZDebug_keyboard,那么它對應(yīng)的conf文件就是如下這個(gè):
asset_tracker的CMakeLists.txt文件定義了子image spm的conf文件,以及定義了一個(gè)靜態(tài)的pm文件,如下所示:
大家在寫自己的multi image應(yīng)用的時(shí)候,可以多借鑒上面的例子,尤其是nrf_desktop,這是一個(gè)非常全面的例子,基本上你要的功能,它都可能有參考。 °8.2 conf文件命名規(guī)則及編譯順序 如前所述,可以通過多種方法指定用戶自定義Kconfig文件,除了上面講的prj.conf,符合如下命名標(biāo)準(zhǔn)的conf文件也可以被系統(tǒng)自動加載進(jìn)來。
首先讀取CONF_FILE變量,我們可以將多個(gè)conf文件都賦給這個(gè)變量(每個(gè)conf文件之間以分號或者空格隔開),這些配置文件最終會合并成一個(gè)。我們可以通過三種方式設(shè)置CONF_FILE變量
通過命令行方式傳遞:-DCONF_FILE=
在CMakeLists.txt中并且必須在調(diào)用find_package(Zephyr)之前(也就是包含boilerplate.cmake之前)
通過CMake變量cache
否則,系統(tǒng)將使用應(yīng)用目錄下的prj_
否則,系統(tǒng)將使用應(yīng)用目錄下的prj_
否則,系統(tǒng)將使用應(yīng)用目錄下的boards/
否則,系統(tǒng)將使用應(yīng)用目錄下的prj.conf
記住:如果同一個(gè)Kconfig選項(xiàng)或者符號被配置多次,以最后一次配置為準(zhǔn)。 °8.3 overlay文件命名規(guī)則及編譯順序 系統(tǒng)也可以有多個(gè)overlay文件,overlay文件裝載的順序是:
首先讀取DTC_OVERLAY_FILE變量,我們可以同時(shí)將多個(gè)overlay文件賦給這個(gè)變量(每個(gè)overlay文件之間以分號或者空格隔開),這些overlay文件最終合并為一個(gè)文件。我們可以通過如下方式設(shè)置DTC_OVERLAY_FILE變量
通過命令行方式傳遞:-DDTC_OVERLAY_FILE="file1.overlay;file2.overlay"
在CMakeLists.txt中并且必須在調(diào)用find_package(Zephyr)之前(也就是包含boilerplate.cmake之前)
否則,系統(tǒng)將使用應(yīng)用目錄下的boards/
否則,系統(tǒng)將使用應(yīng)用目錄下的
責(zé)任編輯:xj
原文標(biāo)題:【Nordic博文分享系列】開發(fā)你的第一個(gè)NCS(Zephyr)應(yīng)用程序
文章出處:【微信公眾號:Nordic半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
NCS
+關(guān)注
關(guān)注
1文章
8瀏覽量
9117 -
Nordic
+關(guān)注
關(guān)注
9文章
174瀏覽量
47411
原文標(biāo)題:【Nordic博文分享系列】開發(fā)你的第一個(gè)NCS(Zephyr)應(yīng)用程序
文章出處:【微信號:nordicsemi,微信公眾號:Nordic半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
使用MCUXpresso for VS Code插件開發(fā)Zephyr的hello world
![使用MCUXpresso for VS Code插件<b class='flag-5'>開發(fā)</b><b class='flag-5'>Zephyr</b>的hello world](https://file1.elecfans.com/web3/M00/04/A6/wKgZPGd3PBeAcAcFAABDETVNApk954.png)
AWTK-WEB 快速入門(2) - JS 應(yīng)用程序
![AWTK-WEB 快速入門(2) - JS <b class='flag-5'>應(yīng)用程序</b>](https://file.elecfans.com/web2/M00/50/DA/pYYBAGLH6TyAB71EAAAPQ7KgtYA038.png)
使用MCUXPresso插件開發(fā)Zephyr
AWTK-WEB 快速入門(1) - C 語言應(yīng)用程序
![AWTK-WEB 快速入門(1) - C 語言<b class='flag-5'>應(yīng)用程序</b>](https://file.elecfans.com/web2/M00/50/DA/pYYBAGLH6TyAB71EAAAPQ7KgtYA038.png)
深入解析Zephyr RTOS的技術(shù)細(xì)節(jié)
![深入解析<b class='flag-5'>Zephyr</b> RTOS的技術(shù)細(xì)節(jié)](https://file1.elecfans.com/web2/M00/0A/E1/wKgaomcXZ22AeVJgAABvcLxtcWM071.png)
【xG24 Matter開發(fā)套件試用體驗(yàn)】第一個(gè)LED測試工程
可以在單個(gè)esp8266上安裝兩個(gè)NON OS SDK應(yīng)用程序嗎?
請問FW OTA二進(jìn)制文件是否包含應(yīng)用程序和BT棧/程序庫?
鴻蒙OpenHarmony【小型系統(tǒng) 編寫“Hello World”程序】 (基于Hi3516開發(fā)板)
![鴻蒙OpenHarmony【小型系統(tǒng) 編寫“Hello World”<b class='flag-5'>程序</b>】 (基于Hi3516<b class='flag-5'>開發(fā)</b>板)](https://file1.elecfans.com/web2/M00/E3/EA/wKgZomY92mCAOpDmAABBE-im69c216.png)
鴻蒙OpenHarmony【標(biāo)準(zhǔn)系統(tǒng) 編寫“Hello World”程序】(基于RK3568開發(fā)板)
![鴻蒙OpenHarmony【標(biāo)準(zhǔn)系統(tǒng) 編寫“Hello World”<b class='flag-5'>程序</b>】(基于RK3568<b class='flag-5'>開發(fā)</b>板)](https://file1.elecfans.com/web2/M00/E4/5A/wKgaomY8nl-ALH4oAAA3gQX5Lbg184.png)
鴻蒙OpenHarmony【小型系統(tǒng)編寫“Hello World”程序】 (基于Hi3516開發(fā)板)
![鴻蒙OpenHarmony【小型系統(tǒng)編寫“Hello World”<b class='flag-5'>程序</b>】 (基于Hi3516<b class='flag-5'>開發(fā)</b>板)](https://file1.elecfans.com/web2/M00/C5/CD/wKgZomYCdwyAIFf5AAB_7E1pFms943.jpg)
評論