How to switch screens and clear all old screen resources

Hi,

I am trying to switch two screens or two lvgl examples, but the screen show nothing.

I would like to delete and clean all resources allocated for the old screen when switching between then.

The examples running outside the task work great.

What i am doing wrong ?

static lv_obj_t* scr1;
static lv_obj_t* scr2;
    
void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     
        
    while(1)
    {     
        scr1 = lv_obj_create(NULL);        
        if( scr2 != NULL )
            lv_obj_del(scr2);
            
        lv_example_img_3();      
             
        vTaskDelay( xDelay );  
             
        scr2 = lv_obj_create(NULL);
        if( scr1 != NULL )
            lv_obj_del(scr1);
             
        lv_example_meter_2();
            
        vTaskDelay( xDelay );               
    }    
}


int main( void )
{   
    SYS_Initialize( NULL );  // Initialize system modules    
    
    my_modules_Initialize();

///////////////////////////////////////////////////////////// 
         
//    lv_example_get_started_1();   
    
//    lv_example_calendar_1();
        
//    lv_example_img_3();
    
//    lv_example_meter_2();
    
        
    TickType_t tempo = 5000; //250       
                
    xTaskCreate(    task,
                    "task",
                    4096,  //512,  // words(4 bytes). 512 words * 4 = 2048 bytes.
                    &tempo,  
                    1,
                    (TaskHandle_t*) NULL       
                );
        
       
    xTaskCreate(    lvgl_task_handler, 
                    "littleVgl", 
                    4096,  //512,  
                    (void*) NULL,
                    2,    
                    (TaskHandle_t*) NULL                                              
                );
    
    
    vTaskStartScheduler();    
}   

lvgl version: 8.0.0

Thank’s.

I increased the memory available for freertos in “configTOTAL_HEAP_SIZE” in file “FreeRTOSConfig.h”, and now the program is working, but the examples resources are not released and the examples are recreated again and again until the memory runs out.

Hi,

This way it is partially working, but after some little time the screens dont switch more.
I just don’t know if it’s having a memory leak.
FreeRtos keeps working, ie, not a “vApplicationMallocFailedHook”.

static lv_obj_t* scr1;
static lv_obj_t* scr2;
static lv_obj_t* prev_scr;    
static bool a = 0;
static lv_style_t style_screen1;
static lv_style_t style_screen2;


void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     
        
    while(1)
    {       
        prev_scr = lv_scr_act(); /* save previously active screen */
        scr1 = lv_obj_create(NULL);
                
        lv_style_init(&style_screen1);
        lv_style_set_bg_color(&style_screen1, lv_color_black());
        lv_obj_add_style(scr1, &style_screen1, LV_PART_MAIN );  //turn the screen black
        
        lv_obj_t* sw = lv_switch_create(scr1);
        lv_obj_set_size(sw, 200, 100);
        lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);
                        
        a = !a;
        if( a )
            lv_obj_add_state(sw, LV_STATE_CHECKED);
        else
            lv_obj_add_state(sw, LV_STATE_DEFAULT);
                
        lv_scr_load(scr1);
        if( prev_scr != NULL )
            lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
                       
        vTaskDelay( xDelay );  
        
                
        prev_scr = lv_scr_act(); /* save previously active screen */
        scr2 = lv_obj_create(NULL);
                
        lv_style_init(&style_screen2);
        lv_style_set_bg_color(&style_screen2, lv_color_white());        
        lv_obj_add_style(scr2, &style_screen2, LV_PART_MAIN );  //turn the screen black
                            
        lv_obj_t* btn1 = lv_btn_create(scr2);
        lv_obj_set_size(btn1, 200, 100);
        lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
        
        lv_obj_t* label = lv_label_create(btn1);
        lv_label_set_text(label, "Button");        
        lv_obj_center(label);
                       
        if( a )
            lv_obj_add_state(btn1, LV_STATE_PRESSED);
        else
            lv_obj_add_state(btn1, LV_STATE_DEFAULT);
     
        lv_scr_load(scr2);
        if( prev_scr != NULL )
            lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
             
        vTaskDelay( xDelay );               
    }    
}



int main( void )
{   
    SYS_Initialize( NULL );  // Initialize system modules    
    
    my_modules_Initialize();

///////////////////////////////////////////////////////////// 
     
    TickType_t tempo = 5000;      
                
    xTaskCreate(    task,
                    "task",
                    4096,    // words(4 bytes). 4096 words * 4 = 16384 bytes.
                    &tempo,  
                    1,
                    (TaskHandle_t*) NULL       
                );
        
       
    xTaskCreate(    lvgl_task_handler, 
                    "littleVgl", 
                    4096,  
                    (void*) NULL,
                    2,    
                    (TaskHandle_t*) NULL                                              
                );
    
    
    vTaskStartScheduler();    
}   

Hi,

Some suggestion or link is appreciated.

Thank’s.

Hi,

Now it didn’t crash anymore, i don’t know why.
I just added some labels on the screen.

static lv_obj_t* scr1;
static lv_obj_t* scr2;
static lv_obj_t* prev_scr;    
static bool a = 0;
static lv_style_t style_screen1;
static lv_style_t style_screen2;

static uint32_t counter = 0;


void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     
        
    while(1)
    {       
        prev_scr = lv_scr_act(); /* save previously active screen */
        scr1 = lv_obj_create(NULL);
        
        
        lv_obj_t* label_scr1 = lv_label_create(scr1);     
        lv_obj_set_style_text_align(label_scr1, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align(label_scr1, LV_ALIGN_CENTER, 0, -100);        
        lv_label_set_text_fmt(label_scr1, "SCR1: %p", scr1);
                
        lv_obj_t* label_scr1a = lv_label_create(scr1);
        lv_obj_set_style_text_align(label_scr1a, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align(label_scr1a, LV_ALIGN_CENTER, 0, -80);        
        lv_label_set_text_fmt(label_scr1a, "&SCR1: %p", &scr1);
        
                                
        lv_style_init(&style_screen1);
        lv_style_set_bg_color(&style_screen1, lv_color_white());
        lv_obj_add_style(scr1, &style_screen1, LV_PART_MAIN );  //turn the screen black
        
        lv_obj_t* sw = lv_switch_create(scr1);
        lv_obj_set_size(sw, 200, 100);
        lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);
        
        
        lv_scr_load(scr1);
                        
        a = !a;
        if( a )
        {
            lv_obj_add_state(sw, LV_STATE_CHECKED);
            vTaskDelay( 2000 );
            lv_obj_clear_state(sw, LV_STATE_CHECKED);
        }
        else
        {
            lv_obj_clear_state(sw, LV_STATE_CHECKED);
            vTaskDelay( 2000 );
            lv_obj_add_state(sw, LV_STATE_CHECKED);        
        }
        
        //lv_scr_load(scr1);
        if( prev_scr != NULL )
            lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
                       
        vTaskDelay( xDelay );  
        
        
        
                
        prev_scr = lv_scr_act(); /* save previously active screen */
        scr2 = lv_obj_create(NULL);
        
        
        lv_obj_t* label_scr2 = lv_label_create(scr2);        
        lv_obj_set_style_text_align(label_scr2, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align(label_scr2, LV_ALIGN_CENTER, 0, -100);        
        lv_label_set_text_fmt(label_scr2, "SCR2: %p", scr2);
        
        
        lv_obj_t* label_scr2a = lv_label_create(scr2);             
        lv_obj_set_style_text_align(label_scr2a, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align(label_scr2a, LV_ALIGN_CENTER, 0, -80);        
        lv_label_set_text_fmt(label_scr2a, "&SCR2: %p", &scr2);
        
        
        counter++;
        lv_obj_t* label_counter = lv_label_create(scr2);             
        lv_obj_set_style_text_align(label_counter, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_align(label_counter, LV_ALIGN_CENTER, 0, 100);        
        lv_label_set_text_fmt(label_counter, "Counter: %u", counter);
        
                
        lv_style_init(&style_screen2);
        lv_style_set_bg_color(&style_screen2, lv_color_white());        
        lv_obj_add_style(scr2, &style_screen2, LV_PART_MAIN );  //turn the screen black
                            
        lv_obj_t* btn1 = lv_btn_create(scr2);
        lv_obj_set_size(btn1, 200, 100);
        lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
        
        lv_obj_t* label = lv_label_create(btn1);
        lv_label_set_text(label, "Button");        
        lv_obj_center(label);
                       
        
        lv_scr_load(scr2);        
        
        if( a )
        {
            lv_obj_add_state(btn1, LV_STATE_PRESSED);
            vTaskDelay( 2000 );
            lv_obj_clear_state(btn1, LV_STATE_PRESSED);           
        }
        else
        {
            lv_obj_clear_state(btn1, LV_STATE_PRESSED);
            vTaskDelay( 2000 );
            lv_obj_add_state(btn1, LV_STATE_PRESSED);
        }
            
        //lv_scr_load(scr2);
        if( prev_scr != NULL )
            lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
             
        vTaskDelay( xDelay );               
    }    
}

btn1 change state manually here(work):

if( a )
{
    lv_obj_add_state(btn1, LV_STATE_PRESSED);
    vTaskDelay( 2000 );
    lv_obj_clear_state(btn1, LV_STATE_PRESSED);           
}
else
{
    lv_obj_clear_state(btn1, LV_STATE_PRESSED);
    vTaskDelay( 2000 );
    lv_obj_add_state(btn1, LV_STATE_PRESSED);
}

But sw dont change state manually here(dont work):

When the screen load, the switch shows on or off, it depends on the state of boolean variable a, but while it is on the screen it does not change the state on to off or off to on, after 2 seconds.

if( a )
{
    lv_obj_add_state(sw, LV_STATE_CHECKED);
    vTaskDelay( 2000 );
    lv_obj_clear_state(sw, LV_STATE_CHECKED);
}
else
{
    lv_obj_clear_state(sw, LV_STATE_CHECKED);
    vTaskDelay( 2000 );
    lv_obj_add_state(sw, LV_STATE_CHECKED);        
}

It looks like you are trying to use LVGL APIs from a separate thread than the one calling lv_task_handler, so you need to use a mutex.

Thank’s @embeddedt, but it still didn’t work. The switch widget “sw” is not changing state when the screen is in steady state, only when the screen is loaded changes the switch state.
Button widget btn1 is working ok.

I’m using lvgl version 8.0.0.

CURRENT VERSION OF LVGL
#define LVGL_VERSION_MAJOR 8
#define LVGL_VERSION_MINOR 0
#define LVGL_VERSION_PATCH 0
#define LVGL_VERSION_INFO “dev”

#define semaphore_block_time 20  // set max block time to get "lvgl_mutex", in ms.

static SemaphoreHandle_t lvgl_mutex = NULL;

static lv_obj_t* scr1;
static lv_obj_t* scr2;
static lv_obj_t* prev_scr;    
static bool a = 0;
static lv_style_t style_screen1;
static lv_style_t style_screen2;
static lv_obj_t* sw;
static lv_obj_t* btn1;

static uint32_t counter = 0;


void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     

    
    while(1)
    {       
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {        
            prev_scr = lv_scr_act(); /* save previously active screen */       
            scr1 = lv_obj_create(NULL);

            lv_style_init(&style_screen1);
            lv_style_set_bg_color(&style_screen1, lv_color_white());
            lv_obj_add_style(scr1, &style_screen1, LV_PART_MAIN );  //turn the screen white

            lv_obj_t* label_scr1 = lv_label_create(scr1);     
            lv_obj_set_style_text_align(label_scr1, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr1, "SCR1: %p", scr1);

            lv_obj_t* label_scr1a = lv_label_create(scr1);
            lv_obj_set_style_text_align(label_scr1a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr1a, "&SCR1: %p", &scr1);

            sw = lv_switch_create(scr1);
            lv_obj_set_size(sw, 200, 100);
            lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);

            lv_scr_load(scr1);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */

            a = !a;
            if( a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);           
            else
                lv_obj_clear_state(sw, LV_STATE_CHECKED);        
                
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
                                       
               
        vTaskDelay( xDelay );  
             
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);              
            else        
                lv_obj_clear_state(sw, LV_STATE_CHECKED); 

            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }   
        

        vTaskDelay( xDelay ); 
        
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            prev_scr = lv_scr_act();  // save previously active screen 
            scr2 = lv_obj_create(NULL);
                
            lv_style_init(&style_screen2);
            lv_style_set_bg_color(&style_screen2, lv_color_white());        
            lv_obj_add_style(scr2, &style_screen2, LV_PART_MAIN );  //turn the screen black
            
            lv_obj_t* label_scr2 = lv_label_create(scr2);        
            lv_obj_set_style_text_align(label_scr2, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr2, "SCR2: %p", scr2);

            lv_obj_t* label_scr2a = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_scr2a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr2a, "&SCR2: %p", &scr2);

            counter++;
            lv_obj_t* label_counter = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_counter, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_counter, LV_ALIGN_CENTER, 0, 100);        
            lv_label_set_text_fmt(label_counter, "Counter: %u", counter);

            btn1 = lv_btn_create(scr2);
            lv_obj_set_size(btn1, 200, 100);
            lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);

            lv_obj_t* label = lv_label_create(btn1);
            lv_label_set_text(label, "Button");        
            lv_obj_center(label);

            lv_scr_load(scr2);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr);  // prev is now not the active screen, so it can safely be deleted

            if( a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED);           
            
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }
        
        
        vTaskDelay( xDelay );               
   
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED);
                        
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
        
        
        vTaskDelay( xDelay );  
    }    
}


void lvgl_task_handler( void* param )
{
    (void) param;
         
    const TickType_t WakeTime = pdMS_TO_TICKS( 5 );  // The macro pdMS_TO_TICKS() can be used to convert milliseconds into ticks. 
     
	while(1)  // execulta a cada 5 ms. 
	{      
        my_led_toggle_3();
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            lv_task_handler();
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }   
        
        // Wait for the next cycle.
  		vTaskDelay( WakeTime );            
    }
}


int main( void )
{   
    SYS_Initialize( NULL );  // Initialize all modules    
    
    my_modules_Initialize();

//////////////////////////////////////////////////////////////////////////////// 
        
    lvgl_mutex = xSemaphoreCreateMutex();    
    if( lvgl_mutex == NULL ) 
    { 
        //printf("ERROR: lvgl_mutex NO MEMORY");
        my_led_set_1();
        return 0;       
    }
    
        
    TickType_t tempo = 5000;       
                
    xTaskCreate(    task,
                    "task",
                    4096, //512,    // words(4 bytes). 512 words * 4 = 2048 bytes.
                    &tempo,  
                    1,
                    (TaskHandle_t*) NULL       
                );
        
       
    xTaskCreate(    lvgl_task_handler, 
                    "littleVgl", 
                    4096,  //512,  
                    (void*) NULL,
                    2,    
                    (TaskHandle_t*) NULL                                              
                );
    
    
    vTaskStartScheduler();    
}

In annex follow a video.
SPI at 45 Mhz.
No tearing support.

in the video you can see that the sw switch does not change state while the scr1 screen is loaded.

Hi,

Now i tested with “lv_scr_load_anim()”.
After some little time the program crash with an exception.

For the little bit i debuged, i saw an exception in “lv_obj_update_layout()” function.

Does anyone have any suggestions why this happens ?

Link to video:

static lv_obj_t* scr1;
static lv_obj_t* scr2;
static lv_obj_t* prev_scr;    
static bool a = 0;
static lv_style_t style_screen1;
static lv_style_t style_screen2;
static lv_obj_t* sw;
static lv_obj_t* btn1;
static uint32_t counter = 0;

void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     

    
    while(1)
    {       
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {        
            //prev_scr = lv_scr_act(); /* save previously active screen */       
            scr1 = lv_obj_create(NULL);

            lv_style_init(&style_screen1);
            lv_style_set_bg_color(&style_screen1, lv_color_white());
            lv_obj_add_style(scr1, &style_screen1, LV_PART_MAIN );  //turn the screen white

            lv_obj_t* label_scr1 = lv_label_create(scr1);     
            lv_obj_set_style_text_align(label_scr1, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr1, "SCR1: %p", scr1);

            lv_obj_t* label_scr1a = lv_label_create(scr1);
            lv_obj_set_style_text_align(label_scr1a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr1a, "&SCR1: %p", &scr1);

            sw = lv_switch_create(scr1);
            lv_obj_set_size(sw, 200, 100);
            lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);

            a = !a;
            if( a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);           
            else
                lv_obj_clear_state(sw, LV_STATE_CHECKED);   
            
            //lv_scr_load(scr1);
            lv_scr_load_anim(scr1, LV_SCR_LOAD_ANIM_FADE_ON, 1000, 0, true);
            //if( prev_scr != NULL )
            //    lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
                       
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
                                       
               
        vTaskDelay( xDelay );  
             
/*        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);              
            else        
                lv_obj_clear_state(sw, LV_STATE_CHECKED); 

            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }   
        

        vTaskDelay( xDelay ); 
*/        
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            //prev_scr = lv_scr_act();  // save previously active screen 
            scr2 = lv_obj_create(NULL);
                
            lv_style_init(&style_screen2);
            lv_style_set_bg_color(&style_screen2, lv_color_white());        
            lv_obj_add_style(scr2, &style_screen2, LV_PART_MAIN );  //turn the screen black
            
            lv_obj_t* label_scr2 = lv_label_create(scr2);        
            lv_obj_set_style_text_align(label_scr2, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr2, "SCR2: %p", scr2);

            lv_obj_t* label_scr2a = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_scr2a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr2a, "&SCR2: %p", &scr2);

            counter++;
            lv_obj_t* label_counter = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_counter, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_counter, LV_ALIGN_CENTER, 0, 100);        
            lv_label_set_text_fmt(label_counter, "Counter: %u", counter);

            btn1 = lv_btn_create(scr2);
            lv_obj_set_size(btn1, 200, 100);
            lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);

            lv_obj_t* label = lv_label_create(btn1);
            lv_label_set_text(label, "Button");        
            lv_obj_center(label);

            if( a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED); 
            
            //lv_scr_load(scr2);
            lv_scr_load_anim(scr2, LV_SCR_LOAD_ANIM_FADE_ON, 1000, 0, true);
            //if( prev_scr != NULL )
            //    lv_obj_del(prev_scr);  // prev is now not the active screen, so it can safely be deleted           
                        
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }
        
        
        vTaskDelay( xDelay );               
   
/*       
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED);
                        
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
        
        
        vTaskDelay( xDelay );
*/  
    }    
}

Hi,

Some suggestion ?

Thank’s.

Try it this way:
if( scr2 != NULL )
{
lv_obj_del(scr2);
scr2 = NULL;
}
scr1 = lv_obj_create(NULL);

lv_example_img_3();
vTaskDelay( xDelay );

if( scr1 != NULL )
{
lv_obj_del(scr1);
scr1 = NULL;
}
scr2 = lv_obj_create(NULL);

lv_example_meter_2();
vTaskDelay( xDelay );

Hi,

I was migrating to another microcomtroller(PIC32MZ) and this way worked.

static lv_obj_t* scr1;
static lv_obj_t* scr2;
static lv_obj_t* prev_scr;    
static bool a = 0;
static lv_style_t style_screen1;
static lv_style_t style_screen2;
static lv_obj_t* sw;
static lv_obj_t* btn1;

static uint32_t counter = 0;


void task( void* pvParameters )
{
    TickType_t* time = (TickType_t*) pvParameters;    

    static TickType_t xDelay;    
    xDelay = pdMS_TO_TICKS( *time );     

    
    while(1)
    {       
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {        
            prev_scr = lv_scr_act(); /* save previously active screen */       
            scr1 = lv_obj_create(NULL);

            lv_style_init(&style_screen1);
            lv_style_set_bg_color(&style_screen1, lv_color_white());
            lv_obj_add_style(scr1, &style_screen1, LV_PART_MAIN );  //turn the screen white

            lv_obj_t* label_scr1 = lv_label_create(scr1);     
            lv_obj_set_style_text_align(label_scr1, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr1, "SCR1: %p", scr1);

            lv_obj_t* label_scr1a = lv_label_create(scr1);
            lv_obj_set_style_text_align(label_scr1a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr1a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr1a, "&SCR1: %p", &scr1);

            sw = lv_switch_create(scr1);
            lv_obj_set_size(sw, 200, 100);
            lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);

            
            a = !a;
            if( a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);           
            else
                lv_obj_clear_state(sw, LV_STATE_CHECKED);        
            
            lv_scr_load(scr1);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */
                
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
                                       
               
        vTaskDelay( xDelay );  
             
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);              
            else        
                lv_obj_clear_state(sw, LV_STATE_CHECKED); 

            lv_scr_load(scr1); 
            
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }   
        

        vTaskDelay( xDelay ); 
        
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            prev_scr = lv_scr_act();  // save previously active screen 
            scr2 = lv_obj_create(NULL);
                
            lv_style_init(&style_screen2);
            lv_style_set_bg_color(&style_screen2, lv_color_white());        
            lv_obj_add_style(scr2, &style_screen2, LV_PART_MAIN );  //turn the screen black
            
            lv_obj_t* label_scr2 = lv_label_create(scr2);        
            lv_obj_set_style_text_align(label_scr2, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2, LV_ALIGN_CENTER, 0, -100);        
            lv_label_set_text_fmt(label_scr2, "SCR2: %p", scr2);

            lv_obj_t* label_scr2a = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_scr2a, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_scr2a, LV_ALIGN_CENTER, 0, -80);        
            lv_label_set_text_fmt(label_scr2a, "&SCR2: %p", &scr2);

            counter++;
            lv_obj_t* label_counter = lv_label_create(scr2);             
            lv_obj_set_style_text_align(label_counter, LV_TEXT_ALIGN_CENTER, 0);
            lv_obj_align(label_counter, LV_ALIGN_CENTER, 0, 100);        
            lv_label_set_text_fmt(label_counter, "Counter: %u", counter);

            btn1 = lv_btn_create(scr2);
            lv_obj_set_size(btn1, 200, 100);
            lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);

            lv_obj_t* label = lv_label_create(btn1);
            lv_label_set_text(label, "Button");        
            lv_obj_center(label);
            
            if( a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED);           

            lv_scr_load(scr2);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr);  // prev is now not the active screen, so it can safely be deleted

            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        }
        
        
        vTaskDelay( xDelay );               
   
        
        if( xSemaphoreTake( lvgl_mutex, ( TickType_t ) semaphore_block_time ) == pdTRUE )
        {
            if( !a )
                lv_obj_add_state(btn1, LV_STATE_PRESSED);
            else
                lv_obj_clear_state(btn1, LV_STATE_PRESSED);
                        
            lv_scr_load(scr2);
            
            xSemaphoreGive( lvgl_mutex );
        }
        else
        {
            // printf("Bug in xxxx, dont take the mutex after: %u ms\n", semaphore_block_time);        
        } 
        
        
        vTaskDelay( xDelay );  
    }    
}

I only swapp the code from this:

            lv_scr_load(scr1);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */

            a = !a;
            if( a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);           
            else
                lv_obj_clear_state(sw, LV_STATE_CHECKED);            

to this:

            a = !a;
            if( a )
                lv_obj_add_state(sw, LV_STATE_CHECKED);           
            else
                lv_obj_clear_state(sw, LV_STATE_CHECKED);        
            
            lv_scr_load(scr1);
            if( prev_scr != NULL )
                lv_obj_del(prev_scr); /* prev is now not the active screen, so it can safely be deleted */

The strange thing is that only “switch” object not changed your state but “btn” object changed this state in this “wrong” way.

Even so i changed the order of the program for the two objects and now works ( i think without memory leak ).