標籤:style blog http io ar color 使用 sp strong
Nuttx的配置
Nuttx配置系統是由kconfig ,makefile和組態工具組成。
核心的Makefile分為5個組成部分:
Makefile 最頂層的Makefile
.config 核心的當前配置文檔,編譯時間成為定層Makefile的一部分
arch/$(ARCH)/Makefile 和體繫結構相關的Makefile
s/ Makefile.* 一些Makefile的通用規則
kbuild Makefile 各級目錄下的大概約500個文檔,編譯時間根據上層Makefile傳下來的宏定義和其他編譯規則,將原始碼編譯成模組或編入核心
頂層的Makefile文檔讀取 .config文檔的內容,並總體上負責build核心和模組。Arch Makefile則提供補充體繫結構相關的資訊。 s目錄下的Makefile文檔包含了任何用來根據kbuild Makefile 構建核心所需的定義和規則。。(其中.config的內容是在make menuconfig的時候,通過Kconfig文檔配置的結果。)
在Nuttx中,Makefile的分類樹如下:
` |<--.config | | |<--.config | |<--tools/Config.mk |<--Makefile.unix-|Makefile-| | |<--.config | |<--Make.defs-|<--tools/Config.mk | |<--arch/arm/src/armv7-m/Toolchain.defs | |<--Makefile.win-(略)
各級子目錄下的 Makefile、 Make.defs 和 Make.dep 並不是通過 include 包含的,而是在執行 Makefile 檔案中的 make 命令時調用的。
NuttX 的主 Kconfig 檔案是 nuttx/Kconfig。主 Kconfig 檔案調用各級子目錄的 Kconfig 檔案和應用程式目錄的 Kconfig 檔案,形成樹狀關係。菜單按照樹狀結構組織,主菜單下有子功能表,子功能表還有子功能表或者配置選項。每個選項可以有依賴關係,這些依賴關係用於確定它是否顯示。只有被依賴項的父項已經選中,子項才會顯示。
注意:
nuttx/.config 是預設的 .config 檔案。從 nuttx/config/<板卡>/<目標配置>/defconfig 複製而來
nuttx/Make.defs:從 nuttx/config/<板卡>/<目標配置>/Make.defs 複製而來。
在 nuttx 目錄下執行 make menuconfig 命令,讀取預設的 .config 檔案,調出基於文本菜單的配置介面,退出配置介面時選<Yes>儲存,在 nuttx 目錄下產生新的 .config 檔案。
比如,我編寫了mytest.c的檔案,這裡不關心mytest.c的內容。如果想把mytest.c編譯到核心中,需要按照以下的步驟來完成。
1) 將test.c放到任何一個目錄中,這個目錄只要求已存在Kconfig和Makefile中,比如源碼根目錄/arch/arm/目錄中。
2) 在這個目錄的Kconfig中添加
config MY_TEST
bool “My Test”
3) 在Makefile中添加
obj-$(CONFIG_MY_TEST) += mytest.o
4) 在.config中可以添加 CONFIG_MY_TEST = y來選中。
或者在執行make menuconfig時,找到顯示名為My Test的選項,使用空格選中。
總而言之,就是如果需要向系統核心中添加一個功能,那麼首先定義一個配置項對應於這個功能,添加到特定的Kconfig檔案中。然後在Makefile裡,定義這個配置項需要編譯哪些檔案。最後就可以通過make menuconfig或者直接修改.config來使能這個配置項。
補充:
defconfig的文法如下:
# STM32 Peripheral Support
# CONFIG_STM32_ADC1 is not set
# CONFIG_STM32_SPI1 is not set
CONFIG_STM32_USART1=y
# CONFIG_STM32_USART2 is not set
加入要增加GPIO的驅動。首先需要修改Kconfig.
配置順序
基本的配置順序是由下而上:
- 選擇構建環境
- 選擇處理器
- 選擇板卡
- 選擇支援的外設
- 配置裝置驅動
- 配置應用程式選項
對建立新的配置來說,這是相當正確的方向,但對修改現有的配置來說則不合適。
在執行make menuconfig時,要記住一些重要的配置選項,例如在配置nuttx時,記住應用程式的入口地址的選擇。
因為 all 目標是預設目標,所以執行無參數的 make 命令即為編譯 all 目標,首先會嘗試編譯 context 目標,其中,根據 .config 檔案產生 config.h,有許多 C 檔案包含了 config.h,以獲得使用者配置。注意其中的2個目錄軟連結,下文會用到:
$(ARCH_SRC)/board:
將 nuttx/configs/shenzhou/src 目錄連結到 nuttx/arch/arm/src/board 目錄。
$(ARCH_SRC)/chip:
將 nuttx/arch/arm/src/stm32 目錄連結到 nuttx/arch/arm/src/chip 目錄。
但是因為在安裝 buildroot 時已經執行過一次 make context,而且執行 make clean 也不會刪除 context 目標所產生的檔案,所以這一步沒做任何事。
Kconfig文法
1. 基本構成
基本構成包括五種,menu/endmenu,menuconfig,config,choice/endchoice,source。下面就對每種詳細介紹:
(1) menu/endmenu
menu的作用,可以理解成一個目錄,menu可以把其中一部分配置項包含到一個menu中,這樣有利於配置的分類顯示。menu與endmenu是一組指令,必須同時出現。menu和endmenu中包含的部分就是子目錄中的配置項。
比如,在init/Kconfig中24行(可能不同)顯示為:
menu "General setup"
這樣,就會產生一個目錄,特徵就是右側會出現一個箭頭,1中第一行。當點擊確認鍵時,會進入這個功能表項目,2。
圖1
圖2
(2) menuconfig
menuconfig有點類似menu,但區別就在於menu後面多了一個config,這個menu是可以配置的,2中的第二行,前面比menu類型多了一個方框,通過空格可以修改這個配置項的選中狀態。而且從格式上來看,也是有區別的。格式如init/Kconfig中1131行:
menuconfig MODULES
bool "Enable loadable module support"config
if MODULES
xx
endif
也就是說,配置項是位於if和endif中。其中的部分就是MODULES子目錄顯示的內容。如果選中了MODULE,那麼if和endif中的內容可以顯示。如果沒有定義,就只能進入一個空目錄。
(3) config
config是構成Kconfig的最基本單元,其中定義了配置項的詳細資料。定義的格式參考arch/arm/Kconfig中的第8行。
config ARM
bool
default y
select xxxxxxxxxx
help
???????????
可知,config需要定義名稱,與menuconfig相同。這個名稱不但用於裁剪核心中,還用於配置項之間的相互依賴關係中。
config的類型有5種,分別是bool(y/n),tristate(y/m/n),string(字串),hex(十六進位),integer(整數)。其中,需要特別介紹一下bool和tristate,bool只能表示選中和不選,而tristate還可以配置成模組(m),特別對於驅動程式的開發非常有用。bool 類型的只能選中或不選中,顯示為[ ]; tristate類型的功能表項目多了編譯成核心模組的選項,顯示為< > , 假如選擇編譯成核心模組,則會在.config中產生一個 CONFIG_HELLO_MODULE=m的配置,假如選擇內建,就是直接編譯成核心影響,就會在.config中產生一個 CONFIG_HELLO_MODULE=y的配置. hex十六進位類型顯示為( )。
Kconfig 中變數的取值類型
Kconfig 中變數取值類型總共有5種。其中做常見的是tristate 和 bool ,分別對應於make meuconfig 配置介面中< > 和 [ ]選項。
(1)tristate :可取y 、n 、m。
(2)bool (其為tristate的變體) :可取 y 、n
(3)string :取值為字串,如:CONFIG_CMDLINE = "root =/dev/hdal ro init = /bin/bash console =ttySAC0 "
(4)hex (其為string的變體):取值為十六進位資料,如:CONFIG_VECTORS_BASE =0xffff0000.
(5)int (其為string的變體):取值為十進位資料,如:CONFIG_SPLIT_PTLOCK_CPUS=4096
其他文法如下:
1) prompt:提示,顯示在make menuconfig中的名稱,一般省略。下面兩種寫法相同。
a. bool “Networking Support”
b. bool
prompt “Networking Support”
2) default:預設值
一個配置項可以有多個預設值,但是只有第一個被定義的值是有效。
3) depends on/requires:依賴關係
如果依賴的配置項沒有選中,那麼就當前項也無法選中。
4) select:反向依賴
如果當前項選中,那麼也選中select後的選項。
5) range:範圍,用於hex和integer
range A B表示當前值不小於A,不大於B
6) comment:注釋
(4) choice/endchoice
choice的作用,多選一,有點像MFC中的Radio控制項。參考arch/arm/Kconfig第205行。
choice
prompt "ARM system type"
default ARCH_VERSATILE
???????
config ARCH_S3C2410
bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
select GENERIC_GPIO
select ARCH_HAS_CPUFREQ
select HAVE_CLK
???????
endchoice
顯示的結果3,進入這一項後,顯示結果4.
圖3
圖4
可見,choice有點類似於menu,是在子視窗裡選擇,但是不同的是子視窗中只能選擇一項。在prompt後會顯示當前選擇項的名稱。
(5) source
source只是將另外一個Kconfig檔案直接複製到當前位置而已。但它的作用也是明顯的,可以將這個系統貫穿在一起。從開始位置arch/arm/Kconfig,來將整個系統都作為配置型。
五.配置分析
當我們進入了linux源碼的根目錄時,輸入make menuconfig。假設,此時根目錄已經存在了.config,如果不存在,會自動產生。這時,在命令列顯示5.
顯然,在執行make menuconfig時,會自動調用scripts/Kconfig/mconf arch/arm/Kconfig開始系統的配置,那麼arch/arm/Kconfig就是配置的起點。這個檔案會通過source指令來調用其他目錄下的Kconfig檔案,從而完成整體配置。這樣,arch/arm/Kconfig就可以理解成main函數,而source指令就有點類似於include。可以按照上面的文法,來分析Kconfig檔案。
Nuttx的配置和編譯