为ALIENTEK 阿波罗STM32F429开发板移植openvela(精简版)

本指南(参考为STM32F407 开发板移植 openvela)详细介绍了如何为 ALIENTEK 阿波罗STM32F429开发板(后文简称“开发板”)移植openvela 操作系统。核心板的主控芯片为 STM32F429IGT6。由于 NuttX 官方已提供对 STM32F429I 系列芯片的支持,本指南将重点阐述板级支持包(Board Support Package, BSP)的适配过程。

准备工作

在开始之前,请确保您已完成以下准备工作:

  1. 获取源码:参考文档快速入门下载最新代码。
  2. 了解 openvela 架构:建议您预先阅读 openvela 架构以理解其分层设计。
  3. 查阅系统启动流程文档,获取更详细的启动时序和函数调用关系图。
  4. 准备好硬件及配套软件

一、移植原理与启动流程

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_INITIALIZEstm32_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.hinclude/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> 提示符。

输入一些常用命令(如lshelp)若反馈正常,则证明本文代码移植实验成功。

在这里插入图片描述

Logo

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

更多推荐