GD32F450IGT6
V7.7
异步操作lvgl控件时,不能出现内存溢出、空指针问题
我尝试在lvglhandle函数内部 和 其他线程异步调用的接口处,增加条件限制,保证在使用 lv_obj_invalidate(lv_scr_act())时,lvhandle处于停止运行状态。
我试过以下几种方法
1、将lv_obj_invalidate(lv_scr_act())屏蔽掉,这样不会发生异常问题,但是会存在屏幕残留。
2、在异步调用接口处,获取lv_task_handle 的运行状态,先lv_task_enable(false), 当lv_task停止运行时,调用lv_obj_invalidate(lv_scr_act())标记屏幕区域无效,然后 lv_task_enable(true)。在连续测试500次后,lv_task_handle 在刷新时,出现了访问错误地址。
3、尝试使用事件注册方式,将lv_obj_invalidate(lv_scr_act())进行注册,进行延时标记,测试后,发现仍会访问错误地址。
/*
void CReagentSetupWnd::DefWindowProc(lv_obj_t* obj,lv_event_t e)
{
if(obj == m_setupTab)
{
switch(e)
{
case G_EVENT_WAIT_START:
{
if(m_oReagentModel.m_taskType == 1)
{
m_pWaitPromptDlg->m_strWaitText = "Delete operation in progress,\n please do not shutdown...";
}
m_pWaitPromptDlg->OnInitDialog();
}break;
case G_EVENT_WAIT_END:
{
if(m_oReagentModel.m_taskType == 0)
{
DelayInit();
m_pWaitPromptDlg->EndWait();
}break;
}
}
}
void CReagentSetupModel::ThreadFunc()
{
switch(m_taskType)
{
case 0:
{
if(m_notifyObj != NULL)
{
lv_event_send(m_notifyObj, G_EVENT_WAIT_END, NULL);
}
}
break;
case 1:
{
if(m_notifyObj != NULL)
{
lv_event_send(m_notifyObj, G_EVENT_WAIT_START, NULL);
}
m_pData->DelTest(m_curTest);
if(m_notifyObj != NULL)
{
lv_event_send(m_notifyObj, G_EVENT_WAIT_END, NULL);
}
}
break;
}
}
void CPopUpBaseDlg::OnClose(int8_t value)
{
m_retValue = value;
ReleaseOBJPtr(m_curDlgObj);
lv_event_send(m_notifyObj, m_notifyEvent, NULL); //阻塞式调用
m_retValue = -1;
m_notifyObj = NULL;
}
void CSearchWaitDlg::OnInitDialog(lv_obj_t* obj,lv_event_t e)
{
CPopUpBaseDlg::OnInitDialog(obj,e);
m_waitConntent = lv_obj_create(GetPopUpBaseObj(),NULL);
lv_obj_set_size(m_waitConntent,LV_HOR_RES / 2,150);
lv_obj_align(m_waitConntent,NULL,LV_ALIGN_CENTER,0,0);
string t_strTitle = "Attention";
AddTitle(m_waitConntent,t_strTitle);
lv_obj_t * arc = lv_arc_create(m_waitConntent, NULL);
lv_arc_set_bg_angles(arc, 0, 360);
lv_arc_set_value(arc,80);
lv_obj_set_size(arc, 50, 50);
lv_obj_align(arc,NULL,LV_ALIGN_IN_TOP_MID,0,30);
m_tipsTextObj = addLabel(m_waitConntent,NULL,m_strWaitText.c_str());
lv_obj_align(m_tipsTextObj,arc,LV_ALIGN_OUT_BOTTOM_MID,0,10);
m_stopWaitBtn = addBtn(m_waitConntent,NULL,"Stop");
lv_obj_set_size(m_stopWaitBtn,70,35);
SetDefEventCB(m_stopWaitBtn);
lv_obj_align(m_stopWaitBtn,NULL,LV_ALIGN_IN_BOTTOM_MID,0,-5);
lv_anim_t a;
lv_anim_init(&a);
a.repeat_cnt = LV_ANIM_REPEAT_INFINITE;
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_arc_set_rotation);
lv_anim_set_values(&a, 0, 360);
lv_anim_set_time(&a, 1000);
lv_anim_set_var(&a, arc);
//lv_anim_set_ready_cb(&a, end_cb);
lv_anim_start(&a);
}
void CSearchWaitDlg::DefWindowProc(lv_obj_t* obj,lv_event_t e)
{
if(obj == m_stopWaitBtn && e == LV_EVENT_CLICKED)
{
m_pModel->m_stopQuery = 1;
}
}
extern OS_EVENT *g_pLvgl_WaitPrompt_Event;
lv_mem_monitor_t g_lv_mem_monitor;
void CSearchWaitDlg::EndWait()
{
uint8_t err;
OnClose(0);
printf(“CSearchWaitDlg OnClose \r\n”);
lv_task_enable(false);
while(1)
{
lv_mem_monitor(&g_lv_mem_monitor);
if(lv_task_get_run_flag() == false)
{
lv_obj_invalidate(lv_scr_act());
lv_task_enable(true);
printf("CSearchWaitDlg lv_task_get_run_flag == flase \r\n");
break;
}
}
}
*/