[openvela] Hello World :从零开始的完整实践与问题复盘
链接:git clone https://gitee.com/mirrors/lvgl.git
github上下载可能会限速,建议使用镜像,非常快~
配置openvela的开发环境。根据文档,我们需要使用repo工具来管理多个Git仓库。
1. 安装必要的依赖工具
sudo apt update && sudo apt install -y git-lfs repo curl wget build-essential
2. 创建openvela工作目录并初始化
mkdir -p vela-opensource && cd vela-opensource
3. 使用Gitee镜像初始化repo(推荐国内用户使用)
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
git lfs install && git lfs --version
5. 返回工作目录并下载openvela源码
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 程序:
#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
函数配置应用程序:
if(CONFIG_EXAMPLES_HELLO)nuttx_add_application(NAME ${CONFIG_EXAMPLES_HELLO_PROGNAME}SRCS hello_main.cSTACKSIZE ${CONFIG_EXAMPLES_HELLO_STACKSIZE}PRIORITY ${CONFIG_EXAMPLES_HELLO_PRIORITY})
endif()
4. Makefile
传统 Make 构建规则文件,定义了编译参数和依赖关系:
PROGNAME
: 程序名称PRIORITY
: 任务优先级STACKSIZE
: 栈大小MAINSRC
: 主函数源文件
5. Make.defs
构建系统配置文件,将应用程序添加到编译列表中:
ifneq ($(CONFIG_EXAMPLES_HELLO),)
CONFIGURED_APPS += $(APPDIR)/examples/hello_main
endif
构建和运行
1. 清理项目
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8
2. 配置项目
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig -j8
在 menuconfig 中启用 EXAMPLES_HELLO
选项。
3. 编译项目
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8
4. 运行模拟器
5. 测试程序
在模拟器启动后,在串口中输入程序名称:
hello
预期输出:
技术特性
- 架构支持: ARM32 (armeabi-v7a)
- 构建系统: 支持 CMake 和传统 Make
- 配置管理: 集成 Kconfig 系统
- 任务管理: 可配置的任务优先级和栈大小
- 跨平台: 基于 NuttX 的跨平台支持
故障排除
常见问题
-
“NuttX binary not found” 错误
- 确保已正确编译项目
- 检查
nuttx/nuttx
符号链接是否正确指向vela_ap.elf
-
“Invalid NuttX binary” 错误
- 检查二进制文件类型:
file nuttx/vela_ap.elf
- 确保脚本能正确检测 ARM 架构
- 检查二进制文件类型:
-
Qt 平台插件错误
- 在服务器环境中使用
-qemu
参数:./emulator.sh vela -qemu
- 在服务器环境中使用
调试技巧
- 使用调试版本的脚本查看详细输出
- 检查进程状态:
ps aux | grep -E "(emulator|qemu)"
- 验证二进制文件:
strings nuttx/vela_ap.elf | grep -i "hello"
扩展开发
添加新功能
- 在
hello_main.c
中添加新的功能代码 - 更新
Kconfig
添加新的配置选项 - 修改
CMakeLists.txt
和Makefile
添加新的源文件 - 重新编译和测试
集成第三方库
- 在
external/
目录下添加库文件 - 更新
Makefile
中的CFLAGS
和CSRCS
- 在
CMakeLists.txt
中添加依赖关系
相关文档
- openvela 开发指南
- NuttX 编程手册
- Android 模拟器文档
添加 Hello World 示例:从零开始的完整实践与问题复盘
最近,我尝试为一个嵌入式项目(OpenVela + NuttX)添加一个简单的 Hello World
示例程序。虽然目标看似简单,但在实际操作过程中却遇到了一些挑战。本文将详细记录整个过程,从创建文件到最终成功运行,并对遇到的问题进行复盘,希望能为后来者提供一些参考。
🚀 第一步:创建目录结构
首先,我们需要在项目中创建一个用于存放示例代码的目录:
mkdir -p apps/examples/hello_main
这一步非常基础,但却是后续所有操作的前提。
✏️ 第二步:创建 hello_main.c
文件
接下来,编写最核心的 C 源码文件:
#include <stdio.h>int main(int argc, char *argv[])
{printf("Hello, World!!\n");return 0;
}
这是一个标准的 C 程序入口,功能是打印一句“Hello, World!!”。
⚙️ 第三步:创建 Kconfig 文件
为了让 menuconfig
能识别我们的示例,需要添加配置项:
config EXAMPLES_HELLObool "Hello World Example"default yhelpBuild the Hello World example program.
这个文件定义了一个布尔类型的配置选项,可以在图形化配置界面中启用或禁用该示例。
📦 第四步:创建 CMakeLists.txt(如果使用 CMake)
尽管当前项目主要使用 Make 构建系统,但为了兼容性,也可以添加一个空的 CMakeLists.txt
文件:
# Placeholder for CMake support
🛠️ 第五步:创建 Makefile
这是构建系统的关键部分,告诉 Make 如何编译我们的程序:
include $(APPDIR)/Make.defsCFLAGS += ${EXTRAFLAGS}
LDLIBS += $(APPDIR)/lib/libapps.a
AOBJS += hello_main.oMAINSRC = $(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))
endifinclude $(APPDIR)/Application.mk
其中 CONFIG_EXAMPLES_HELLO_PROGNAME
会在 Make.defs
中定义。
🔧 第六步:创建 Make.defs
此文件用于定义程序名称和是否启用:
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
。幸运的是,它已经包含了通配符:
$(wildcard $(APPDIR)/examples/*/Make.defs)
这意味着我们的 hello_main/Make.defs
会被自动加载,无需额外修改。
💣 第八步:清理并重新编译
为了避免旧配置干扰,先执行清理:
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8
然后准备重新构建整个项目。
🎛️ 第九步:启动 menuconfig 配置
运行配置工具以启用我们的示例:
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig -j8
成功启动后,在菜单中找到并启用 Hello World Example
选项。
✅ 提示:按
Y
启用,按N
禁用,按ESC
保存并退出。
🔨 第十步:编译项目
执行编译命令:
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8
编译完成后,检查输出文件:
ls -la nuttx/vela_ap.elf nuttx/vela_ap.bin
并通过 strings
检查是否包含我们的字符串:
strings nuttx/vela_ap.elf | grep -i "hello"
输出如下,说明已成功集成:
Hello, World!!
hello_main
CONFIG_EXAMPLES_HELLO 1
CONFIG_EXAMPLES_HELLO_PROGNAME "hello"
🎉 成功!程序已被编译进固件。
🖥️ 第十一步:运行模拟器测试
激动人心的时刻到了——运行模拟器:
./emulator.sh vela
然而,结果并不顺利……
❌ 问题一:找不到 NuttX 二进制文件
错误信息:
Invalid NuttX binary
CPU Architecture '' is not supported
原因分析:
模拟器脚本 run_emulator.sh
默认查找名为 nuttx
的可执行文件,但我们生成的是 vela_ap.elf
。
解决方案:
创建符号链接:
cd nuttx && ln -sf vela_ap.elf nuttx && cd ..
❌ 问题二:架构检测失败(ARM)
虽然我们生成的是 ARM 架构的 ELF 文件:
file nuttx/vela_ap.elf
# 输出:ELF 32-bit LSB executable, ARM, EABI5...
但脚本中检测逻辑为:
file -b ${NUTTX_BIN} | grep 'ELF 32-bit LSB executable, ARM'
当 ${NUTTX_BIN}
是符号链接时,file
命令可能不会自动解析其目标内容。
解决方案:
修改 run_emulator.sh
,先解析符号链接:
NUTTX_BIN=$(readlink -f ${NUTTX_BIN})
然后再进行类型判断。
❌ 问题三:Qt 平台插件错误(无图形环境)
在服务器环境下运行 GUI 模拟器会报错:
Could not load the Qt platform plugin "xcb"
原因:缺少 X11 图形界面支持。
解决方案:使用纯 QEMU 模式运行:
./emulator.sh vela -qemu
这样可以避免依赖图形界面。
✅ 最终结果
经过上述调整后,QEMU 成功启动,NuttX 系统正常运行。我们可以进入 shell 并运行新添加的程序:
nsh> hello
Hello, World!!
🎉 大功告成!
“每一个伟大的程序,都始于一句
Hello, World!
”