LVGL输入设备管理

LVGL版本:8.1

原理框图

       在LVGL中,官方定义了四种输入设备(除了未定类型):

//lv_hal_invdv.h
typedef enum {
    LV_INDEV_TYPE_NONE,    /* 未定类型 */
    LV_INDEV_TYPE_POINTER, /* 触摸屏、鼠标 */
    LV_INDEV_TYPE_KEYPAD,  /* 键盘 */
    LV_INDEV_TYPE_BUTTON,  /* 硬件按键,和屏幕上的某个部件或点联动 */
    LV_INDEV_TYPE_ENCODER, /* 三个键值的解码器,通常为“左”、“右”和“按下” */
} lv_indev_type_t;

       这些输入设备都是LVGL统一管理的,其代码结构都是类似的,可以用以下原理图来表示:

       输入设备管理中,最核心的就是LVGL定时查询设备状态并获取数据,在图上为红色字体的lv_indev_reader,该模块承上启下,收集设备的数据并向上传递。原理图层级从上到下分别是:

  • 用户层(User):把这层定义为用户注册设备驱动以及用户操作设备和显示之间的交互行为,其中特定输入设备仅归属于一个显示器,而显示器不绑定任何输入设备。
  • 核心层(Core):reader定时(timing)采集输入设备的状态和数据,并整理成LVGL所需要的数据逻辑,再以事件形式分发到相关对象,如定义了光标,还需要在显示器上绘制光标图案。
  • 事件驱动层(Event):连接LVGL核心和操作系统的部分,通过设备驱动提供的接口读取特定格式的数据,并初步分类为有意义的输入设备状态和数据,如鼠标、键盘等类型的数据。
  • 设备驱动层(Device):通常不属于LVGL的部分,和硬件的设备驱动模块相关联,如Linux系统下使用设备驱动和输入设备之间传递数据。

源码逻辑

       LVGL查询输入设备的方式是轮询的,周期默认LV_INDEV_DEF_READ_PERIOD设置为30ms,即33Hz刷新率。在用户使用驱动注册新的输入设备时,就为新设备创建了定时器任务lv_indev_read_timer_cb()

//lv_hal_indev.c
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
{

    if(driver->disp == NULL) driver->disp = lv_disp_get_default();  //设备和显示器绑定

    if(driver->disp == NULL) {
        LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
                    "a display");
        return NULL;
    }

    lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));  //取下一个设备指针用于注册新设备
    if(!indev) {
        LV_ASSERT_MALLOC(indev);
        return NULL;
    }

    lv_memset_00(indev, sizeof(lv_indev_t));
    indev->driver = driver;  //为新设备"安装"驱动

    indev->proc.reset_query  = 1;
    indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);  //为新设备创建定时器任务

    return indev;
}

       该定时器任务就是上面原理图中的lv_indev_rader,其作用就是读取输入设备的数据,并组织成LVGL所需要的数据逻辑进行处理,起到承上启下的作用。

//lv_indev.c
void lv_indev_read_timer_cb(lv_timer_t * timer)
{
    INDEV_TRACE("begin");

    lv_indev_data_t data;

    indev_act = timer->user_data;  //这里的user_data就是输入设备

    if(indev_act->driver->disp == NULL) return; /* 设备没有绑定到任何显示器,就没有意义 */

    indev_proc_reset_query_handler(indev_act);    /* 如果有reset请求,优先处理并复位 */

    if(indev_act->proc.disabled) return;
    bool continue_reading;
    do {
        _lv_indev_read(indev_act, &data);  //从设备中读取数据
        continue_reading = data.continue_reading;

        indev_proc_reset_query_handler(indev_act);  /* 在读取函数中,有可能设置了复位,在这里还要
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值