使用异步调用delete 屏幕对象 并且标记屏幕对象无效时 发生内存溢出

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;
    }         
}   

}

*/