lvgl脏数据报错问题

Wi-Fi 设备、蜂窝设备、WuKongAI、开发板、TuyaOS 移植等


Post Reply
nuker_l
Posts: 5

当我正在动画中,或者其他可能是lvgl后台数据更新中,或是其他事物执行中,再次切换动画。例如执行以下代码,会引起脏数据报错。
报错信息如下:

Code: Select all

[aic_cpu1_callback][139]---AIC_LCD_BLACKLIGHT_LEFT AIC_LCD_BLACKLIGHT_LEFT
[10-21 10:41:06 ty W][75b4][drv_encoder.c:110] ------encode_angle :143
[10-21 10:41:06 ty I][75b4][tuya_ai_entry.c:1000] [MyApp] Counter-clockwise rotation - Angle: 143
[aic_frame_left][413]
[Error] (2027.276, +44)  _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.278, +2)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.278, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.278, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.278, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +2)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[Error] (2027.280, +0)   _lv_inv_area: detected modifying dirty areas in render         (in lv_refr.c line #212)
[aic_cpu1_callback][139]---AIC_LCD_BLACKLIGHT_LEFT AIC_LCD_BLACKLIGHT_LEFT

lvgl操作代码如下:

Code: Select all

// 闹钟控制函数
void alarm_move_focus(lv_ui_t *ui, int direction) {
    // 移除当前焦点样式
    lv_obj_remove_style(ui->s30_clock_alrarm[ui->s30_current_focus_index], &ui->style_s30_clock_list_1_extra_btns_selected, 0);
    
// 更新焦点索引 ui->s30_current_focus_index += direction; if(ui->s30_current_focus_index < 0) ui->s30_current_focus_index = 7; if(ui->s30_current_focus_index > 7) ui->s30_current_focus_index = 0; // 应用新焦点样式 lv_obj_add_style(ui->s30_clock_alrarm[ui->s30_current_focus_index], &ui->style_s30_clock_list_1_extra_btns_selected, 0); // 确保焦点项在可视区域内 lv_obj_scroll_to_view(ui->s30_clock_alrarm[ui->s30_current_focus_index], LV_ANIM_ON); }

任何动画性质的lvgl切换都会报这个错误,比如如下代码频繁切换也会

Code: Select all

void slide_image_right(lv_ui_t *ui)
{
    // 如果正在切换,标记为中断
    if (ui->s2_main_select_is_switching) {
        ui->s2_main_select_anim_interrupted = true;
        lv_anim_del(ui->s2_main_select_img_front, NULL);
        lv_anim_del(ui->s2_main_select_img_back, NULL);
        
// 立即完成清理工作 lv_obj_t *temp = ui->s2_main_select_img_front; ui->s2_main_select_img_front = ui->s2_main_select_img_back; ui->s2_main_select_img_back = temp; lv_obj_set_pos(ui->s2_main_select_img_back, 180, 0); ui->s2_main_select_is_switching = false; } ui->s2_main_select_is_switching = true; ui->s2_main_select_anim_interrupted = false; int new_index = (ui->s2_main_select_current_img_index +1) % image_count; bk_printf("-------Left shift-----new_index=%d\r\n",new_index); // 设置新图片到背景图片 lv_img_set_src(ui->s2_main_select_img_back, image_list[new_index]); // 设置初始位置 lv_obj_set_pos(ui->s2_main_select_img_back, 180, 0); lv_obj_set_pos(ui->s2_main_select_img_front, 0, 0); // 动画:前景图片向左移出 lv_anim_t a_front; lv_anim_init(&a_front); lv_anim_set_var(&a_front, ui->s2_main_select_img_front); lv_anim_set_values(&a_front, 0, -180); lv_anim_set_time(&a_front, 500); lv_anim_set_exec_cb(&a_front, (lv_anim_exec_xcb_t)slide_anim_cb); lv_anim_set_path_cb(&a_front, lv_anim_path_ease_out); lv_anim_start(&a_front); // 动画:背景图片从右向左移入 lv_anim_t a_back; lv_anim_init(&a_back); lv_anim_set_var(&a_back, ui->s2_main_select_img_back); lv_anim_set_values(&a_back, 180, 0); lv_anim_set_time(&a_back, 500); lv_anim_set_exec_cb(&a_back, (lv_anim_exec_xcb_t)slide_anim_cb); lv_anim_set_path_cb(&a_back, lv_anim_path_ease_out); lv_anim_set_ready_cb(&a_back, slide_anim_ready_cb); lv_anim_set_user_data(&a_back, ui); lv_anim_start(&a_back); ui->s2_main_select_current_img_index = new_index; update_position_indicators(ui); }

有时,首次第一个画面,进入第二个画面,也会失败,他们之间没有动画,只是单次的报错。
[Error] (2027.276, +44) _lv_inv_area: detected modifying dirty areas in render (in lv_refr.c line #212

有时甚至会引起死机。
请问,这个问题提如何避免。如何优化。

liujt@tuya.com
Posts: 66

Re: lvgl脏数据报错问题

你好,请问有在事件回调函数中直接修改UI及相关控件属性吗?尽量避免这种操作。可以在事件回调中调用lv_async_call中去做控件更改的异步处理。

nuker_l
Posts: 5

Re: lvgl脏数据报错问题

liujt@tuya.com 2025年 Oct 21日 11:22

你好,请问有在事件回调函数中直接修改UI及相关控件属性吗?尽量避免这种操作。可以在事件回调中调用lv_async_call中去做控件更改的异步处理。

是的,我的确是在按键回调中,执行了修改UI操作,中间经过了消息队列转发了到了lvgl的核心,操作才最终执行的。
我尝试一下看看。

nuker_l
Posts: 5

Re: lvgl脏数据报错问题

liujt@tuya.com 2025年 Oct 21日 11:22

你好,请问有在事件回调函数中直接修改UI及相关控件属性吗?尽量避免这种操作。可以在事件回调中调用lv_async_call中去做控件更改的异步处理。

实测有效。
感谢,lv_async_call可以实现我需要的功能。解决了这个报错问题。

Post Reply