只要在回调里面给到按下,弹起这个。

Linux

在linux下,一般按键输入被映射成linux内置的按键编码。比如说产品只有4个物理按钮,那么我们在写linux驱动的时候会把这这4个按钮映射为:上,下,ok,back。

所以,lvgl在linux下直接读取系统输入就好了。

lv_indev_drv_t indev_drv; //新增一个输入设备对象
lv_indev_drv_init(&indev_drv);//初始化这个设备对象,主要是分配内存等操作
indev_drv.type = LV_INDEV_TYPE_KEYPAD;//设置这个输入设备接受的是键盘类型
indev_drv.read_cb = evdev_read;// 回调,比较重要,lvgl会每隔一段时间去回调这个函数,判断是否有输入事件
lv_indev_drv_register(&indev_drv);//注册这个输入设备
static int evdev_fd = -1; //打开的linux系统中的某个输入事件,对应文件描述符
static uint32_t last_key = 0;//当前输入键对应在linux中的值
static lv_indev_state_t last_state = LV_INDEV_STATE_RELEASED;//按下类型
void evdev_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
    (void)drv;

    data->key = last_key;//赋值为上一次的值
    data->state = last_state;//赋值为上一次的值,为了lvgl如果这次的值和上一次的值一样,那就判断没有新事件
    data->continue_reading = false;

    if (evdev_fd < 0) return;
    
    struct input_event ev;
    if (read(evdev_fd, &ev, sizeof(ev)) != sizeof(ev)) return;

    uint32_t k = ev.code;
   	//按下类型,长按2,短按1,松开0
    printf("key=%d, code=%d, val=%d\n", k, ev.code, ev.value);
    if (!k) return;

    /* 只处理按下(1)和弹起(0),忽略按住不放的重复事件(2) */
    if (ev.value != 0 && ev.value != 1) return;

    /* --- 驱动只需要给到lvgl按下松开就好。不需要提供长按 --- */
    last_key = k;
    last_state = ev.value == 1 ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; //按下或者松开

	//将这一次的按键值重新给到lvgl
    data->key = last_key;
    data->state = last_state;
    data->continue_reading = true;
}
  • continue_reading 作用:按照lvgl原来的方式是每次lv_timer_handler()之后才会重新调用我们提供的回调,现在这种情况,我们设置了continue_reading=true,立马又再次调用我们提供的回调,达到快速处理事件的效果

MCU

在mcu下由于没有像linux下的按键映射。