Edit online

使用指南

18 Feb 2024
Read time: 3 minute(s)
代码目录:
source/artinchip/lvgl-ui
├── lvgl           // lvgl 库
├── lv_drivers     // lvgl 平台适配
├── base_ui        // base_ui 测试用例
├── lv_conf.h      // lvgl 配置文件
└── main.c         // lvgl 应用入口

key_process

LVGL 框架的运行都是基于 LVGL 中定义的 Timer 定时器,系统需要给 LVGL 一个“心跳”, LVGL 才能正常的运转起来。LVGL 整体流程的两个关键函数:
  • lv_tick_get(), 获取以 ms 为单位的 tick 时间

    文件 c 中的 lv_tick_get 的实现代码如下:
    uint32_t lv_tick_get(void)
    {
    #if LV_TICK_CUSTOM == 0
    
        /*If `lv_tick_inc` is called from an interrupt while `sys_time` is read
        *the result might be corrupted.
        *This loop detects if `lv_tick_inc` was called while reading `sys_time`.
        *If `tick_irq_flag` was cleared in `lv_tick_inc` try to read again
        *until `tick_irq_flag` remains `1`.*/
        uint32_t result;
        do {
            tick_irq_flag = 1;
            result        = sys_time;
        } while(!tick_irq_flag); /*Continue until see a non interrupted cycle*/
    
        return result;
    #else
        return LV_TICK_CUSTOM_SYS_TIME_EXPR;
    #endif
    }
  • lv_timer_handler(),在 while 循环中的基于定时器的任务处理,函数 handler 会调用 lv_timer_handler, lv_tick_get 决定了 handler 基于定时器的任务处理的时间的准确性。

    头文件 h 中定义了上述函数中的 LV_TICK_CUSTOM_SYS_TIME_EXPR
    #define LV_TICK_CUSTOM 1
    #if LV_TICK_CUSTOM
        #define LV_TICK_CUSTOM_INCLUDE <aic_ui.h>
        #define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get()) /*system time in ms*/
    #endif   /*LV_TICK_CUSTOM*/
LVGL 应用主函数代码如下所示:
#define IMG_CACHE_NUM 10

#if LV_USE_LOG
static void lv_user_log(const char *buf)
{
    printf("%s\n", buf);
}
#endif /* LV_USE_LOG */

int main(void)
{
#if LV_USE_LOG
    lv_log_register_print_cb(lv_user_log);
#endif /* LV_USE_LOG */

    /*LittlevGL init*/
    lv_init();

#if LV_IMG_CACHE_DEF_SIZE == 1
    lv_img_cache_set_size(IMG_CACHE_NUM);
#endif

    aic_dec_create();

    lv_port_disp_init();
    lv_port_indev_init();

    /*Create a Demo*/
#if LV_USE_DEMO_MUSIC == 1
    void lv_demo_music(void);
    lv_demo_music();
#else
    void base_ui_init();
    base_ui_init();
#endif

    /*Handle LitlevGL tasks (tickless mode)*/
    while (1) {
        lv_timer_handler();
        usleep(1000);
    }

    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if (start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}
  • 其中在函数 lv_port_disp_init()中实现显示接口的对接以及硬件 2D 加速的对接

  • 在函数 lv_port_indev_init()中实现触摸屏的对接

  • 函数 aic_dec_create()注册硬件解码器

  • 用户只需替换 base_ui_init()的实现来对接自己的应用