官方文档路径:目录结构 - NuttX 最新文档 (apache.org)
NuttX 目录结构
NuttX 的总目录布局与 Linux 内核的目录结构非常相似 - 至少在最肤浅的层中是这样。在最高层是主要的制作文件和一系列子目录,下面确定并在以下段落中讨论:
配置文件
NuttX 配置由处理器架构目录、芯片/SoC目录和板配置目录中的逻辑组成。完整的配置由 NuttX 配置文件中的多个设置指定。
处理器架构特定文件
位于arch//目录下。
- 例如,当
CONFIG_ARCH="arm"
配置选项时,所有 ARM 处理器架构均在带有配置选项的目录arch/arm/下提供。 - 多种不同的处理器架构在子目录下提供,例如, 当设置
CONFIG_ARCH_CORTEXM3=y, CONFIG_ARCH_CORTEXM4=y, or CONFIG_ARCH_CORTEXM7=y
等配置选项时,ARMv7-M系列处理器的文件位于 arch/arm/include/armv7-m 和arch/arm/src/armv7-m目录下
芯片/SoC 特定文件
每个处理器架构都嵌入在芯片系统(SoC) 架构中。完整的 SoC 架构包括处理器架构加上芯片特异性中断逻辑、时钟逻辑、通用 I/O (GPIO) 逻辑以及专用的内部外设(如 UART、USB 等)
- 这些芯片特定文件也包含在芯片特定子目录中,也包含在
arch/<arch-name>/
目录中,并通过 CONFIG_ARCH_CHIP进行选择 - 例如,STMicro STM32 SoC 架构基于 ARMv7-M 处理器,并由
arch/arm/include/stm32
和arch/arm/src/stm32
目录中的逻辑支持,这些目录使用CONFIG_ARCH_CHIP="stm32"
选择配置设置。
板特定配置
为了可用,芯片必须包含在电路板环境中。电路板配置定义了电路板的其他属性,包括外围 LED、外部外围设备(例如网络、USB 等)。
- 这些特定电路板的配置文件可以在
boards/<arch-name>/<chip-name>/<board-name>/ sub-directories
中找到,并在下面的段落中讨论。 - 例如,目录
board/arm/stm32/stm32f4disovery/
包含 STM32F4 Discovery 板的板特定逻辑,并通过CONFIG_ARCH_BOARD="stm32f4discovery"
配置设置进行选择。
nuttx/Documentation
此目录保存 NuttX 文档。它是用 Sphinx documentation system制作的。有关如何构建它的信息,请参阅 README.md 文件。
nuttx/arch
Arch 子目录结构
该目录包含多个子目录,每个子目录都包含特定于体系结构的逻辑。将 NuttX 移植到新处理器的任务包括在 arch/ 下添加一个新子目录,其中包含特定于新架构的逻辑。完整的板卡端口由该目录中特定于架构的代码定义(加上 config/ 子目录中的特定于板卡的配置)。每个架构都必须在 arch/ 下提供一个子目录 ,具有以下特征:
Arch 文件摘要
include/<chip-name>/
该子目录包含特定于芯片的头文件。include/arch.h
这是系统可能需要的任何体系结构特定定义的钩子函数(hook)。它包含在 include/nuttx/arch.h 中。include/types.h
这为标准类型提供了体系结构/工具链特定的定义。这个文件应该typedef:…include/irq.h
这个文件需要定义一些架构特定的函数(如果编译器支持内联,通常是内联的)和一些结构。这些包括:- struct xcptcontext 此结构用来线程的保存上下文。
- irqstate_t up_irq_save(void) 用于禁用所有中断。在多 CPU 平台的情况下,此功能禁用 CPU 上的中断。
- void up_irq_restore(irqstate_t flags) 用于将中断使能恢复到调用 up_irq_save() 之前的相同状态。
- 该文件还必须定义 NR_IRQS,即电路板支持的 IRQ 总数。
include/syscall.h
该文件需要定义一些特定于架构的函数(如果编译器支持内联,通常是内联的)以支持软件中断或系统调用,这些中断或系统调用可以从用户模式应用程序到内核模式 NuttX 函数中使用。必须始终提供此目录以防止编译错误。但是,如果体系结构支持 CONFIG_BUILD_PROTECTED 或 CONFIG_BUILD_KERNEL 配置,则它只需要包含有效的函数声明。- uintptr_t sys_call0(unsigned int nbr) nbr 是可以在 include/sys/syscall.h 中找到的系统调用号之一。此函数将执行没有(附加)参数的系统调用。
- uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1) nbr 是可以在 include/sys/syscall.h 中找到的系统调用号之一。此函数将使用一个(附加)参数执行系统调用。
- uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2) …
- uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4)…
- uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5)
- uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6)
该文件还必须定义 NR_IRQS,即电路板支持的 IRQ 总数。
src/<chip-name>/
该子目录包含特定于芯片的源文件。
src/Makefile 将执行此 makefile 以构建目标 src/libup.a 和 src/up_head.o。 up_head.o 文件包含进入系统的入口点(例如,上电复位入口点)。它将用于与 libup.a 和其他系统存档的最终链接以生成最终可执行文件
(架构特定源文件) 文件include/nuttx/arch.h
标识了架构特定逻辑必须提供的所有 API。 (它还包括如上所述的 arch//arch.h)。
支持的架构
特定于架构和芯片的目录。所有特定于处理器体系结构的目录都保存在 arch/ 目录的子目录中。不同的芯片或 SoC 可能实现相同的处理器内核。芯片特定的逻辑可以在架构目录下的子目录中找到。当前架构/芯片目录总结如下:
- arch/sim 可以使用 NuttX 到 x86 Linux 或 Cygwin 平台的用户模式端口。此端口的目的主要是支持操作系统功能开发。此端口不支持中断或实时计时器(因此没有循环调度程序),否则就完成了。
- arch/arm 该目录包含常见的 ARM 架构
- arch/avr
- arch/mips
- arch/misoc
- arch/or1K
- arch/renesas
- arch/xtensa
- arch/z16f
- arch/z80
nuttx/binfmt
binfmt/ 子目录包含将文件系统中的二进制文件以可用于执行它们的形式加载到内存中的逻辑。
nuttx/audio
audio/ 子目录包含 NuttX 音频子系统。
nuttx/boards
board/ 子目录
包含每个板的自定义逻辑和板配置数据。这些特定于板的配置加上 arch/ 子目录中特定于架构的配置完整定义了 NuttX 的自定义端口。
特定板的逻辑
- include/ 该目录包含板特定的头文件。此目录将在配置时链接为
include/arch/board
,并且可以通过#include <arch/board/header.h>
包含。这些头文件只能被arch/<arch-name>/include/
和arch/<arch-name>/src/
中的文件包含。 src/
此目录包含板特定的驱动程序。该目录将在配置时链接为<config>/arch/<arch-name>/src/board
并将集成到构建系统中。src/Makefile
将调用此 makefile 来构建板特定的驱动程序。它必须支持以下目标:libext$(LIBEXT)、clean 和 distclean。
特定板的配置子目录
board/<arch-name>/<chip-name>/<board-name>/configs
子目录包含为特定板配置 NuttX 所需的所有文件。使用公共源文件,电路板可能具有各种不同的配置。每个电路板配置由两个文件描述:Make.defs 和 defconfig。通常,每组配置文件都保留在单独的配置子目录中(上图中的<config1-dir>
、<config2-dir>
、…)。- 注意:Make.defs 文件可能位于以下两个位置之一:配置目录中的每个配置可能有一个唯一的 Make.defs 文件,或者如果该文件不存在,则可能有一个公共板 Make.defs 文件/scripts 目录。如果存在,则配置中的 Make.defs 文件优先
NuttX 的配置过程
- Make.defs这个 makefile 片段提供了体系结构和特定于工具的构建选项。它将被构建中的所有其他 makefile 包含(一旦安装)。这个 make 片段应该定义:
- Tools: CC, LD, AR, NM, OBJCOPY, OBJDUMP
- Tool options: CFLAGS, LDFLAGS
- 当这个 makefile 片段运行时,它将传递 TOPDIR,它是构建根目录的路径。这个 makefile 片段应该包括:
-
$(TOPDIR)/.config : NuttX configuration
-
$(TOPDIR)/tools/Config.mk : Common definitions
-
Make.defs 文件中的定义可能取决于 .config 文件中的某些设置。例如,如果
CONFIG_DEBUG_FEATURES=y
,CFLAGS 很可能会有所不同。 -
包含的
tools/Config.mk
文件包含额外的定义,可以根据需要在特定于体系结构的 Make.defs 文件中覆盖:- COMPILE, ASSEMBLE, ARCHIVE, CLEAN, and MKDEP macros
-
defconfig 这是一个类似于 Linux 配置文件的配置文件。 In 包含变量/值对,例如:
CONFIG_VARIABLE=value
- This configuration file will be used at build time:
- 作为包含在其他 makefile 中的 makefile 片段,以及
- 生成系统中大多数 C 文件都包含的
include/nuttx/config.h
。
-
支持的电路板
- NuttX 支持的所有特定板都在 README.txt 文件中标识。
添加新的电路板配置
- 好的,您已经创建了一个新的板配置目录。现在,您如何将此板挂接到配置系统中,以便您可以使用 make menuconfig 进行选择?
- 您将需要修改文件
boards/Kconfig
。让我们看看 Kconfig 文件中的 STM32F4-Discovery 配置,看看我们如何将新的板子目录添加到配置中。对于此配置,假设您的新板位于目录board/myarch/mychip/myboard
中;它使用通过 CONFIG_ARCH_CHIP_MYMCU 选择的 MCU;并且您希望使用 CONFIG_ARCH_BOARD_MYBOARD 选择板。那么这里是如何克隆boards/Kconfig 中的 STM32F4-Discovery 配置以支持新的板配置。 - 在
stm32f4-discovery 的boards/Kconfig
中,您将看到如下配置定义:- 以上选用STM32F4-Discovery板。select行表示该板同时具有 LED 和按钮,并且该板可以通过按下按钮产生中断。您可以将上述配置定义复制到新位置(请注意,这些配置是按字母顺序排列的)。然后您应该编辑配置以支持您的电路板。最终的配置定义可能类似于
- 稍后在 board/Kconfig 文件中,您将看到一个很长很长的字符串配置,其中包含许多类似这样的默认值:
- 此逻辑将字符串值分配给名为 CONFIG_ARCH_BOARD 的配置变量,该变量将命名板特定文件所在的目录。在我们的例子中,这些文件位于
board/myarch/mychip/myboard
中,我们将以下内容添加到一长串默认值中(再次按字母顺序): - 现在构建系统知道在哪里可以找到您的电路板配置!
- 最后,在
board/myarch/mychip/myboard
底部附近添加类似这样的东西: - 这包括
board/myarch/mychip/myboard/Kconfig
中额外的、特定于板的配置变量定义。
nuttx/crypto
- 该子目录包含 NuttX 加密子系统
nuttx/drivers
- 此目录包含与体系结构无关的设备驱动程序。
nuttx/fs
- 该目录包含 NuttX 文件系统。该文件系统描述如下 below。
nuttx/graphics
- 该目录包含 NuttX 下图形/视频支持的文件。
nuttx/include
- 该目录包含 NuttX 头文件。保留在的标准头文件文件可以以正常方式包含:
nuttx
- 这是一个(几乎)空目录,其中包含生成的静态库的存放位置。 NuttX 构建系统在编译阶段在此目录中生成此类静态库的集合。然后,这些库在最终链接阶段位于一个已知位置,在那里访问它们以生成最终二进制文件。
nuttx/libs/libc
该目录保存了一系列标准的 libc 类函数,以及 NuttX 中的自定义接口。
通常,此文件中的逻辑构建为单个库 (libc.a)。但是,如果 NuttX 构建为单独编译的内核(使用 CONFIG_BUILD_PROTECTED=y
或 CONFIG_BUILD_KERNEL=y
),则该目录的内容构建为两个库:一个供用户程序使用(libc.a),一个仅供使用在 空间 (libkc.a) 内。
需要这些用户/内核空间库(以及 nuttx/syscall <#DirStructSyscall>
__ 的系统调用)来支持两个不同的保护域。
nuttx/libs/libxx
- 该目录包含一个微小的、最小的标准 C++,可用于在 NuttX 中构建一些简单的 C++ 应用程序。
nuttx/mm
- 这是 NuttX 内存管理器。
nuttx/net
- 该目录包含 NuttX 网络层的实现,包括内部套接字 API。
nuttx/sched
- 构成 NuttX RTOS 核心的文件驻留在此处。
nuttx/syscall
- 如果 NuttX 构建为单独编译的内核(使用
CONFIG_BUILD_PROTECTED=y
或CONFIG_BUILD_KERNEL=y
),则构建此目录的内容。该目录包含一个系统调用接口,可用于用户模式应用程序和内核模式 RTOS 之间的通信。
nuttx/tools
- 该目录包含一组工具和脚本,用于简化 NuttX 的配置、构建和维护。
有关各个文件的更多信息,请参阅工具目录中的 README 文件。其中一些工具也在下面讨论配置和构建 NuttX configuring and building时进行了讨论。
nuttx/wireless
- 该目录支持独立于硬件的无线支持。
nuttx/Makefile
- $(TOPDIR) 目录中的顶层 Makefile 包含构建 NuttX 的所有顶层控制逻辑。