为ALIENTEK 阿波罗STM32F429开发板移植openvela(精简版)
本文介绍了为ALIENTEK阿波罗STM32F429开发板移植openvela操作系统的过程。
为ALIENTEK 阿波罗STM32F429开发板移植openvela(精简版)
本指南(参考为STM32F407 开发板移植 openvela)详细介绍了如何为 ALIENTEK 阿波罗STM32F429开发板(后文简称“开发板”)移植openvela 操作系统。核心板的主控芯片为 STM32F429IGT6。由于 NuttX 官方已提供对 STM32F429I 系列芯片的支持,本指南将重点阐述板级支持包(Board Support Package, BSP)的适配过程。
文章目录
准备工作
在开始之前,请确保您已完成以下准备工作:
- 获取源码:参考文档快速入门下载最新代码。
- 了解
openvela架构:建议您预先阅读 openvela 架构以理解其分层设计。 - 查阅系统启动流程文档,获取更详细的启动时序和函数调用关系图。
- 准备好硬件及配套软件。
一、移植原理与启动流程
openvela 的移植本质上是为操作系统框架提供一套与特定硬件交互的接口。这些接口构成了板级支持包(BSP),它位于 nuttx/boards/ 目录下。本指南将通过实现一个最小功能的 BSP,让openvela在 开发板上启动并运行。
关键启动函数
openvela 在启动过程中,会按照特定顺序调用一系列由 BSP 提供的函数来完成硬件初始化。要成功启动系统,您必须在 BSP 中实现以下关键函数:
| 函数 | 描述 |
|---|---|
| void stm32_boardinitialize(void) | 由系统启动代码 __start 调用。这是最早执行的板级初始化函数,用于配置最基础的硬件,如时钟和调试串口。 |
| void board_late_initialize(void) | 如果配置了 CONFIG_BOARD_LATE_INITIALIZE,此函数会在 OS 初始化后期被调用,通常用于初始化那些依赖 OS 服务的驱动。 |
| int stm32_bringup(void) | 如果配置 CONFIG_BOARD_LATE_INITIALIZE 选项,由 board_late_initialize() 调用; 如果没有配置 CONFIG_BOARD_LATE_INITIALIZE 选项,由 board_app_initialize(arg) 调用。 在 stm32_bringup 里将实现驱动的初始化。 |
| int board_app_initialize(uintptr_t arg) | 由 boardctl() 接口通过 BOARDIOC_INIT 命令触发,用于执行应用层或用户自定义的初始化。 |
此外,如果您的系统配置CONFIG_ARCH_LEDS用于显示系统状态(如启动、Panic),则还需要实现以下函数:
| 函数 | 描述 |
|---|---|
| void board_autoled_initialize(void) | 初始化用于系统状态指示的 LED 引脚,通常设置为 GPIO 输出模式。 |
| void board_autoled_on(int led) | 根据系统状态(如 LED_STARTED)点亮指定的 LED。 |
| void board_autoled_off(int led) | 根据系统状态(如 LED_PANIC 结束)熄灭指定的 LED。 |
硬件配置:时钟与引脚
除了实现函数接口,您还需要在板级头文件board.h中定义宏,以配置 STM32 的时钟树、外设引脚功能等。这些宏将被芯片级的驱动代码(如 stm32_rcc.c)使用。
以下是开发板时钟树的配置示例,它描述了如何将 25MHz 的外部高速晶振(HSE)通过 PLL 倍频至 168MHz 作为系统主时钟(SYSCLK)。
/* Clocking *****************************************************************/
/* The APOLLO Discovery board features a single 25MHz crystal.
* Space is provided for a 32kHz RTC backup crystal, but it is not stuffed.
*
* This is the canonical configuration:
* System Clock source : PLL (HSE)
* SYSCLK(Hz) : 168000000 Determined by PLL
* configuration
* HCLK(Hz) : 168000000 (STM32_RCC_CFGR_HPRE)
* AHB Prescaler : 1 (STM32_RCC_CFGR_HPRE)
* APB1 Prescaler : 4 (STM32_RCC_CFGR_PPRE1)
* APB2 Prescaler : 2 (STM32_RCC_CFGR_PPRE2)
* HSE Frequency(Hz) : 25000000 (STM32_BOARD_XTAL)
* PLLM : 25 (STM32_PLLCFG_PLLM)
* PLLN : 336 (STM32_PLLCFG_PLLN)
* PLLP : 2 (STM32_PLLCFG_PLLP)
* PLLQ : 7 (STM32_PLLCFG_PLLQ)
* Main regulator output voltage : Scale1 mode Needed for high speed
* SYSCLK
* Flash Latency(WS) : 5
* Prefetch Buffer : OFF
* Instruction cache : ON
* Data cache : ON
* Require 48MHz for USB OTG FS, : Enabled
* SDIO and RNG clock
*/
二、代码实现步骤
本节将指导您完成本项目的文件创建和代码编写。
1.创建代码目录结构
首先,在nuttx/boards/arm/stm32/目录下,创建一个名为 apollo-stm32f429i的新目录,并建立如下的子目录和文件结构。
代码路径: nuttx/boards/arm/stm32/apollo-stm32f429i/
apollo-stm32f429i
├── CMakeLists.txt
├── configs # defconfig 配置路径
│ └── nsh
│ └── defconfig # NuttShell (NSH) 的默认配置
├── include
│ └── board.h # 板级硬件配置头文件
├── Kconfig # 板级 Kconfig 配置文件
├── scripts # 链接脚本
│ ├── ld.script # 链接器脚本
│ └── Make.defs # 板级 Make 定义
└── src
├── CMakeLists.txt
├── Make.defs
├── stm32_appinit.c # 实现 board_app_initialize
├── stm32_autoleds.c # 实现系统状态 LED 控制
├── stm32_boot.c # 实现 stm32_boardinitialize
├── stm32_bringup.c # 实现驱动初始化
├── apollo-stm32f429i.h # 板级私有头文件,定义 GPIO
└── stm32_userleds.c # 实现用户层 LED 驱动接口
2.实现核心初始化函数
在 src/ 目录下,您需要创建并填充以下 C 文件。
stm32_boot.c:早期硬件初始化
此文件负责实现 stm32_boardinitialize(),用于在系统启动的最初阶段配置必要的硬件。
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/stm32_boot.c
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "apollo-stm32f429i.h"
#include "stm32_ccm.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_boardinitialize
*
* Description:
* All STM32 architectures must provide the following entry point.
* This entry point is called early in the initialization -- after all
* memory has been configured and mapped but before any devices have been
* initialized.
*
****************************************************************************/
void stm32_boardinitialize(void)
{
#ifdef CONFIG_ARCH_LEDS
/* Configure on-board LEDs if LED support has been selected. */
board_autoled_initialize();
#endif
}
/****************************************************************************
* Name: board_late_initialize
*
* Description:
* If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
* initialization call will be performed in the boot-up sequence to a
* function called board_late_initialize(). board_late_initialize() will be
* called immediately after up_initialize() is called and just before the
* initial application is started. This additional initialization phase
* may be used, for example, to initialize board-specific device drivers.
*
****************************************************************************/
#ifdef CONFIG_BOARD_LATE_INITIALIZE
void board_late_initialize(void)
{
/* Perform board-specific initialization */
stm32_bringup();
}
#endif
stm32_bringup.c:设备驱动初始化
此文件中的 stm32_bringup() 函数负责初始化并注册所有板载设备的驱动程序。
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/stm32_bringup.c
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/board.h>
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
#include "stm32.h"
#include "apollo-stm32f429i.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture-specific initialization
*
* CONFIG_BOARD_LATE_INITIALIZE=y :
* Called from board_late_initialize().
*
* CONFIG_BOARD_LATE_INITIALIZE=y && CONFIG_BOARDCTL=y :
* Called from the NSH library
*
****************************************************************************/
int stm32_bringup(void)
{
int ret;
#ifdef HAVE_PROC
/* mount the proc filesystem */
ret = nx_mount(NULL, CONFIG_NSH_PROC_MOUNTPOINT, "procfs", 0, NULL);
if (ret < 0)
{
syslog(LOG_ERR,
"ERROR: Failed to mount the PROC filesystem: %d\n", ret);
return ret;
}
#endif
UNUSED(ret);
return OK;
}
stm32_appinit.c:应用初始化桥梁
主要实现 int board_app_initialize(uintptr_t arg) 函数:
- 如果打开
CONFIG_BOARD_LATE_INITIALIZE,stm32_bringup()将由board_late_initialize()调用。 - 如果没有打开
CONFIG_BOARD_LATE_INITIALIZE,stm32_bringup()将由board_app_initialize(arg)调用。
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/stm32_appinit.c
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <nuttx/board.h>
#include "apollo-stm32f429i.h"
#ifdef CONFIG_BOARDCTL
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_app_initialize
*
* Description:
* Perform application specific initialization. This function is never
* called directly from application code, but only indirectly via the
* (non-standard) boardctl() interface using the command BOARDIOC_INIT.
*
* Input Parameters:
* arg - The boardctl() argument is passed to the board_app_initialize()
* implementation without modification. The argument has no
* meaning to NuttX; the meaning of the argument is a contract
* between the board-specific initialization logic and the
* matching application logic. The value could be such things as a
* mode enumeration value, a set of DIP switch switch settings, a
* pointer to configuration data read from a file or serial FLASH,
* or whatever you would like to do with it. Every implementation
* should accept zero/NULL as a default configuration.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure to indicate the nature of the failure.
*
****************************************************************************/
int board_app_initialize(uintptr_t arg)
{
#ifdef CONFIG_BOARD_LATE_INITIALIZE
/* Board initialization already performed by board_late_initialize() */
return OK;
#else
/* Perform board-specific initialization */
return stm32_bringup();
#endif
}
#endif /* CONFIG_BOARDCTL */
3.实现 LED 驱动
openvela将 LED 分为两类:一类用于指示系统状态(autoleds),另一类供用户应用程序控制(userleds)。
stm32_autoleds.c:系统状态 LED
该文件实现 board_autoled_* 系列函数,来控制实现 LED 的亮灭,由系统内核在特定事件(如启动、断言失败)发生时自动调用。此部分实现参照nuttx/boards/arm/stm32/stm32f429i-disco/src/stm32_autoleds.c
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/stm32_autoleds.c
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "chip.h"
#include "arm_internal.h"
#include "stm32.h"
#include "apollo-stm32f429i.h"
#ifdef CONFIG_ARCH_LEDS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* The following definitions map the encoded LED setting to GPIO settings */
#define STM32F4_LED1 (1 << 0)
#define STM32F4_LED2 (1 << 1)
#define ON_SETBITS_SHIFT (0)
#define ON_CLRBITS_SHIFT (4)
#define OFF_SETBITS_SHIFT (8)
#define OFF_CLRBITS_SHIFT (12)
#define ON_BITS(v) ((v) & 0xff)
#define OFF_BITS(v) (((v) >> 8) & 0x0ff)
#define SETBITS(b) ((b) & 0x0f)
#define CLRBITS(b) (((b) >> 4) & 0x0f)
#define ON_SETBITS(v) (SETBITS(ON_BITS(v))
#define ON_CLRBITS(v) (CLRBITS(ON_BITS(v))
#define OFF_SETBITS(v) (SETBITS(OFF_BITS(v))
#define OFF_CLRBITS(v) (CLRBITS(OFF_BITS(v))
#define LED_STARTED_ON_SETBITS ((STM32F4_LED1) << ON_SETBITS_SHIFT)
#define LED_STARTED_ON_CLRBITS ((STM32F4_LED2) << ON_CLRBITS_SHIFT)
#define LED_STARTED_OFF_SETBITS (0 << OFF_SETBITS_SHIFT)
#define LED_STARTED_OFF_CLRBITS ((STM32F4_LED1|STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_HEAPALLOCATE_ON_SETBITS ((STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_HEAPALLOCATE_ON_CLRBITS ((STM32F4_LED1) << ON_CLRBITS_SHIFT)
#define LED_HEAPALLOCATE_OFF_SETBITS ((STM32F4_LED1) << OFF_SETBITS_SHIFT)
#define LED_HEAPALLOCATE_OFF_CLRBITS ((STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_IRQSENABLED_ON_SETBITS ((STM32F4_LED1|STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_IRQSENABLED_ON_CLRBITS ((STM32F4_LED2) << ON_CLRBITS_SHIFT)
#define LED_IRQSENABLED_OFF_SETBITS ((STM32F4_LED2) << OFF_SETBITS_SHIFT)
#define LED_IRQSENABLED_OFF_CLRBITS ((STM32F4_LED1) << OFF_CLRBITS_SHIFT)
#define LED_STACKCREATED_ON_SETBITS ((STM32F4_LED1) << ON_SETBITS_SHIFT)
#define LED_STACKCREATED_ON_CLRBITS ((STM32F4_LED1|STM32F4_LED2) << ON_CLRBITS_SHIFT)
#define LED_STACKCREATED_OFF_SETBITS ((STM32F4_LED1|STM32F4_LED2) << OFF_SETBITS_SHIFT)
#define LED_STACKCREATED_OFF_CLRBITS ((STM32F4_LED1|STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_INIRQ_ON_SETBITS ((STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_INIRQ_ON_CLRBITS ((0) << ON_CLRBITS_SHIFT)
#define LED_INIRQ_OFF_SETBITS ((0) << OFF_SETBITS_SHIFT)
#define LED_INIRQ_OFF_CLRBITS ((STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_SIGNAL_ON_SETBITS ((STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_SIGNAL_ON_CLRBITS ((0) << ON_CLRBITS_SHIFT)
#define LED_SIGNAL_OFF_SETBITS ((0) << OFF_SETBITS_SHIFT)
#define LED_SIGNAL_OFF_CLRBITS ((STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_ASSERTION_ON_SETBITS ((STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_ASSERTION_ON_CLRBITS ((0) << ON_CLRBITS_SHIFT)
#define LED_ASSERTION_OFF_SETBITS ((0) << OFF_SETBITS_SHIFT)
#define LED_ASSERTION_OFF_CLRBITS ((STM32F4_LED2) << OFF_CLRBITS_SHIFT)
#define LED_PANIC_ON_SETBITS ((STM32F4_LED2) << ON_SETBITS_SHIFT)
#define LED_PANIC_ON_CLRBITS ((0) << ON_CLRBITS_SHIFT)
#define LED_PANIC_OFF_SETBITS ((0) << OFF_SETBITS_SHIFT)
#define LED_PANIC_OFF_CLRBITS ((STM32F4_LED2) << OFF_CLRBITS_SHIFT)
/****************************************************************************
* Private Data
****************************************************************************/
static const uint16_t g_ledbits[8] =
{
(LED_STARTED_ON_SETBITS | LED_STARTED_ON_CLRBITS |
LED_STARTED_OFF_SETBITS | LED_STARTED_OFF_CLRBITS),
(LED_HEAPALLOCATE_ON_SETBITS | LED_HEAPALLOCATE_ON_CLRBITS |
LED_HEAPALLOCATE_OFF_SETBITS | LED_HEAPALLOCATE_OFF_CLRBITS),
(LED_IRQSENABLED_ON_SETBITS | LED_IRQSENABLED_ON_CLRBITS |
LED_IRQSENABLED_OFF_SETBITS | LED_IRQSENABLED_OFF_CLRBITS),
(LED_STACKCREATED_ON_SETBITS | LED_STACKCREATED_ON_CLRBITS |
LED_STACKCREATED_OFF_SETBITS | LED_STACKCREATED_OFF_CLRBITS),
(LED_INIRQ_ON_SETBITS | LED_INIRQ_ON_CLRBITS |
LED_INIRQ_OFF_SETBITS | LED_INIRQ_OFF_CLRBITS),
(LED_SIGNAL_ON_SETBITS | LED_SIGNAL_ON_CLRBITS |
LED_SIGNAL_OFF_SETBITS | LED_SIGNAL_OFF_CLRBITS),
(LED_ASSERTION_ON_SETBITS | LED_ASSERTION_ON_CLRBITS |
LED_ASSERTION_OFF_SETBITS | LED_ASSERTION_OFF_CLRBITS),
(LED_PANIC_ON_SETBITS | LED_PANIC_ON_CLRBITS |
LED_PANIC_OFF_SETBITS | LED_PANIC_OFF_CLRBITS)
};
/****************************************************************************
* Private Functions
****************************************************************************/
static inline void led_clrbits(unsigned int clrbits)
{
if ((clrbits & STM32F4_LED1) != 0)
{
/* 对于本开发板而言,对应IO输出高电平灭灯 */
stm32_gpiowrite(GPIO_LED_GREEN, true);
}
if ((clrbits & STM32F4_LED2) != 0)
{
stm32_gpiowrite(GPIO_LED_RED, true);
}
}
static inline void led_setbits(unsigned int setbits)
{
if ((setbits & STM32F4_LED1) != 0)
{
/* 对于本开发板而言,对应IO输出低电平亮灯 */
stm32_gpiowrite(GPIO_LED_GREEN, false);
}
if ((setbits & STM32F4_LED2) != 0)
{
stm32_gpiowrite(GPIO_LED_RED, false);
}
}
static void led_setonoff(unsigned int bits)
{
led_clrbits(CLRBITS(bits));
led_setbits(SETBITS(bits));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_autoled_initialize
****************************************************************************/
void board_autoled_initialize(void)
{
/* Configure LED1-2 GPIOs for output */
stm32_configgpio(GPIO_LED_GREEN);
stm32_configgpio(GPIO_LED_RED);
}
/****************************************************************************
* Name: board_autoled_on
****************************************************************************/
void board_autoled_on(int led)
{
ledinfo("board_autoled_on(%d)\n", led);
led_setonoff(ON_BITS(g_ledbits[led]));
}
/****************************************************************************
* Name: board_autoled_off
****************************************************************************/
void board_autoled_off(int led)
{
led_setonoff(OFF_BITS(g_ledbits[led]));
}
#endif /* CONFIG_ARCH_LEDS */
stm32_userleds.c:用户应用 LED
该文件为通用的 LED 驱动(位于 nuttx/drivers/leds/userled_lower.c)提供底层的硬件操作接口。应用程序通过标准的 open(), write(), ioctl() 等VFS接口访问 /dev/userleds 来控制这些 LED。
我们需要提供下面的函数接口给 userled_lower.c 调用:
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/stm32_userleds.c
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/power/pm.h>
#include "chip.h"
#include "arm_internal.h"
#include "stm32.h"
#include "apollo-stm32f429i.h"
#ifndef CONFIG_ARCH_LEDS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
/****************************************************************************
* Private Data
****************************************************************************/
/* This array maps an LED number to GPIO pin configuration */
static uint32_t g_ledcfg[BOARD_NLEDS] =
{
GPIO_LED_GREEN,
GPIO_LED_RED
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_userled_initialize
*
* Description:
* If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
* LEDs. If CONFIG_ARCH_LEDS is not defined, then the
* board_userled_initialize() is available to initialize the LED from user
* application logic.
*
****************************************************************************/
uint32_t board_userled_initialize(void)
{
int i;
/* Configure LED1-2 GPIOs for output */
for (i = 0; i < ARRAYSIZE(g_ledcfg); i++)
{
stm32_configgpio(g_ledcfg[i]);
}
return BOARD_NLEDS;
}
/****************************************************************************
* Name: board_userled
*
* Description:
* If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
* LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled() is
* available to control the LED from user application logic.
*
****************************************************************************/
void board_userled(int led, bool ledon)
{
int i;
for (i = 0; i < ARRAYSIZE(g_ledcfg); i++)
{
/* 对于本开发板而言,对应IO输出高电平灭灯,对应IO输出低电平亮灯*/
if (i != led)
{
stm32_gpiowrite(g_ledcfg[i], ledon);
}
else
{
stm32_gpiowrite(g_ledcfg[i], !ledon);
}
}
}
/****************************************************************************
* Name: board_userled_all
****************************************************************************/
void board_userled_all(uint32_t ledset)
{
int i;
for (i = 0; i < ARRAYSIZE(g_ledcfg); i++)
{
stm32_gpiowrite(g_ledcfg[i], (ledset & (1 << i)) == 0);
}
}
#endif /* !CONFIG_ARCH_LEDS */
最终,在 userled_upper.c 实现下面 LED 驱动接口:
static int userled_open(FAR struct file *filep);
static int userled_close(FAR struct file *filep);
static ssize_t userled_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static int userled_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);
5、定义硬件宏
在src/apollo-stm32f429i.h和 include/board.h 中定义与硬件相关的宏。
apollo-stm32f429i.h:板级私有定义
此文件定义了板载外设的 GPIO 引脚和其他私有配置。参考boards/arm/stm32/stm32f429i-disco/src/stm32f429i-disco.h
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/src/apollo-stm32f429i.h
****************************************************************************/
#ifndef __BOARDS_ARM_STM32_APOLLO_STM32F429I_SRC_APOLLO_STM32F429I_H
#define __BOARDS_ARM_STM32_APOLLO_STM32F429I_SRC_APOLLO_STM32F429I_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdint.h>
#include <arch/stm32/chip.h>
#include "stm32_gpio.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#define HAVE_PROC 1
#define HAVE_USBDEV 1
#define HAVE_USBHOST 1
#define HAVE_USBMONITOR 1
/* Can't support USB host or device features if USB OTG HS is not enabled */
#ifndef CONFIG_STM32_OTGHS
# undef HAVE_USBDEV
# undef HAVE_USBHOST
#endif
/* Can't support USB device monitor if USB device is not enabled */
#ifndef CONFIG_USBDEV
# undef HAVE_USBDEV
#endif
/* Can't support USB host is USB host is not enabled */
#ifndef CONFIG_USBHOST
# undef HAVE_USBHOST
#endif
/* Check if we should enable the USB monitor before starting NSH */
#ifndef CONFIG_USBMONITOR
# undef HAVE_USBMONITOR
#endif
#ifndef HAVE_USBDEV
# undef CONFIG_USBDEV_TRACE
#endif
#ifndef HAVE_USBHOST
# undef CONFIG_USBHOST_TRACE
#endif
#if !defined(CONFIG_USBDEV_TRACE) && !defined(CONFIG_USBHOST_TRACE)
# undef HAVE_USBMONITOR
#endif
/* Check if we have the procfs file system */
#if !defined(CONFIG_FS_PROCFS)
# undef HAVE_PROC
#endif
#if defined(HAVE_PROC) && defined(CONFIG_DISABLE_MOUNTPOINT)
# warning Mountpoints disabled. No procfs support
# undef HAVE_PROC
#endif
/* APOLLO STM32F429I GPIOs ************************************************/
/* LED.
* User LED1: the green LED is a user LED connected to board LED DS1
* corresponding to MCU I/O PB0.
* User LED2: the red LED is a user LED connected to board LED DS0
* corresponding to MCU I/O PB1.
*
* - When the I/O is HIGH value, the LED is on.
* - When the I/O is LOW, the LED is off.
*/
#define GPIO_LED_RED (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN1)
#define GPIO_LED_GREEN (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_PULLUP|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN0)
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: stm32_bringup
*
* Description:
* Perform architecture-specific initialization
*
* CONFIG_BOARD_LATE_INITIALIZE=y :
* Called from board_late_initialize().
*
* CONFIG_BOARD_LATE_INITIALIZE=y && CONFIG_BOARDCTL=y :
* Called from the NSH library
*
****************************************************************************/
int stm32_bringup(void);
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_STM32_APOLLO_STM32F429I_SRC_APOLLO_STM32F429I_H */
include/board.h:公共板级定义
此文件包含被 NuttX 内核和应用共享的板级定义,如时钟配置。参考boards/arm/stm32/stm32f429i-disco/include/board.h
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/include/board.h
****************************************************************************/
#ifndef __BOARDS_ARM_STM32_APOLLO_STM32F429I_INCLUDE_BOARD_H
#define __BOARDS_ARM_STM32_APOLLO_STM32F429I_INCLUDE_BOARD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
/* DO NOT include STM32 internal header files here */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Clocking *****************************************************************/
/* The APOLLO Discovery board features a single 25MHz crystal.
* Space is provided for a 32kHz RTC backup crystal, but it is not stuffed.
*
* This is the canonical configuration:
* System Clock source : PLL (HSE)
* SYSCLK(Hz) : 168000000 Determined by PLL
* configuration
* HCLK(Hz) : 168000000 (STM32_RCC_CFGR_HPRE)
* AHB Prescaler : 1 (STM32_RCC_CFGR_HPRE)
* APB1 Prescaler : 4 (STM32_RCC_CFGR_PPRE1)
* APB2 Prescaler : 2 (STM32_RCC_CFGR_PPRE2)
* HSE Frequency(Hz) : 25000000 (STM32_BOARD_XTAL)
* PLLM : 25 (STM32_PLLCFG_PLLM)
* PLLN : 336 (STM32_PLLCFG_PLLN)
* PLLP : 2 (STM32_PLLCFG_PLLP)
* PLLQ : 7 (STM32_PLLCFG_PLLQ)
* Main regulator output voltage : Scale1 mode Needed for high speed
* SYSCLK
* Flash Latency(WS) : 5
* Prefetch Buffer : OFF
* Instruction cache : ON
* Data cache : ON
* Require 48MHz for USB OTG FS, : Enabled
* SDIO and RNG clock
*/
/* HSI - 16 MHz RC factory-trimmed
* LSI - 32 KHz RC
* HSE - On-board crystal frequency is 25MHz
* LSE - 32.768 kHz
*/
#define STM32_BOARD_XTAL 25000000ul
#define STM32_HSI_FREQUENCY 16000000ul
#define STM32_LSI_FREQUENCY 32000
#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
#define STM32_LSE_FREQUENCY 32768
/* Main PLL Configuration.
*
*
* Formulae:
*
* VCO input freq = PLL input clock freq/PLLM 2 <= PLLM <= 63
* VCO output freq = VCO input freq × PLLN, 192 <= PLLN <= 432
* PLL output clock freq = VCO freq / PLLP, PLLP = 2,4,6 or 8
* USB OTG FS clock freq = VCO freq / PLLQ, 2 <= PLLQ <= 15
*
* There is no config for 180 MHz and 48 MHz for usb,
* so we would like to have SYSYCLK=168 MHz and we must have the USB
* clock = 48MHz
*
* PLLQ = 7 PLLP = 2 PLLN=336 PLLM=25
*
* PLL source is HSE
* PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN
* = (25,000,000 / 25) * 336
* = 336,000,000
* SYSCLK = PLL_VCO / PLLP
* = 336,000,000 / 2 = 168,000,000
* USB OTG FS, SDIO and RNG Clock
* = PLL_VCO / PLLQ
* = 48,000,000
*/
#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(25)
#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(336)
#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(7)
#define STM32_SYSCLK_FREQUENCY 168000000ul
/* AHB clock (HCLK) is SYSCLK (168MHz) */
#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */
#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
/* APB1 clock (PCLK1) is HCLK/4 (42MHz) */
#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */
#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4)
/* Timers driven from APB1 will be twice PCLK1 */
#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
/* APB2 clock (PCLK2) is HCLK/2 (84MHz) */
#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
/* Timers driven from APB2 will be twice PCLK2 */
#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY)
#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY)
/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
* otherwise frequency is 2xAPBx.
* Note: TIM1,8 are on APB2, others on APB1
*/
#define BOARD_TIM1_FREQUENCY STM32_HCLK_FREQUENCY
#define BOARD_TIM2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM3_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM4_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM5_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM6_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM7_FREQUENCY (STM32_HCLK_FREQUENCY/2)
#define BOARD_TIM8_FREQUENCY STM32_HCLK_FREQUENCY
/* LED definitions **********************************************************/
/*
* If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in
* any way. The following definitions are used to access individual LEDs.
*/
/* LED index values for use with board_userled() */
#define BOARD_LED1 0
#define BOARD_LED2 1
#define BOARD_NLEDS 2
/* LED bits for use with board_userled_all() */
#define BOARD_LED1_BIT (1 << BOARD_LED1)
#define BOARD_LED2_BIT (1 << BOARD_LED2)
/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in
* include/board.h and src/stm32_autoleds.c. The LEDs are used to encode
* OS-related events as follows:
*
*
* SYMBOL Meaning LED state
* GREEN RED
* ---------------------- -------------------------- ------ ------
*/
#define LED_STARTED 0 /* NuttX has been started ON OFF */
#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF ON */
#define LED_IRQSENABLED 2 /* Interrupts enabled ON ON */
#define LED_STACKCREATED 3 /* Idle stack created OFF ON */
#define LED_INIRQ 4 /* In an interrupt ON ON */
#define LED_SIGNAL 5 /* In a signal handler N/C ON */
#define LED_ASSERTION 6 /* An assertion failed ON ON */
#define LED_PANIC 7 /* The system has crashed ON Blink */
/* Thus if the Green LED is statically on, NuttX has successfully booted and
* is, apparently, running normally. If the Red LED is flashing at
* approximately 2Hz, then a fatal error has been detected and the system
* has halted.
*/
/* Alternate function pin selections ****************************************/
/* USART1:
*
* The Apollo Discovery has no on-board serial devices, but the console is
* brought out to PA9 (TX) and PA10 (RX) for connection to an external serial
* device. (See the README.txt file for other options)
*/
#define GPIO_USART1_RX GPIO_USART1_RX_1
#define GPIO_USART1_TX GPIO_USART1_TX_1
#endif /* __BOARDS_ARM_STM32_APOLLO_STM32F429I_INCLUDE_BOARD_H */
6、编写项目配置文件
编写src/Make.defs
参考boards/arm/stm32/stm32f429i-disco/src/Make.defs
############################################################################
# boards/arm/stm32/apollo-stm32f429i/src/Make.defs
############################################################################
include $(TOPDIR)/Make.defs
CSRCS = stm32_boot.c stm32_bringup.c
ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += stm32_autoleds.c
else
CSRCS += stm32_userleds.c
endif
ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
编写src/CMakeLists.txt
参考boards/arm/stm32/stm32f429i-disco/src/CMakeLists.txt)
# ##############################################################################
# boards/arm/stm32/apollo-stm32f429i/src/CMakeLists.txt
# ##############################################################################
set(SRCS stm32_boot.c stm32_bringup.c)
if(CONFIG_ARCH_LEDS)
list(APPEND SRCS stm32_autoleds.c)
else()
list(APPEND SRCS stm32_userleds.c)
endif()
if(CONFIG_BOARDCTL)
list(APPEND SRCS stm32_appinit.c)
endif()
target_sources(board PRIVATE ${SRCS})
set_property(GLOBAL PROPERTY LD_SCRIPT "${NUTTX_BOARD_DIR}/scripts/ld.script")
编写CMakeLists.txt
参考boards/arm/stm32/stm32f429i-disco/CMakeLists.txt
# ##############################################################################
# boards/arm/stm32/apollo-stm32f429i/CMakeLists.txt
# ##############################################################################
add_subdirectory(src)
7、链接脚本
scripts/Make.defs
参考boards/arm/stm32/stm32f429i-disco/scripts/Make.defs
############################################################################
# boards/arm/stm32/apollo-stm32f429i/scripts/Make.defs
############################################################################
include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs
LDSCRIPT = ld.script
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS := $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048
scripts/ld.script
参考boards/arm/stm32/stm32f429i-disco/scripts/ld.script
/****************************************************************************
* boards/arm/stm32/apollo-stm32f429i/scripts/ld.script
****************************************************************************/
/* The STM32F429IGT6 has 1024Kb of FLASH beginning at address 0x0800:0000 and
* 256Kb of SRAM. SRAM is split up into four blocks:
*
* 1) 112Kb of SRAM beginning at address 0x2000:0000
* 2) 16Kb of SRAM beginning at address 0x2001:c000
* 3) 64Kb of SRAM beginning at address 0x2002:0000
* 4) 64Kb of CCM SRAM beginning at address 0x1000:0000
*
* When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
* where the code expects to begin execution by jumping to the entry point in
* the 0x0800:0000 address
* range.
*/
MEMORY
{
flash (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
sram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K
}
OUTPUT_ARCH(arm)
EXTERN(_vectors)
ENTRY(_stext)
SECTIONS
{
.text : {
_stext = ABSOLUTE(.);
*(.vectors)
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > flash
.init_section : ALIGN(4) {
_sinit = ABSOLUTE(.);
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o) .ctors))
_einit = ABSOLUTE(.);
} > flash
.ARM.extab : ALIGN(4) {
*(.ARM.extab*)
} > flash
.ARM.exidx : ALIGN(4) {
__exidx_start = ABSOLUTE(.);
*(.ARM.exidx*)
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */
.ram_vectors : {
*(.ram_vectors)
} > sram
.data : ALIGN(4) {
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.gnu.linkonce.d.*)
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > sram AT > flash
.bss : ALIGN(4) {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > sram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}
三、集成到构建系统
完成代码编写后,需要修改构建系统配置,使 openvela 能够识别和编译您的新 BSP。
1、Kconfig 集成
Kconfig 用于管理内核和应用的功能配置。您需要执行以下三步来集成新板。
1.在 nuttx/boards/Kconfig 中定义板级选项:
添加一个新的 config 条目,用于在配置菜单中显示您的开发板。
config ARCH_BOARD_APOLLO_STM32F429I
bool "ATK APOLLO-F429I board"
depends on ARCH_CHIP_STM32F429I
select ARCH_HAVE_LEDS
select ARCH_HAVE_BUTTONS
select ARCH_HAVE_IRQBUTTONS
---help---
ATK Apollo-F429I board based on the STMicro STM32F429IGT6 MCU.
上述可参考条目config ARCH_BOARD_STM32F429I_DISCO

2.在 nuttx/boards/Kconfig 中设置默认板名:
当选中您的板型时,让 ARCH_BOARD 变量自动设置为您的 BSP 目录名。
config ARCH_BOARD
string
# ... 其他板的 default 设置 ...
default "apollo-stm32f429i" if ARCH_BOARD_APOLLO_STM32F429I
上述可参考条目default "stm32f429i-disco"

3.在 nuttx/boards/Kconfig 中加载板级 Kconfig 文件:
确保选中您的板型时,会加载 BSP 目录下的 Kconfig 文件。
if ARCH_BOARD_APOLLO_STM32F429I
source "boards/arm/stm32/apollo-stm32f429i/Kconfig"
endif
上述可参考条目if ARCH_BOARD_STM32F429I_DISCO

4.在 nuttx/boards/arm/stm32/apollo-stm32f429i/Kconfig 文件中可以添加此板特有的配置选项
本篇例程只需运行NSH,无需添加额外配置,留空即可。
if ARCH_BOARD_APOLLO_STM32F429I
endif # ARCH_BOARD_APOLLO_STM32F429I
2、创建默认配置 (defconfig)
defconfig 文件是一个最小化的系统配置集合,为用户提供了一个开箱即用的配置起点。您应该为每个核心功能(如 NSH、特定示例)提供一个 defconfig。
参照nuttx/boards/arm/stm32/stm32f429i-disco/configs/nsh/deconfig,创建 nuttx/boards/arm/stm32/apollo-stm32f429i/configs/nsh/deconfig 如下:
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_FPU is not set
# CONFIG_STM32_FLASH_PREFETCH is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="apollo-stm32f429i"
CONFIG_ARCH_BOARD_APOLLO_STM32F429I=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F429I=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_MM_REGIONS=2
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_PWR=y
CONFIG_STM32_USART1=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART1_SERIAL_CONSOLE=y
四、运行Demo
1、编译代码
在完成上面的步骤后,按以下流程为 阿波罗STM32F429 开发板生成所需二进制文件:
# 进入 openvela 根目录
# 编译
./build.sh apollo-stm32f429i:nsh -j8

编译完成后,生成的文件位于 nuttx 目录下,包括:
- nuttx.bin
- nuttx.hex
2、烧录固件
参考在 STM32F411 上使用 openvela 点亮 LED: : 四、运行Demo::5、烧录固件
3、连接串口
参考在 STM32F411 上使用 openvela 点亮 LED: : 四、运行Demo::6、连接串口
4、交互测试
重新打开 minicom,连接成功后,在 Minicom 终端中按回车,您会看到 nsh> 提示符。
输入一些常用命令(如ls,help)若反馈正常,则证明本文代码移植实验成功。

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐

所有评论(0)