code: https://github.com/lvy010/vela/tree/main/music_player

OpenVela 音乐播放器

基于 OpenVela 系统的嵌入式音乐播放器,使用 LVGL 图形库开发,支持 Wi-Fi 连接和本地音频播放。

📋 目录

🎵 项目简介

本项目是一个功能完整的嵌入式音乐播放器,专为 OpenVela 系统设计。它提供了现代化的用户界面,支持音频播放、播放列表管理、音量控制等功能。应用程序采用模块化设计,易于扩展和维护。

主要亮点

  • 🎨 现代化 UI:基于 LVGL 的精美图形界面
  • 🎵 音频支持:支持 WAV 格式音频文件播放
  • 📱 触屏友好:完整的触屏操作支持
  • 🌐 网络功能:内置 Wi-Fi 连接管理
  • 高性能:优化的嵌入式系统性能
  • 🔧 易于扩展:模块化架构设计

✨ 功能特性

核心功能

  • ▶️ 音频播放控制(播放/暂停/停止)
  • ⏭️ 上一首/下一首切换
  • 🔊 音量调节
  • 📋 播放列表管理
  • 🕒 播放进度显示
  • 📊 实时时间显示

界面功能

  • 📱 1280x800 分辨率支持
  • 🎨 专辑封面显示
  • 🎭 动态主题色彩
  • 📜 滚动播放列表
  • 🎛️ 可视化音量条

系统功能

  • 🌐 Wi-Fi 网络连接
  • 📁 文件系统集成
  • 🔧 配置文件管理
  • 📊 系统资源监控

🔧 系统要求

硬件要求

  • 处理器:ARM Cortex-A7 或更高
  • 内存:至少 128MB RAM
  • 存储:至少 256MB 闪存
  • 显示:1280x800 分辨率触摸屏
  • 音频:PCM 音频输出支持

软件要求

  • 操作系统:OpenVela
  • 图形库:LVGL 8.x
  • 音频库:NuttX Audio 框架
  • 网络:Wi-Fi 驱动支持

开发环境

  • 编译器:arm-none-eabi-gcc
  • 构建系统:Make
  • 调试工具:ADB
  • 主机系统:Linux (推荐 Ubuntu 22.04)

📁 项目结构

music_player/
├── src/                          # 源代码目录
│   ├── music_player.c           # 主应用逻辑
│   ├── music_player.h           # 主应用头文件
│   ├── music_player_main.c      # 应用程序入口
│   ├── audio_ctl.c              # 音频控制模块
│   ├── audio_ctl.h              # 音频控制头文件
│   ├── wifi.c                   # Wi-Fi 管理模块
│   └── wifi.h                   # Wi-Fi 管理头文件
├── res/                         # 资源文件目录
│   ├── fonts/                   # 字体文件
│   │   ├── MiSans-Normal.ttf   # 常规字体
│   │   └── MiSans-Semibold.ttf # 半粗体字体
│   ├── icons/                   # 图标文件
│   │   ├── album_picture.png    # 专辑图片
│   │   ├── audio.png           # 音频图标
│   │   ├── music.png           # 音乐图标
│   │   ├── mute.png            # 静音图标
│   │   ├── next.png            # 下一首图标
│   │   ├── nocover.png         # 无封面占位图
│   │   ├── pause.png           # 暂停图标
│   │   ├── play.png            # 播放图标
│   │   ├── playlist.png        # 播放列表图标
│   │   └── previous.png        # 上一首图标
│   ├── musics/                  # 音乐文件目录
│   │   ├── manifest.json       # 音乐列表配置
│   │   ├── UnamedRhythm.wav    # 示例音频文件
│   │   └── UnamedRhythm.png    # 示例专辑封面
│   └── config.json             # 全局配置文件
├── build/                       # 构建输出目录
│   ├── *.o                     # 目标文件
│   ├── .built                  # 构建标记
│   └── .depend                 # 依赖文件
├── Kconfig                      # 内核配置
├── Makefile                     # 主构建文件
├── Make.defs                    # 构建定义
├── Make.dep                     # 构建依赖
└── README.md                    # 项目文档

核心模块说明

1. music_player.c/h
  • 功能:应用程序主逻辑
  • 职责:UI 管理、状态控制、事件处理
  • 关键结构
    • struct ctx_s:运行时上下文
    • struct resource_s:UI 资源管理
    • album_info_t:专辑信息结构
2. audio_ctl.c/h
  • 功能:音频控制模块
  • 职责:音频播放、暂停、停止、音量控制
  • 支持格式:WAV 音频文件
  • 接口:NuttX Audio 框架
3. wifi.c/h
  • 功能:Wi-Fi 连接管理
  • 职责:网络连接、配置管理
  • 配置:基于 config.json
4. 资源文件管理
  • 字体:多种字重的 MiSans 字体
  • 图标:SVG 转换的 PNG 图标
  • 音频:WAV 格式音乐文件
  • 配置:JSON 格式配置文件

🚀 快速开始

1. 环境准备

# 安装必要的工具
sudo apt update
sudo apt install -y android-tools-adb build-essential git

# 克隆 OpenVela 仓库
git clone <openvela-repo-url>
cd vela_code

2. 配置项目

# 进入项目根目录
cd /root/vela_code

# 配置音乐播放器
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig

# 或者直接编辑配置文件
echo "CONFIG_LVX_USE_DEMO_MUSIC_PLAYER=y" >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig
echo 'CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT="/data"' >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig

3. 编译项目

# 清理构建产物
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8

# 开始构建
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8

4. 启动模拟器

# 创建 nuttx 符号链接(如果不存在)
cd nuttx && ln -sf vela_ap.elf nuttx && cd ..

# 启动模拟器
./emulator.sh vela

5. 部署资源

# 等待模拟器启动
sleep 15

# 连接 ADB
adb connect 127.0.0.1:5555

# 推送资源文件
adb -s emulator-5554 push apps/packages/demos/music_player/res /data/

6. 运行应用

# 通过 ADB Shell 启动音乐播放器
adb -s emulator-5554 shell "music_player &"

⚙️ 配置说明

config.json 配置

{
  "wifi": {
    "ssid": "your_wifi_name",     // Wi-Fi 网络名称
    "pswd": "your_password"       // Wi-Fi 密码
  }
}

注意:请勿在代码中硬编码敏感信息,建议通过环境变量或安全存储方式加载。

manifest.json 音乐配置

{
  "musics": [
    {
      "path": "UnamedRhythm.wav",     // 音频文件路径
      "name": "UnamedRhythm",         // 歌曲名称
      "artist": "Benign X",           // 艺术家
      "cover": "UnamedRhythm.png",    // 专辑封面
      "total_time": 12000,            // 总时长(毫秒)
      "color": "#114514"              // 主题颜色
    }
  ]
}

Kconfig 配置选项

CONFIG_LVX_USE_DEMO_MUSIC_PLAYER        # 启用音乐播放器
CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT       # 数据根目录路径
CONFIG_LVX_MUSIC_PLAYER_STACKSIZE       # 应用栈大小
CONFIG_LVX_MUSIC_PLAYER_PRIORITY        # 应用优先级

🔨 构建指南

构建系统概述

项目使用 NuttX 构建系统,包含以下关键文件:

Makefile
include $(APPDIR)/Make.defs

ifeq ($(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER), y)
PROGNAME = music_player          # 程序名称
PRIORITY = 100                   # 优先级
STACKSIZE = 40960               # 栈大小(字节)
MODULE = $(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER)

CSRCS = music_player.c audio_ctl.c wifi.c     # C源文件
MAINSRC = music_player_main.c                  # 主入口文件
endif

include $(APPDIR)/Application.mk
Make.defs
ifneq ($(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER),)
CONFIGURED_APPS += $(APPDIR)/packages/demos/music_player
endif

构建选项

调试版本
# 启用调试符号
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap DEBUG=1 -j8
发布版本
# 优化构建
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap OPTIMIZE=2 -j8
清理构建
# 完全清理
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean

# 仅清理音乐播放器
make -C apps/packages/demos/music_player clean

构建产物

成功构建后会生成:

  • nuttx/vela_ap.elf:主可执行文件
  • nuttx/vela_ap.bin:二进制映像
  • nuttx/vela_system.bin:系统映像
  • nuttx/vela_data.bin:数据映像

🚢 部署运行

模拟器部署

1. 启动模拟器
# 启动 QEMU 模拟器
./emulator.sh vela

# 检查模拟器状态
ps aux | grep qemu
2. ADB 连接
# 检查 ADB 服务
adb devices

# 连接到模拟器
adb connect 127.0.0.1:5555

# 验证连接
adb -s emulator-5554 shell uname -a
3. 文件传输
# 创建目标目录
adb -s emulator-5554 shell mkdir -p /data/res

# 推送资源文件
adb -s emulator-5554 push res/ /data/

# 验证文件
adb -s emulator-5554 shell ls -la /data/res/

硬件设备部署

1. 串口连接
# 配置串口连接
minicom -s
# 设置:115200 8N1,无流控

# 或使用 screen
screen /dev/ttyUSB0 115200
2. 网络部署
# 配置网络启动
setenv serverip 192.168.1.100
setenv ipaddr 192.168.1.200
tftp 0x40000000 vela_ap.bin
go 0x40000000
3. 存储部署
# 烧录到 Flash
flash erase 0x00000000 0x00800000
flash write 0x40000000 0x00000000 0x00800000

运行时监控

1. 系统监控
# 检查系统状态
adb shell ps
adb shell free
adb shell df -h

# 查看日志
adb shell dmesg
adb logcat
2. 应用监控
# 检查音乐播放器进程
adb shell ps | grep music_player

# 查看应用日志
adb shell tail -f /var/log/music_player.log
3. 性能分析
# CPU 使用率
adb shell top -p $(adb shell pidof music_player)

# 内存使用
adb shell cat /proc/$(adb shell pidof music_player)/status

🎨 自定义指南

添加新音乐

1. 准备音频文件
# 转换音频格式(如果需要)
ffmpeg -i input.mp3 -acodec pcm_s16le -ar 44100 -ac 2 output.wav

# 准备专辑封面(推荐 300x300)
convert cover.jpg -resize 300x300 cover.png
2. 更新配置文件
{
  "musics": [
    {
      "path": "new_song.wav",
      "name": "新歌名称",
      "artist": "艺术家名称",
      "cover": "new_cover.png",
      "total_time": 240000,
      "color": "#FF5722"
    }
  ]
}
3. 部署文件
# 复制文件到资源目录
cp new_song.wav res/musics/
cp new_cover.png res/musics/

# 推送到设备
adb push res/musics/ /data/res/musics/

自定义界面

1. 修改主题颜色
// 在 music_player.c 中修改
#define THEME_PRIMARY_COLOR   lv_color_hex(0x2196F3)
#define THEME_SECONDARY_COLOR lv_color_hex(0xFF5722)
#define THEME_BACKGROUND_COLOR lv_color_hex(0x121212)
2. 调整界面布局
// 修改分辨率适配
#define SCREEN_WIDTH  1280
#define SCREEN_HEIGHT 800
#define UI_SCALE_FACTOR 1.0f

// 调整控件大小
#define ALBUM_COVER_SIZE 300
#define BUTTON_SIZE 60
#define PROGRESS_BAR_HEIGHT 8
3. 添加新功能
// 添加均衡器功能
typedef struct {
    int8_t bass;
    int8_t middle;
    int8_t treble;
} equalizer_t;

static void app_equalizer_apply(equalizer_t* eq) {
    // 实现均衡器逻辑
}

扩展音频格式

1. 添加 MP3 支持
// 在 audio_ctl.c 中添加
#ifdef CONFIG_AUDIO_MP3_SUPPORT
#include <mad.h>

static int mp3_decode(const char* file_path) {
    // 实现 MP3 解码
}
#endif
2. 配置构建系统
config MUSIC_PLAYER_MP3_SUPPORT
    bool "Enable MP3 support"
    default n
    depends on LVX_USE_DEMO_MUSIC_PLAYER

🔧 故障排除

常见问题

1. 编译错误

问题music_player: command not found

# 解决方案:检查配置
grep -r LVX_USE_DEMO_MUSIC_PLAYER vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig

# 重新配置和编译
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean
./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8

问题:栈溢出错误

# 解决方案:增加栈大小
# 编辑 Makefile
STACKSIZE = 65536  # 从 32768 增加到 65536
2. 运行时错误

问题:找不到资源文件

# 检查文件是否存在
adb shell ls -la /data/res/

# 重新推送资源
adb push res/ /data/

问题:音频播放失败

# 检查音频设备
adb shell ls -la /dev/audio/

# 检查音频格式
file res/musics/*.wav
3. 模拟器问题

问题:模拟器启动失败

# 检查 nuttx 文件
ls -la nuttx/nuttx

# 重新创建符号链接
cd nuttx && rm -f nuttx && ln -sf vela_ap.elf nuttx

问题:ADB 连接失败

# 检查端口
netstat -tlnp | grep 555

# 重新连接
adb disconnect 127.0.0.1:5555
adb connect 127.0.0.1:5555

调试技巧

1. 使用日志输出
// 添加调试日志
#define MUSIC_DEBUG 1

#if MUSIC_DEBUG
#define DLOG(fmt, ...) printf("[MUSIC] " fmt "\n", ##__VA_ARGS__)
#else
#define DLOG(fmt, ...)
#endif

// 在关键位置添加日志
DLOG("Loading audio file: %s", file_path);
DLOG("Audio playback started, duration: %lu ms", duration);
2. 使用 GDB 调试
# 启动 GDB 服务器
./emulator.sh vela -s -S

# 连接 GDB
arm-none-eabi-gdb nuttx/nuttx
(gdb) target remote localhost:1234
(gdb) b main
(gdb) c
3. 内存分析
// 添加内存使用统计
static void print_memory_usage(void) {
    struct mallinfo info = mallinfo();
    printf("Memory usage:\n");
    printf("  Total heap: %d bytes\n", info.arena);
    printf("  Used heap: %d bytes\n", info.uordblks);
    printf("  Free heap: %d bytes\n", info.fordblks);
}

性能优化

1. 界面优化
// 减少不必要的重绘
lv_obj_add_flag(obj, LV_OBJ_FLAG_FLOATING);

// 使用缓存提高性能
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0);
2. 音频优化
// 优化音频缓冲区大小
#define AUDIO_BUFFER_SIZE (4096 * 4)  // 16KB 缓冲区

// 使用DMA传输
static int audio_dma_setup(void) {
    // 配置 DMA 音频传输
}
3. 内存优化
// 预分配内存池
static uint8_t audio_buffer_pool[AUDIO_BUFFER_SIZE * 4];
static uint8_t ui_buffer_pool[UI_BUFFER_SIZE];

// 使用对象池管理
static album_info_t album_pool[MAX_ALBUMS];

🏗️ 技术架构

架构概览

在这里插入图片描述

数据流图

在这里插入图片描述

模块关系

在这里插入图片描述

关键数据结构

运行时上下文
struct ctx_s {
    bool resource_healthy_check;          // 资源健康检查
    album_info_t* current_album;          // 当前专辑
    lv_obj_t* current_album_related_obj;  // 关联UI对象
    
    uint16_t volume;                      // 音量
    play_status_t play_status_prev;       // 上一次播放状态
    play_status_t play_status;            // 当前播放状态
    uint64_t current_time;                // 当前播放时间
    
    struct {
        lv_timer_t* volume_bar_countdown;      // 音量条倒计时
        lv_timer_t* playback_progress_update;  // 播放进度更新
    } timers;
    
    audioctl_s* audioctl;                 // 音频控制句柄
};
资源管理
struct resource_s {
    struct {
        lv_obj_t* time;           // 时间显示
        lv_obj_t* date;           // 日期显示
        lv_obj_t* player_group;   // 播放器组
        // ... 更多UI组件
    } ui;
    
    struct {
        struct { lv_font_t* normal; } size_16;
        struct { lv_font_t* bold; } size_22;
        // ... 更多字体
    } fonts;
    
    struct {
        lv_style_t button_default;    // 按钮默认样式
        lv_style_t button_pressed;    // 按钮按下样式
        // ... 更多样式
    } styles;
    
    album_info_t* albums;         // 专辑数组
    uint8_t album_count;          // 专辑数量
};

状态机设计

typedef enum {
    PLAY_STATUS_STOP,    // 停止
    PLAY_STATUS_PLAY,    // 播放
    PLAY_STATUS_PAUSE,   // 暂停
} play_status_t;

// 状态转换表
static const state_transition_t transitions[] = {
    {PLAY_STATUS_STOP,  PLAY_STATUS_PLAY,  action_start_playback},
    {PLAY_STATUS_PLAY,  PLAY_STATUS_PAUSE, action_pause_playback},
    {PLAY_STATUS_PAUSE, PLAY_STATUS_PLAY,  action_resume_playback},
    {PLAY_STATUS_PLAY,  PLAY_STATUS_STOP,  action_stop_playback},
    {PLAY_STATUS_PAUSE, PLAY_STATUS_STOP,  action_stop_playback},
};

📚 API 参考

核心 API

应用程序控制
/**
 * @brief 创建并初始化音乐播放器应用
 * @return void
 */
void app_create(void);

/**
 * @brief 设置播放状态
 * @param status 播放状态
 */
static void app_set_play_status(play_status_t status);

/**
 * @brief 切换到指定专辑
 * @param index 专辑索引
 */
static void app_switch_to_album(int index);

/**
 * @brief 设置音量
 * @param volume 音量值 (0-100)
 */
static void app_set_volume(uint16_t volume);
音频控制 API
/**
 * @brief 初始化音频控制器
 * @param file_path 音频文件路径
 * @return 音频控制句柄
 */
audioctl_s* audio_ctl_init_nxaudio(const char* file_path);

/**
 * @brief 开始播放
 * @param audioctl 音频控制句柄
 * @return 0 成功, -1 失败
 */
int audio_ctl_start(audioctl_s* audioctl);

/**
 * @brief 暂停播放
 * @param audioctl 音频控制句柄
 * @return 0 成功, -1 失败
 */
int audio_ctl_pause(audioctl_s* audioctl);

/**
 * @brief 停止播放
 * @param audioctl 音频控制句柄
 * @return 0 成功, -1 失败
 */
int audio_ctl_stop(audioctl_s* audioctl);

/**
 * @brief 设置音量
 * @param audioctl 音频控制句柄
 * @param volume 音量值
 * @return 0 成功, -1 失败
 */
int audio_ctl_set_volume(audioctl_s* audioctl, uint16_t volume);
Wi-Fi 管理 API
/**
 * @brief Wi-Fi 配置结构
 */
typedef struct {
    char ssid[64];      // 网络名称
    char psk[128];      // 密码
    uint32_t conn_delay; // 连接延迟
} wifi_conf_t;

/**
 * @brief 连接 Wi-Fi
 * @param conf Wi-Fi 配置
 * @return 0 成功, -1 失败
 */
int wifi_connect(wifi_conf_t* conf);

/**
 * @brief 断开 Wi-Fi 连接
 * @return 0 成功, -1 失败
 */
int wifi_disconnect(void);

/**
 * @brief 获取连接状态
 * @return true 已连接, false 未连接
 */
bool wifi_is_connected(void);

UI 组件 API

事件处理
/**
 * @brief 播放按钮事件处理
 * @param e 事件对象
 */
static void app_play_status_event_handler(lv_event_t* e);

/**
 * @brief 音量条事件处理
 * @param e 事件对象
 */
static void app_volume_bar_event_handler(lv_event_t* e);

/**
 * @brief 播放列表事件处理
 * @param e 事件对象
 */
static void app_playlist_event_handler(lv_event_t* e);
UI 刷新
/**
 * @brief 刷新专辑信息显示
 */
static void app_refresh_album_info(void);

/**
 * @brief 刷新播放进度
 */
static void app_refresh_playback_progress(void);

/**
 * @brief 刷新音量条
 */
static void app_refresh_volume_bar(void);

/**
 * @brief 刷新播放列表
 */
static void app_refresh_playlist(void);

配置 API

配置文件管理
/**
 * @brief 读取配置文件
 */
static void read_configs(void);

/**
 * @brief 重新加载音乐配置
 */
static void reload_music_config(void);

/**
 * @brief 保存配置
 * @param config 配置结构
 * @return 0 成功, -1 失败
 */
int save_config(const config_t* config);
资源管理
/**
 * @brief 初始化资源
 * @return true 成功, false 失败
 */
static bool init_resource(void);

/**
 * @brief 加载字体资源
 * @return true 成功, false 失败
 */
static bool load_fonts(void);

/**
 * @brief 加载图片资源
 * @return true 成功, false 失败
 */
static bool load_images(void);

/**
 * @brief 释放资源
 */
static void cleanup_resources(void);

错误代码

#define MUSIC_ERROR_OK              0    // 成功
#define MUSIC_ERROR_INVALID_PARAM  -1    // 无效参数
#define MUSIC_ERROR_NO_MEMORY      -2    // 内存不足
#define MUSIC_ERROR_FILE_NOT_FOUND -3    // 文件未找到
#define MUSIC_ERROR_AUDIO_INIT     -4    // 音频初始化失败
#define MUSIC_ERROR_NETWORK        -5    // 网络错误
#define MUSIC_ERROR_CONFIG         -6    // 配置错误

🤝 贡献指南

开发流程

  1. Fork 项目

    git clone https://github.com/your-username/openvela-music-player.git
    cd openvela-music-player
    
  2. 创建功能分支

    git checkout -b feature/new-feature
    
  3. 开发和测试

    # 开发新功能
    # 编写测试用例
    # 运行测试
    make test
    
  4. 提交更改

    git add .
    git commit -m "feat: add new audio format support"
    
  5. 推送和PR

    git push origin feature/new-feature
    # 创建 Pull Request
    

代码规范

C 代码风格
// 函数命名:snake_case
static void app_create_main_page(void);

// 变量命名:snake_case
static bool resource_healthy_check = false;

// 常量命名:UPPER_CASE
#define MAX_ALBUM_COUNT 100

// 结构体命名:snake_case_t
typedef struct album_info_s {
    const char* name;
    const char* artist;
} album_info_t;
注释规范
/**
 * @brief 函数简要描述
 * @param param1 参数1描述
 * @param param2 参数2描述
 * @return 返回值描述
 * @note 注意事项
 * @warning 警告信息
 */
int function_name(int param1, const char* param2);
提交信息规范
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建/工具相关

示例:
feat: add MP3 audio format support
fix: resolve memory leak in audio playback
docs: update API documentation

测试指南

单元测试
// test/test_audio_ctl.c
#include "unity.h"
#include "audio_ctl.h"

void test_audio_ctl_init(void) {
    audioctl_s* ctl = audio_ctl_init_nxaudio("test.wav");
    TEST_ASSERT_NOT_NULL(ctl);
    audio_ctl_uninit_nxaudio(ctl);
}

void test_audio_ctl_volume(void) {
    audioctl_s* ctl = audio_ctl_init_nxaudio("test.wav");
    int result = audio_ctl_set_volume(ctl, 50);
    TEST_ASSERT_EQUAL(0, result);
    audio_ctl_uninit_nxaudio(ctl);
}
集成测试
# 运行完整测试套件
./scripts/run_tests.sh

# 运行性能测试
./scripts/performance_test.sh

# 运行内存泄漏测试
valgrind --leak-check=full ./music_player

文档贡献

  1. API 文档:使用 Doxygen 格式
  2. 用户文档:使用 Markdown 格式
  3. 代码示例:提供完整可运行的示例
  4. 翻译:支持多语言文档

问题报告

提交 Issue 时请包含:

  • 操作系统和版本
  • OpenVela 版本
  • 复现步骤
  • 期望行为
  • 实际行为
  • 相关日志

📄 许可证

本项目采用 Apache License 2.0 开源许可证。详情请参阅 LICENSE 文件。

🙏 致谢

  • OpenVela 团队:提供优秀的嵌入式操作系统
  • LVGL 社区:提供强大的图形库
  • NuttX 项目:提供可靠的实时操作系统内核

📞 联系

  • 项目主页:https://github.com/openvela/music-player
  • 文档站点:https://docs.openvela.org/music-player
  • 问题反馈:https://github.com/openvela/music-player/issues
  • 讨论社区:https://forum.openvela.org

最后更新时间:2024-08-24

Logo

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

更多推荐