[openvela] Hello World :从零开始的完整实践与问题复盘

链接:git clone https://gitee.com/mirrors/lvgl.git

github上下载可能会限速,建议使用镜像,非常快~

配置openvela的开发环境。根据文档,我们需要使用repo工具来管理多个Git仓库。

1. 安装必要的依赖工具

bash 复制代码
sudo apt update && sudo apt install -y git-lfs repo curl wget build-essential

2. 创建openvela工作目录并初始化

bash 复制代码
mkdir -p vela-opensource && cd vela-opensource

3. 使用Gitee镜像初始化repo(推荐国内用户使用)

bash 复制代码
repo init --partial-clone -u https://gitee.com/open-vela/manifests.git -b dev -m openvela.xml --git-lfs --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/

4. 配置Git LFS

bash 复制代码
git lfs install && git lfs --version

5. 返回工作目录并下载openvela源码

bash 复制代码
repo sync -c -j8

16核可以j16


启动模拟器

运行模拟项目


Hello World 示例应用程序

code:https://github.com/lvy010/vela/blob/main/hello_main/README.md

项目概述

这是一个基于 openvela 和 NuttX 操作系统的 Hello World 示例应用程序。该项目展示了如何在 openvela 开发框架中添加新的应用程序,包括完整的构建配置和运行说明。

项目结构

复制代码
apps/examples/hello_main/
├── README.md           # 项目说明文档
├── hello_main.c        # 主程序源代码
├── CMakeLists.txt      # CMake 构建配置
├── Kconfig            # 内核配置选项
├── Makefile           # Make 构建规则
└── Make.defs          # 构建系统配置

文件说明

1. hello_main.c

主程序源代码文件,包含一个简单的 Hello World 程序:

c 复制代码
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, World!!\n");
    return 0;
}

2. Kconfig

内核配置文件,定义了应用程序的配置选项:

  • CONFIG_EXAMPLES_HELLO: 启用 Hello World 示例
  • CONFIG_EXAMPLES_HELLO_PROGNAME: 程序名称(默认为 "hello")
  • CONFIG_EXAMPLES_HELLO_PRIORITY: 任务优先级(默认为 100)
  • CONFIG_EXAMPLES_HELLO_STACKSIZE: 栈大小(默认为 DEFAULT_TASK_STACKSIZE)

3. CMakeLists.txt

CMake 构建配置文件,使用 nuttx_add_application 函数配置应用程序:

cmake 复制代码
if(CONFIG_EXAMPLES_HELLO)
  nuttx_add_application(
    NAME ${CONFIG_EXAMPLES_HELLO_PROGNAME}
    SRCS hello_main.c
    STACKSIZE ${CONFIG_EXAMPLES_HELLO_STACKSIZE}
    PRIORITY ${CONFIG_EXAMPLES_HELLO_PRIORITY})
endif()

4. Makefile

传统 Make 构建规则文件,定义了编译参数和依赖关系:

  • PROGNAME: 程序名称
  • PRIORITY: 任务优先级
  • STACKSIZE: 栈大小
  • MAINSRC: 主函数源文件

5. Make.defs

构建系统配置文件,将应用程序添加到编译列表中:

makefile 复制代码
ifneq ($(CONFIG_EXAMPLES_HELLO),)
CONFIGURED_APPS += $(APPDIR)/examples/hello_main
endif

构建和运行

1. 清理项目

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8

2. 配置项目

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig -j8

在 menuconfig 中启用 EXAMPLES_HELLO 选项。

3. 编译项目

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8

4. 运行模拟器

5. 测试程序

在模拟器启动后,在串口中输入程序名称:

bash 复制代码
hello

预期输出:

技术特性

  • 架构支持: ARM32 (armeabi-v7a)
  • 构建系统: 支持 CMake 和传统 Make
  • 配置管理: 集成 Kconfig 系统
  • 任务管理: 可配置的任务优先级和栈大小
  • 跨平台: 基于 NuttX 的跨平台支持

故障排除

常见问题

  1. "NuttX binary not found" 错误

    • 确保已正确编译项目
    • 检查 nuttx/nuttx 符号链接是否正确指向 vela_ap.elf
  2. "Invalid NuttX binary" 错误

    • 检查二进制文件类型:file nuttx/vela_ap.elf
    • 确保脚本能正确检测 ARM 架构
  3. Qt 平台插件错误

    • 在服务器环境中使用 -qemu 参数:./emulator.sh vela -qemu

调试技巧

  • 使用调试版本的脚本查看详细输出
  • 检查进程状态:ps aux | grep -E "(emulator|qemu)"
  • 验证二进制文件:strings nuttx/vela_ap.elf | grep -i "hello"

扩展开发

添加新功能

  1. hello_main.c 中添加新的功能代码
  2. 更新 Kconfig 添加新的配置选项
  3. 修改 CMakeLists.txtMakefile 添加新的源文件
  4. 重新编译和测试

集成第三方库

  1. external/ 目录下添加库文件
  2. 更新 Makefile 中的 CFLAGSCSRCS
  3. CMakeLists.txt 中添加依赖关系

相关文档


添加 Hello World 示例:从零开始的完整实践与问题复盘

最近,我尝试为一个嵌入式项目(OpenVela + NuttX)添加一个简单的 Hello World 示例程序。虽然目标看似简单,但在实际操作过程中却遇到了一些挑战。本文将详细记录整个过程,从创建文件到最终成功运行,并对遇到的问题进行复盘,希望能为后来者提供一些参考。


🚀 第一步:创建目录结构

首先,我们需要在项目中创建一个用于存放示例代码的目录:

bash 复制代码
mkdir -p apps/examples/hello_main

这一步非常基础,但却是后续所有操作的前提。


✏️ 第二步:创建 hello_main.c 文件

接下来,编写最核心的 C 源码文件:

c 复制代码
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, World!!\n");
    return 0;
}

这是一个标准的 C 程序入口,功能是打印一句"Hello, World!!"。


⚙️ 第三步:创建 Kconfig 文件

为了让 menuconfig 能识别我们的示例,需要添加配置项:

kconfig 复制代码
config EXAMPLES_HELLO
    bool "Hello World Example"
    default y
    help
      Build the Hello World example program.

这个文件定义了一个布尔类型的配置选项,可以在图形化配置界面中启用或禁用该示例。


📦 第四步:创建 CMakeLists.txt(如果使用 CMake)

尽管当前项目主要使用 Make 构建系统,但为了兼容性,也可以添加一个空的 CMakeLists.txt 文件:

cmake 复制代码
# Placeholder for CMake support

🛠️ 第五步:创建 Makefile

这是构建系统的关键部分,告诉 Make 如何编译我们的程序:

makefile 复制代码
include $(APPDIR)/Make.defs

CFLAGS += ${EXTRAFLAGS}
LDLIBS += $(APPDIR)/lib/libapps.a
AOBJS += hello_main.o

MAINSRC = $(AOBJS:.o=)

APPBUILDIR = $(OUTDIR)/$(APPDIR)
ASRCS = $(AOBJS:.o=.s)
COBJS = $(AOBJS:.o=.o)

SRCS = $(ASRCS) $(COBJS)
OBJS = $(AOBJS)

ifneq ($(CONFIG_BUILD_KERNEL),y)
  PROGRAM = $(patsubst %,$(BINDIR)/%,$(CONFIG_EXAMPLES_HELLO_PROGNAME))
endif

include $(APPDIR)/Application.mk

其中 CONFIG_EXAMPLES_HELLO_PROGNAME 会在 Make.defs 中定义。


🔧 第六步:创建 Make.defs

此文件用于定义程序名称和是否启用:

makefile 复制代码
CONFIG_EXAMPLES_HELLO_PROGNAME ?= hello
CONFIG_EXAMPLES_HELLO_PRIORITY ?= SCHED_PRIORITY_DEFAULT
CONFIG_EXAMPLES_HELLO_STACKSIZE ?= 2048

这些变量将被主构建系统读取并应用。


🔍 第七步:检查上层目录的 Make.defs

我们还需要确认上级目录 apps/examples/Make.defs 是否包含子目录的 Make.defs。幸运的是,它已经包含了通配符:

makefile 复制代码
$(wildcard $(APPDIR)/examples/*/Make.defs)

这意味着我们的 hello_main/Make.defs 会被自动加载,无需额外修改。


💣 第八步:清理并重新编译

为了避免旧配置干扰,先执行清理:

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8

然后准备重新构建整个项目。


运行配置工具以启用我们的示例:

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig -j8

成功启动后,在菜单中找到并启用 Hello World Example 选项。

✅ 提示:按 Y 启用,按 N 禁用,按 ESC 保存并退出。


🔨 第十步:编译项目

执行编译命令:

bash 复制代码
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8

编译完成后,检查输出文件:

bash 复制代码
ls -la nuttx/vela_ap.elf nuttx/vela_ap.bin

并通过 strings 检查是否包含我们的字符串:

bash 复制代码
strings nuttx/vela_ap.elf | grep -i "hello"

输出如下,说明已成功集成:

复制代码
Hello, World!!
hello_main
CONFIG_EXAMPLES_HELLO 1
CONFIG_EXAMPLES_HELLO_PROGNAME "hello"

🎉 成功!程序已被编译进固件。


🖥️ 第十一步:运行模拟器测试

激动人心的时刻到了------运行模拟器:

bash 复制代码
./emulator.sh vela

然而,结果并不顺利......

❌ 问题一:找不到 NuttX 二进制文件

错误信息:

复制代码
Invalid NuttX binary
CPU Architecture '' is not supported

原因分析

模拟器脚本 run_emulator.sh 默认查找名为 nuttx 的可执行文件,但我们生成的是 vela_ap.elf

解决方案

创建符号链接:

bash 复制代码
cd nuttx && ln -sf vela_ap.elf nuttx && cd ..

❌ 问题二:架构检测失败(ARM)

虽然我们生成的是 ARM 架构的 ELF 文件:

bash 复制代码
file nuttx/vela_ap.elf
# 输出:ELF 32-bit LSB executable, ARM, EABI5...

但脚本中检测逻辑为:

bash 复制代码
file -b ${NUTTX_BIN} | grep 'ELF 32-bit LSB executable, ARM'

${NUTTX_BIN} 是符号链接时,file 命令可能不会自动解析其目标内容。

解决方案

修改 run_emulator.sh,先解析符号链接:

bash 复制代码
NUTTX_BIN=$(readlink -f ${NUTTX_BIN})

然后再进行类型判断。


❌ 问题三:Qt 平台插件错误(无图形环境)

在服务器环境下运行 GUI 模拟器会报错:

复制代码
Could not load the Qt platform plugin "xcb"

原因:缺少 X11 图形界面支持。

解决方案:使用纯 QEMU 模式运行:

bash 复制代码
./emulator.sh vela -qemu

这样可以避免依赖图形界面。


✅ 最终结果

经过上述调整后,QEMU 成功启动,NuttX 系统正常运行。我们可以进入 shell 并运行新添加的程序:

shell 复制代码
nsh> hello
Hello, World!!

🎉 大功告成!

"每一个伟大的程序,都始于一句 Hello, World!"

相关推荐
XINVRY-FPGA44 分钟前
EPM240T100I5N Altera FPGA MAX II CPLD
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发·射频工程·fpga
啊阿狸不会拉杆4 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路4 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
曙曙学编程5 小时前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件
△曉風殘月〆5 小时前
Visual Studio中的常用调试功能(下)
c++·ide·visual studio·调试
武当豆豆5 小时前
C++编程学习(第25天)
开发语言·c++·学习
第二层皮-合肥6 小时前
FPGA实现ETH接口
单片机·嵌入式硬件·fpga开发
anghost1506 小时前
基于单片机的智能声控窗帘
单片机·嵌入式硬件·mongodb
minji...9 小时前
C++ string类(STL简介 , string类 , 访问修改字符)
开发语言·c++