1. 项目概述泰山派NAS-LVGL9监控器是一个基于LVGL图形库开发的嵌入式系统监控界面项目。作为一名长期从事嵌入式开发的工程师我最近在泰山派开发板上实现了一个完整的系统监控解决方案现在将详细的技术实现过程分享给大家。这个项目最大的特点是将安卓Activity的组件化思想引入到嵌入式GUI开发中配合LVGL9.1的强大功能实现了模块化、可扩展的监控界面。整个项目从环境搭建到最终实现涉及多个关键技术点包括LVGL在嵌入式Linux平台的移植FrameBuffer驱动适配触摸输入系统集成仿安卓Activity的UI框架设计系统资源监控实现开发调试技巧下面我将从环境搭建开始逐步讲解这个项目的完整实现过程。2. 开发环境搭建2.1 LVGL基础环境配置LVGLLight and Versatile Graphics Library是一个专为嵌入式系统设计的轻量级图形库支持多种显示设备和输入设备。在开始项目前我们需要搭建好开发环境。首先创建工作目录并获取LVGL源代码mkdir lvgl_blog_demo cd lvgl_blog_demo git clone https://github.com/lvgl/lvgl.git -b release/v9.1为了便于开发调试我们还需要获取Visual Studio模拟器项目git clone --recurse-submodules https://github.com/lvgl/lv_port_pc_visual_studio.git以及Linux平台适配代码git clone https://github.com/lvgl/lv_port_linux.git -b release/v9.02.2 配置文件调整将lv_port_linux目录下的关键文件复制到项目根目录cp lv_port_linux/{Makefile,main.c,CMakeLists.txt,.gitignore} .然后修改Makefile注释掉mouse_cursor_icon.c的引用# CSRCS $(LVGL_DIR)/mouse_cursor_icon.c同样修改CMakeLists.txt移除mouse_cursor_icon.c的编译add_executable(main main.c)2.3 屏幕参数配置复制lvgl目录下的lv_conf_template.h到项目根目录并重命名为lv_conf.h。然后进行以下关键配置#define DISP_WIDTH 320 // 设置屏幕宽度 #define DISP_HIGHT 240 // 设置屏幕高度 #define LV_MEM_SIZE (2048 * 1024U) // 分配2MB内存给LVGL #define LV_DEF_REFR_PERIOD 10 // 设置刷新周期为10ms #define LV_USE_OS LV_OS_PTHREAD // 使用Linux线程 #define LV_USE_LOG 1 // 启用日志 #define LV_USE_FLOAT 1 // 启用浮点支持 #define LV_USE_GIF 1 // 启用GIF支持 #define LV_GIF_CACHE_DECODE_DATA 1 // 启用GIF缓存 #define LV_USE_SYSMON 1 // 启用系统监控 #define LV_USE_LINUX_FBDEV 1 // 启用FrameBuffer支持 #define LV_LINUX_FBDEV_BUFFER_COUNT 2 // 启用双缓冲 #define LV_USE_EVDEV 1 // 启用输入设备支持这些配置为后续开发奠定了基础特别是双缓冲和输入设备支持对流畅的UI体验至关重要。3. 显示与输入驱动适配3.1 FrameBuffer驱动适配为了让LVGL能够在泰山派开发板上正常显示我们需要修改FrameBuffer驱动接口。主要修改位于lvgl/src/drivers/display/fb/lv_linux_fbdev.clv_display_t * lv_linux_fbdev_create(int32_t hor_res, int32_t ver_res) { static bool inited false; if(!inited) { lv_tick_set_cb(tick_get_cb); inited true; } lv_linux_fb_t * dsc lv_malloc_zeroed(sizeof(lv_linux_fb_t)); LV_ASSERT_MALLOC(dsc); if(dsc NULL) return NULL; lv_display_t * disp lv_display_create(hor_res, ver_res); if(disp NULL) { lv_free(dsc); return NULL; } dsc-fbfd -1; lv_display_set_driver_data(disp, dsc); lv_display_set_flush_cb(disp, flush_cb); return disp; }同时需要修改头文件中的函数声明lv_display_t * lv_linux_fbdev_create(int32_t hor_res, int32_t ver_res);在main.c中初始化显示设备lv_display_t * disp lv_linux_fbdev_create(DISP_WIDTH, DISP_HIGHT); lv_linux_fbdev_set_file(disp, /dev/fb0);3.2 触摸输入驱动适配泰山派开发板通常使用Linux输入子系统(evdev)来处理触摸输入。在main.c中添加以下代码char evdev[41] /dev/input/event1; lv_indev_t* cdev lv_evdev_create(LV_INDEV_TYPE_POINTER, evdev); lv_evdev_set_swap_axes(cdev, true); // 交换XY轴 lv_evdev_set_calibration(cdev, 0, 0, DISP_WIDTH, DISP_HIGHT); // 设置触摸范围这里有几个关键点需要注意触摸设备节点通常是/dev/input/eventX具体是哪个需要根据实际情况确定某些屏幕可能需要交换XY轴坐标校准参数需要根据实际触摸屏特性调整4. 开发工具链配置4.1 交叉编译环境泰山派开发板使用ARM架构处理器我们需要配置交叉编译工具链。假设SDK已经解压到~/share_file/tspi_linux/可以这样设置环境变量export CC~/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc然后创建build目录并编译mkdir build cd build cmake .. make -j8编译完成后可执行文件会生成在bin目录下。4.2 VSCode开发环境为了提高开发效率建议使用VSCode进行开发。首先安装以下插件Remote - SSH用于远程连接开发主机CMake Tools用于CMake项目管理配置交叉编译工具链{ name: GCC 6.3.1 arm-rockchip-tspi, compilers: { C: /home/chen/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc, CXX: /home/chen/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g } }配置完成后可以在VSCode中一键编译项目大大提高开发效率。4.3 Visual Studio模拟器为了加快UI开发速度我们可以使用Visual Studio模拟器进行前期开发下载安装Visual Studio打开lv_port_pc_visual_studio/LVGL.sln修改LvglWindowsSimulator.cpp中的屏幕尺寸lv_display_t* display lv_windows_create_display( LLVGL Windows Simulator Display 1, 350, // 宽度 200, // 高度 zoom_level, allow_dpi_override, simulator_mode);模拟器开发可以大大减少实际设备上的调试时间特别适合UI布局和动画效果的调试。5. Activity组件化框架设计5.1 设计思想借鉴安卓Activity的设计理念我实现了一个轻量级的UI框架主要特点包括页面组件化每个界面作为独立组件生命周期管理onCreate、onDestroy等回调三种压栈模式STANDARD、SINGLE_TOP、SINGLE_TASK消息总线支持跨页面通信动态启动页设置这种设计使得UI开发更加模块化便于维护和扩展。5.2 核心实现框架核心代码位于uikit目录主要包含ui.c实现Activity管理data_bus.c实现消息总线页面组件的基本结构如下#include application.h static lv_obj_t * container; static ui_data_t * ui; LV_IMG_DECLARE(img_start_lunch) static void timer_cb(lv_timer_t * timer) { ui_intent_t intent; intent.anim true; ui_fun_fast_create_intent(ui, PAGE_MONITOR_STYLE1, intent); ui_fun_start_activity(intent); ui_fun_finish(ui, false); } static void on_page_create(ui_data_t * ui_dat, void * params) { ui ui_dat; container lv_image_create(lv_screen_active()); lv_img_set_src(container, img_start_lunch); lv_timer_t * timer lv_timer_create(timer_cb, 3000, NULL); lv_timer_set_repeat_count(timer, 1); } static void on_page_destoy(void * params) {} static lv_obj_t * page_get_view() { return container; } ui_data_t page_lunch { .id PAGE_LUNCH, .launcher true, .launcher_mode SINGLE_TASK, .fun_get_view page_get_view, .fun_on_create on_page_create, .fun_on_destoy on_page_destoy };5.3 页面管理与跳转所有页面需要在application.h中注册#include application.h extern ui_data_t page_lunch; extern ui_data_t page_monitor; static ui_data_t* pages[] {page_lunch, page_monitor}; void app_lunch() { ui_init_and_start(pages, sizeof(pages)); }页面跳转通过intent实现ui_intent_t intent; intent.anim true; // 启用切换动画 ui_fun_fast_create_intent(ui, PAGE_MONITOR_STYLE1, intent); ui_fun_start_activity(intent); ui_fun_finish(ui, false); // 结束当前页面这种设计使得页面之间的跳转和通信变得非常清晰和可控。6. GIF动画集成6.1 准备工作首先确保lv_conf.h中启用了GIF支持#define LV_USE_GIF 1 #define LV_GIF_CACHE_DECODE_DATA 1使用LVGL官方提供的在线图片转换工具将GIF转换为C数组 https://lvgl.io/tools/imageconverter转换时注意选择正确的颜色格式CF_RAW无透明通道CF_RAW_ALPHA带透明通道6.2 GIF使用示例声明GIF资源LV_IMG_DECLARE(gif_radiantboy)创建并显示GIFlv_obj_t * gif_obj lv_gif_create(parent); lv_gif_set_src(gif_obj, gif_radiantboy); lv_obj_set_pos(gif_obj, x, y);控制GIF播放lv_gif_pause(gif_obj); // 暂停 lv_gif_resume(gif_obj); // 恢复在实际项目中GIF动画可以大大增强用户体验但需要注意控制GIF大小避免占用过多内存复杂动画可能会影响性能考虑提供暂停/播放控制接口7. 项目构建系统7.1 目录结构项目采用模块化目录结构├── app/ # 页面组件 ├── assets/ # 原始资源 ├── font/ # 字体文件 ├── image/ # 图片资源 ├── monitor/ # 系统监控实现 ├── store/ # 存储相关 └── uikit/ # UI框架7.2 CMake配置修改CMakeLists.txt包含所有模块include_directories( ${PROJECT_SOURCE_DIR}/app ${PROJECT_SOURCE_DIR}/monitor ${PROJECT_SOURCE_DIR}/uikit ${PROJECT_SOURCE_DIR}/store ) file(GLOB APP ${CMAKE_CURRENT_SOURCE_DIR}/app/*.c) file(GLOB MONITOR ${CMAKE_CURRENT_SOURCE_DIR}/monitor/*.c) file(GLOB UIKIT ${CMAKE_CURRENT_SOURCE_DIR}/uikit/*.c) file(GLOB STORE ${CMAKE_CURRENT_SOURCE_DIR}/store/*.c) file(GLOB FONT ${CMAKE_CURRENT_SOURCE_DIR}/font/*.c) file(GLOB IMG ${CMAKE_CURRENT_SOURCE_DIR}/image/*.c) add_executable(nas_monitor main.c ${STORE} ${UIKIT} ${MONITOR} ${FONT} ${IMG} ${APP}) target_link_libraries(nas_monitor lvgl lvgl::thorvg ${SDL2_LIBRARIES} m pthread)这种配置方式使得项目结构清晰便于维护和扩展。8. 启动参数解析8.1 参数设计程序支持以下启动参数./nas_monitor -fb 0 -ev 1 -disk /dev/sda1 -net eth0-fb指定FrameBuffer设备号-ev指定输入设备号-disk监控的磁盘设备-net监控的网络接口8.2 实现代码参数解析工具函数int extractData(int argc, char* argv[], char* buf, const char* key) { for (int i 1; i argc; i) { if (strncmp(argv[i], key, strlen(key)) 0) { if (i 1 argc) { strcpy(buf, argv[i 1]); return 0; } return -2; } } return -1; }在main函数中使用char flag_fb[2] 0; char flag_ev[2] 1; extractData(argc, argv, flag_fb, -fb); extractData(argc, argv, flag_ev, -evdev); extractData(argc, argv, monitor_dat.disk_name, -disk); extractData(argc, argv, monitor_dat.net_name, -net); if(extractData(argc, argv, NULL, -h) -2){ printf(\tNAS MONITOR Helper\n \ INPUT:-fb DESC: Display Output; Example: -fb 0\n \ INPUT:-evdev DESC: Touch the input subsystem used; Example:-evdev 1\n \ INPUT:-disk DESC: The hard drive to be monitored; Example: -disk /dev/sda1\n \ INPUT:-net DESC: The name of the NIC to which you want to monitor the network speed; Example: -net eth0\n); return 0; } char fb[41] /dev/fb; char evdev[41] /dev/input/event; strcat(fb, flag_fb); strcat(evdev, flag_ev);这种设计使得程序更加灵活可以适应不同的硬件配置。9. 部署与测试9.1 文件传输编译完成后使用scp将程序传输到开发板scp bin/nas_monitor user192.168.110.167:~/9.2 运行测试在开发板上运行程序./nas_monitor -fb 0 -ev 1 -disk /dev/sda1 -net eth09.3 性能优化建议在实际部署时可以考虑以下优化措施调整LVGL的内存配置优化刷新频率精简不必要的组件使用更高效的绘图方式合理使用双缓冲10. 项目总结与扩展通过这个项目我们实现了一个完整的嵌入式系统监控界面主要技术亮点包括LVGL在嵌入式Linux平台的完整适配创新的Activity组件化设计灵活的参数配置系统高效的开发调试流程这个项目还可以进一步扩展添加更多监控指标实现远程配置功能增加告警通知机制支持多语言优化性能表现在实际开发过程中我总结了以下几点经验模拟器开发可以大大提高效率组件化设计使项目更易维护合理的日志系统对调试很有帮助性能优化需要结合实际测试数据良好的文档习惯很重要
基于LVGL的嵌入式系统监控界面开发实践
1. 项目概述泰山派NAS-LVGL9监控器是一个基于LVGL图形库开发的嵌入式系统监控界面项目。作为一名长期从事嵌入式开发的工程师我最近在泰山派开发板上实现了一个完整的系统监控解决方案现在将详细的技术实现过程分享给大家。这个项目最大的特点是将安卓Activity的组件化思想引入到嵌入式GUI开发中配合LVGL9.1的强大功能实现了模块化、可扩展的监控界面。整个项目从环境搭建到最终实现涉及多个关键技术点包括LVGL在嵌入式Linux平台的移植FrameBuffer驱动适配触摸输入系统集成仿安卓Activity的UI框架设计系统资源监控实现开发调试技巧下面我将从环境搭建开始逐步讲解这个项目的完整实现过程。2. 开发环境搭建2.1 LVGL基础环境配置LVGLLight and Versatile Graphics Library是一个专为嵌入式系统设计的轻量级图形库支持多种显示设备和输入设备。在开始项目前我们需要搭建好开发环境。首先创建工作目录并获取LVGL源代码mkdir lvgl_blog_demo cd lvgl_blog_demo git clone https://github.com/lvgl/lvgl.git -b release/v9.1为了便于开发调试我们还需要获取Visual Studio模拟器项目git clone --recurse-submodules https://github.com/lvgl/lv_port_pc_visual_studio.git以及Linux平台适配代码git clone https://github.com/lvgl/lv_port_linux.git -b release/v9.02.2 配置文件调整将lv_port_linux目录下的关键文件复制到项目根目录cp lv_port_linux/{Makefile,main.c,CMakeLists.txt,.gitignore} .然后修改Makefile注释掉mouse_cursor_icon.c的引用# CSRCS $(LVGL_DIR)/mouse_cursor_icon.c同样修改CMakeLists.txt移除mouse_cursor_icon.c的编译add_executable(main main.c)2.3 屏幕参数配置复制lvgl目录下的lv_conf_template.h到项目根目录并重命名为lv_conf.h。然后进行以下关键配置#define DISP_WIDTH 320 // 设置屏幕宽度 #define DISP_HIGHT 240 // 设置屏幕高度 #define LV_MEM_SIZE (2048 * 1024U) // 分配2MB内存给LVGL #define LV_DEF_REFR_PERIOD 10 // 设置刷新周期为10ms #define LV_USE_OS LV_OS_PTHREAD // 使用Linux线程 #define LV_USE_LOG 1 // 启用日志 #define LV_USE_FLOAT 1 // 启用浮点支持 #define LV_USE_GIF 1 // 启用GIF支持 #define LV_GIF_CACHE_DECODE_DATA 1 // 启用GIF缓存 #define LV_USE_SYSMON 1 // 启用系统监控 #define LV_USE_LINUX_FBDEV 1 // 启用FrameBuffer支持 #define LV_LINUX_FBDEV_BUFFER_COUNT 2 // 启用双缓冲 #define LV_USE_EVDEV 1 // 启用输入设备支持这些配置为后续开发奠定了基础特别是双缓冲和输入设备支持对流畅的UI体验至关重要。3. 显示与输入驱动适配3.1 FrameBuffer驱动适配为了让LVGL能够在泰山派开发板上正常显示我们需要修改FrameBuffer驱动接口。主要修改位于lvgl/src/drivers/display/fb/lv_linux_fbdev.clv_display_t * lv_linux_fbdev_create(int32_t hor_res, int32_t ver_res) { static bool inited false; if(!inited) { lv_tick_set_cb(tick_get_cb); inited true; } lv_linux_fb_t * dsc lv_malloc_zeroed(sizeof(lv_linux_fb_t)); LV_ASSERT_MALLOC(dsc); if(dsc NULL) return NULL; lv_display_t * disp lv_display_create(hor_res, ver_res); if(disp NULL) { lv_free(dsc); return NULL; } dsc-fbfd -1; lv_display_set_driver_data(disp, dsc); lv_display_set_flush_cb(disp, flush_cb); return disp; }同时需要修改头文件中的函数声明lv_display_t * lv_linux_fbdev_create(int32_t hor_res, int32_t ver_res);在main.c中初始化显示设备lv_display_t * disp lv_linux_fbdev_create(DISP_WIDTH, DISP_HIGHT); lv_linux_fbdev_set_file(disp, /dev/fb0);3.2 触摸输入驱动适配泰山派开发板通常使用Linux输入子系统(evdev)来处理触摸输入。在main.c中添加以下代码char evdev[41] /dev/input/event1; lv_indev_t* cdev lv_evdev_create(LV_INDEV_TYPE_POINTER, evdev); lv_evdev_set_swap_axes(cdev, true); // 交换XY轴 lv_evdev_set_calibration(cdev, 0, 0, DISP_WIDTH, DISP_HIGHT); // 设置触摸范围这里有几个关键点需要注意触摸设备节点通常是/dev/input/eventX具体是哪个需要根据实际情况确定某些屏幕可能需要交换XY轴坐标校准参数需要根据实际触摸屏特性调整4. 开发工具链配置4.1 交叉编译环境泰山派开发板使用ARM架构处理器我们需要配置交叉编译工具链。假设SDK已经解压到~/share_file/tspi_linux/可以这样设置环境变量export CC~/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc然后创建build目录并编译mkdir build cd build cmake .. make -j8编译完成后可执行文件会生成在bin目录下。4.2 VSCode开发环境为了提高开发效率建议使用VSCode进行开发。首先安装以下插件Remote - SSH用于远程连接开发主机CMake Tools用于CMake项目管理配置交叉编译工具链{ name: GCC 6.3.1 arm-rockchip-tspi, compilers: { C: /home/chen/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc, CXX: /home/chen/share_file/tspi_linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g } }配置完成后可以在VSCode中一键编译项目大大提高开发效率。4.3 Visual Studio模拟器为了加快UI开发速度我们可以使用Visual Studio模拟器进行前期开发下载安装Visual Studio打开lv_port_pc_visual_studio/LVGL.sln修改LvglWindowsSimulator.cpp中的屏幕尺寸lv_display_t* display lv_windows_create_display( LLVGL Windows Simulator Display 1, 350, // 宽度 200, // 高度 zoom_level, allow_dpi_override, simulator_mode);模拟器开发可以大大减少实际设备上的调试时间特别适合UI布局和动画效果的调试。5. Activity组件化框架设计5.1 设计思想借鉴安卓Activity的设计理念我实现了一个轻量级的UI框架主要特点包括页面组件化每个界面作为独立组件生命周期管理onCreate、onDestroy等回调三种压栈模式STANDARD、SINGLE_TOP、SINGLE_TASK消息总线支持跨页面通信动态启动页设置这种设计使得UI开发更加模块化便于维护和扩展。5.2 核心实现框架核心代码位于uikit目录主要包含ui.c实现Activity管理data_bus.c实现消息总线页面组件的基本结构如下#include application.h static lv_obj_t * container; static ui_data_t * ui; LV_IMG_DECLARE(img_start_lunch) static void timer_cb(lv_timer_t * timer) { ui_intent_t intent; intent.anim true; ui_fun_fast_create_intent(ui, PAGE_MONITOR_STYLE1, intent); ui_fun_start_activity(intent); ui_fun_finish(ui, false); } static void on_page_create(ui_data_t * ui_dat, void * params) { ui ui_dat; container lv_image_create(lv_screen_active()); lv_img_set_src(container, img_start_lunch); lv_timer_t * timer lv_timer_create(timer_cb, 3000, NULL); lv_timer_set_repeat_count(timer, 1); } static void on_page_destoy(void * params) {} static lv_obj_t * page_get_view() { return container; } ui_data_t page_lunch { .id PAGE_LUNCH, .launcher true, .launcher_mode SINGLE_TASK, .fun_get_view page_get_view, .fun_on_create on_page_create, .fun_on_destoy on_page_destoy };5.3 页面管理与跳转所有页面需要在application.h中注册#include application.h extern ui_data_t page_lunch; extern ui_data_t page_monitor; static ui_data_t* pages[] {page_lunch, page_monitor}; void app_lunch() { ui_init_and_start(pages, sizeof(pages)); }页面跳转通过intent实现ui_intent_t intent; intent.anim true; // 启用切换动画 ui_fun_fast_create_intent(ui, PAGE_MONITOR_STYLE1, intent); ui_fun_start_activity(intent); ui_fun_finish(ui, false); // 结束当前页面这种设计使得页面之间的跳转和通信变得非常清晰和可控。6. GIF动画集成6.1 准备工作首先确保lv_conf.h中启用了GIF支持#define LV_USE_GIF 1 #define LV_GIF_CACHE_DECODE_DATA 1使用LVGL官方提供的在线图片转换工具将GIF转换为C数组 https://lvgl.io/tools/imageconverter转换时注意选择正确的颜色格式CF_RAW无透明通道CF_RAW_ALPHA带透明通道6.2 GIF使用示例声明GIF资源LV_IMG_DECLARE(gif_radiantboy)创建并显示GIFlv_obj_t * gif_obj lv_gif_create(parent); lv_gif_set_src(gif_obj, gif_radiantboy); lv_obj_set_pos(gif_obj, x, y);控制GIF播放lv_gif_pause(gif_obj); // 暂停 lv_gif_resume(gif_obj); // 恢复在实际项目中GIF动画可以大大增强用户体验但需要注意控制GIF大小避免占用过多内存复杂动画可能会影响性能考虑提供暂停/播放控制接口7. 项目构建系统7.1 目录结构项目采用模块化目录结构├── app/ # 页面组件 ├── assets/ # 原始资源 ├── font/ # 字体文件 ├── image/ # 图片资源 ├── monitor/ # 系统监控实现 ├── store/ # 存储相关 └── uikit/ # UI框架7.2 CMake配置修改CMakeLists.txt包含所有模块include_directories( ${PROJECT_SOURCE_DIR}/app ${PROJECT_SOURCE_DIR}/monitor ${PROJECT_SOURCE_DIR}/uikit ${PROJECT_SOURCE_DIR}/store ) file(GLOB APP ${CMAKE_CURRENT_SOURCE_DIR}/app/*.c) file(GLOB MONITOR ${CMAKE_CURRENT_SOURCE_DIR}/monitor/*.c) file(GLOB UIKIT ${CMAKE_CURRENT_SOURCE_DIR}/uikit/*.c) file(GLOB STORE ${CMAKE_CURRENT_SOURCE_DIR}/store/*.c) file(GLOB FONT ${CMAKE_CURRENT_SOURCE_DIR}/font/*.c) file(GLOB IMG ${CMAKE_CURRENT_SOURCE_DIR}/image/*.c) add_executable(nas_monitor main.c ${STORE} ${UIKIT} ${MONITOR} ${FONT} ${IMG} ${APP}) target_link_libraries(nas_monitor lvgl lvgl::thorvg ${SDL2_LIBRARIES} m pthread)这种配置方式使得项目结构清晰便于维护和扩展。8. 启动参数解析8.1 参数设计程序支持以下启动参数./nas_monitor -fb 0 -ev 1 -disk /dev/sda1 -net eth0-fb指定FrameBuffer设备号-ev指定输入设备号-disk监控的磁盘设备-net监控的网络接口8.2 实现代码参数解析工具函数int extractData(int argc, char* argv[], char* buf, const char* key) { for (int i 1; i argc; i) { if (strncmp(argv[i], key, strlen(key)) 0) { if (i 1 argc) { strcpy(buf, argv[i 1]); return 0; } return -2; } } return -1; }在main函数中使用char flag_fb[2] 0; char flag_ev[2] 1; extractData(argc, argv, flag_fb, -fb); extractData(argc, argv, flag_ev, -evdev); extractData(argc, argv, monitor_dat.disk_name, -disk); extractData(argc, argv, monitor_dat.net_name, -net); if(extractData(argc, argv, NULL, -h) -2){ printf(\tNAS MONITOR Helper\n \ INPUT:-fb DESC: Display Output; Example: -fb 0\n \ INPUT:-evdev DESC: Touch the input subsystem used; Example:-evdev 1\n \ INPUT:-disk DESC: The hard drive to be monitored; Example: -disk /dev/sda1\n \ INPUT:-net DESC: The name of the NIC to which you want to monitor the network speed; Example: -net eth0\n); return 0; } char fb[41] /dev/fb; char evdev[41] /dev/input/event; strcat(fb, flag_fb); strcat(evdev, flag_ev);这种设计使得程序更加灵活可以适应不同的硬件配置。9. 部署与测试9.1 文件传输编译完成后使用scp将程序传输到开发板scp bin/nas_monitor user192.168.110.167:~/9.2 运行测试在开发板上运行程序./nas_monitor -fb 0 -ev 1 -disk /dev/sda1 -net eth09.3 性能优化建议在实际部署时可以考虑以下优化措施调整LVGL的内存配置优化刷新频率精简不必要的组件使用更高效的绘图方式合理使用双缓冲10. 项目总结与扩展通过这个项目我们实现了一个完整的嵌入式系统监控界面主要技术亮点包括LVGL在嵌入式Linux平台的完整适配创新的Activity组件化设计灵活的参数配置系统高效的开发调试流程这个项目还可以进一步扩展添加更多监控指标实现远程配置功能增加告警通知机制支持多语言优化性能表现在实际开发过程中我总结了以下几点经验模拟器开发可以大大提高效率组件化设计使项目更易维护合理的日志系统对调试很有帮助性能优化需要结合实际测试数据良好的文档习惯很重要