Zephyr内核和子系统可在构建时候通过Kconfig进行配置,以适应特定的应用和平台需求。
配置选项在Kconfig文件中定义,其中还可以指定配置的依赖性。可以分为菜单和子菜单,以保持交互式配置界面的组织关系。
Kconfig的输出是一个宏的标头文件autoconfig.h,可在构建时使用。
Kconfig的作用可以在不编译未使用的功能代码以节省空间。

Kconfig的交互系统

有两个交互式配置界面可用于探索可用的 Kconfig 选项并进行临时更改

  • menuconfig
  • guiconfig

    要使设置永久化的配置值,你应该将其设置在*.conf文件中。

运行一个配置交互式的Kconfig交互界面需要如下:

  • 进入应用程序目录下先编译应用程序

    1. west build -b <board>
  • 通过指令打开交互式配置页面

    1. west build -t menuconfig

    或者

    1. west build -t guiconfig
  • menuconfig的界面
    02.zephyr的Kconfig配置系统 - 图1

  • guiconfig界面
    02.zephyr的Kconfig配置系统 - 图2

    设置Kconfig的值

    所有的Kconfig符号参考

    交互式设置Kconfig值只是为了测试配置,并不能永久的存储的配置值。

可见和不可见的Kconfig符号配置

  • 可见符号是用于提示定义的符号。可见符号可以显示在交互式配置界面中,并可以设置在*.config配置文件中。

    1. config FPU
    2. bool "Support floating point operations"
    3. depends on HAS_FPU

    在交互界面显示如下:

    1. [ ] Support floating point operations
  • 不可见的符号是无提示定义的符号。交互式配置界面中不能显示不可见的符号,用户无法直接控制其值。只能通过其他符号启用。

    1. config CPU_HAS_FPU
    2. bool
    3. help
    4. This symbol is y if the CPU has a hardware floating point unit.

    在配置文件中设置Kconfig配置符号

    可见符号可以通过在配置文件中设置它们来配置。
    初始配置是通过将板子的*_defconfig文件与应用程序的prj.conf文件合并后生成。
    配置文件中的设置配置的语法:

    1. CONFIG_<symbol name>=<value>

    等号周围应该没有空格。

bool配置可以通过分别设置y或禁用n它们来启用或禁用。

  1. CONFIG_FPU=y

其他配置类型可以如下设置:

  1. CONFIG_SOME_STRING="cool value"
  2. CONFIG_SOME_INT=123

只有在满足配置的依赖关系时,配置文件中的配置才会得到应用。否则会打印警告。

初始配置

应用程序的初始配置来自三个源的合并配置设置:

  • 存储在特定板子配置文件的配置,路径类似与:boards/<architecture>/<BOARD>/<BOARD>_defconfig
  • 任何的CMake缓存条目中的CONFIG_*配置
  • 应用程序配置

CONF_FILE属性设置的方式:

  • CMakeLists.txt中调用find_package(Zephyr)之前
  • 通过在执行west时定义-DCONF_FILE=<conf file(s)>
  • 从CMake变量缓存中取

应用程序的配置来自与如下源:

  • 如果设置了CONF_FILE属性为文件列表,就合并CONF_FILE的文件列表的值作为应用程序配置文件。
  • 否则,如果设置CONF_FILE为单个配置文件,且配置文件名称格式为prj_<build>.conf,就将设置的prj_<build>.conf和同目录下的boards/<BOARD>_<build>.conf配置文件合并后作为应用配置文件。
  • 否则,如果应用程序目录下存在prj_<BOARD>.conf文件就使用该文件作为配置文件。
  • 否则,如果存在应用程序目录存在boards/<BOARD>.confprj.conf文件,就将两个文件合并后作为配置文件。
  • 否则,如果存在应用程序目录存在boards/<BOARD>.confboards/<BOARD>_<revision>.confprj.conf文件,就将三个文件合并后作为配置文件。
  • 否则,如果应用程序目录下存在prj.conf,则使用prj.conf为配置文件。

如果配置即存在于boards/<architecture>/<BOARD>/<BOARD>_defconfig中又存在于应用程序配置文件中,以应用程序配置文件设置的为主。

合并后的配置保存到目录中的zephyr/.config

配置不可见的配置符号

更改板子的默认配置时,你需要在boards/<architecture>/<BOARD>/Kconfig.defconfig文件中配置不可见的配置符号。
例如我们想将不可见配置符号FOO_WIDTH的默认值设置为32,可以在Kconfig.defconfig中定义如下:

  1. if BOARD_MY_BOARD
  2. config FOO_WIDTH
  3. default 32
  4. endif

由于符号的类型已在第一个定义时指定了,因此无需在此处重复指定。

Kconfig.defconfig定义的default定义的值将会覆盖该符号第一次定义时指定的值。
在多个位置定义符号时,依赖关系为或的关系使用。例如:

  1. config FOO
  2. ...
  3. depends on DEP1
  4. config FOO
  5. ...
  6. depends on DEP2

FOO配置符号的直接依赖为:DEP1 || DEP2

Kconfig的最佳实践

如果使用可见Kconfig配置,则用户可以通过交互界面和设置文件更改配置。不可见的Kconfig配置用户无法直接更改配置。
只有在用户更改配置有意义时,才会放置可见Kconfig配置中。
一般来说,使用Kconfig配置进行与固定机器特定设置相对应的配置是没有意义的。通常此类设置应通过设备树进行配置。

自定义Kconfig预处理器功能

Kconfiglib支持在Python中编写自定义Kconfig预处理器函数。这些功能在scripts/kconfig/kconfigfunctions.py文件中定义。
大多数自定义预处理器功能用于将设备树信息放入Kconfig中。例如,Kconfig的默认值可以从设备树属性中获取。

Kconfig从设备树中获取值

下面列出的功能用于将设备树信息放入Kconfig中。有关详细信息文档,请参阅scripts/kconfig/kconfigfunctions.py的python文件。
*_int结束的函数返回十进制数值,以*_hex返回十六进制数值。

  1. $(dt_chosen_reg_addr_int,<property in /chosen>[,<index>,<unit>])
  2. $(dt_chosen_reg_addr_hex,<property in /chosen>[,<index>,<unit>])
  3. $(dt_chosen_reg_size_int,<property in /chosen>[,<index>,<unit>])
  4. $(dt_chosen_reg_size_hex,<property in /chosen>[,<index>,<unit>])
  5. $(dt_node_reg_addr_int,<node path>[,<index>,<unit>])
  6. $(dt_node_reg_addr_hex,<node path>[,<index>,<unit>])
  7. $(dt_node_reg_size_int,<node path>[,<index>,<unit>])
  8. $(dt_node_reg_size_hex,<node path>[,<index>,<unit>])
  9. $(dt_compat_enabled,<compatible string>)
  10. $(dt_chosen_enabled,<property in /chosen>)
  11. $(dt_node_has_bool_prop,<node path>,<prop>)
  12. $(dt_node_has_prop,<node path>,<prop>)

示例:
假设某些板子的设备树看起来像这样:

  1. {
  2. soc {
  3. #address-cells = <1>;
  4. #size-cells = <1>;
  5. spi0: spi@10014000 {
  6. compatible = "sifive,spi0";
  7. reg = <0x10014000 0x1000 0x20010000 0x3c0900>;
  8. reg-names = "control", "mem";
  9. ...
  10. };
  11. };

将SPI的reg属性的第二个地址0x20010000应用Kconfig文件中:

  1. config FLASH_BASE_ADDRESS
  2. default $(dt_node_reg_addr_hex,/soc/spi@1001400,1)

预处理后的结果为:

  1. config FLASH_BASE_ADDRESS
  2. default 0x20010000

对传统Kconfig的扩展

获取环境变量的值

推荐用于引用环境变量的语法是。扩展环境变量的语法仅支持向后兼容性。

  1. $(FOO)
  2. $FOO
  3. $FOO

再添加子文件时使用通配符

示例

  1. source "foo/bar/*/Kconfig"

如果模式与文件匹配,则上述语句等同于以下两个语句:

  1. source "foo/bar/baz/Kconfig"
  2. source "foo/bar/qaz/Kconfig"

如果没有文件与模式匹配,则会生成错误。
接受的通配符和python的通配符相同。

新增属性关键字

新增了如下属性关键字:

  • def_int
  • def_hex
  • def_string
  • def_bool

    通配符搜索文件

    以下声明将包括当前目录符合通配符的文件如果存在。文件不存在也不会报错。
    1. orsource "Kconfig[12]"