Memory leak when using wiced_wifi_scan_networks

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi,

I can easily reproduce memory leak issue with the following sequence:

1) Connect to Wifi AP with wiced_wifi_join & wicked_network_up to bring up the connection.

2) delay for 1 second or 2... actually this is not necessary.

3) disconnect the wifi connection by calling wiced_network_down

4) call scan networks by calling wicked_wifi_scan_networks (NOTE: this will always timeout after a scan success)

5) print system memory

6) Go back to step 1.

PS. by executing above step you will see system memory total allocated spec increases on each loop... the issue seems to be scan timeout after wiced_network_down. When scan failed with timeout the memory increases... By the way, scan timeout can only be reproduced after you call wiced_network_down.

Here is the code if needed:

void application_start( )

{

  uint8_t FirstTimeConneced = 0;

    wiced_init( );

    while(1)

    {

  //Sleep for 1 seconds

        wiced_rtos_delay_milliseconds(1*SECONDS);

        if (!FirstTimeConneced)

        {

            char SSIDToConnect[32] = "AP_2.4G"; //Change to connect your AP

            char PassWord[32] = "8888888888"; //Change to connect your AP

            wiced_result_t result = wiced_wifi_join( SSIDToConnect, WICED_SECURITY_WPA2_MIXED_PSK, (uint8_t*)PassWord, 10, NULL ); //Change the security type according to your AP

            WPRINT_APP_INFO( ( "AP Connect Result = %d\r\n",  result) );

            if (result == WICED_SUCCESS)

            {

            if (wiced_network_up( WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL ) == WICED_SUCCESS)

            {

            FirstTimeConneced = 1;

            }

            }

        }

        if (wiced_network_is_up( WICED_STA_INTERFACE ) == WICED_TRUE)

        {

        wiced_network_down(WICED_STA_INTERFACE);

        WPRINT_APP_INFO( ( "NetworkConnection is DOWN\r\n") );

        FirstTimeConneced = 0;

        }

        print_System_memory();

        wiced_result_t scanApiResult = wiced_wifi_scan_networks(scan_result_handler, NULL );

        if (scanApiResult != WICED_SUCCESS)

        {

        WPRINT_APP_INFO( ( "wiced_wifi_scan_networks failed with error code = %d\r\n", scanApiResult) );

        }

    }

}

static void print_System_memory( void )

{

    volatile struct mallinfo mi = mallinfo( );

    WPRINT_APP_INFO( ("\r\n-------------------SYS DBG MEM HEAP DIAGNOSTIC-----------------------\r\n") );

    WPRINT_APP_INFO( ("malloc_info {\r\n"

                      "\tarena:   \t%5d;\t/* total space allocated from system */\r\n"

                      "\tordblks: \t%5d;\t/* number of non-inuse chunks */\r\n"

                      "\tsmblks:  \t%5d;\t/* unused -- always zero */\r\n"

                      "\thblks:   \t%5d;\t/* number of mmapped regions */\r\n"

                      "\thblkhd:  \t%5d;\t/* total space in mmapped regions */\r\n"

                      "\tusmblks: \t%5d;\t/* unused -- always zero */\r\n"

                      "\tfsmblks: \t%5d;\t/* unused -- always zero */\r\n"

                      "\tuordblks:\t%5d;\t/* total allocated space */\r\n"

                      "\tfordblks:\t%5d;\t/* total non-inuse space */\r\n"

                      "\tkeepcost:\t%5d;\t/* top-most, releasable (via malloc_trim) space */\r\n"

                      "};\r\n",

                      mi.arena,

                      mi.ordblks,

                      mi.smblks,

                      mi.hblks,

                      mi.hblkhd,

                      mi.usmblks,

                      mi.fsmblks,

                      mi.uordblks,

                      mi.fordblks,

                      mi.keepcost ));

}

/*

* Callback function to handle scan results

*/

wiced_result_t scan_result_handler( wiced_scan_handler_result_t* malloced_scan_result )

{

    malloc_transfer_to_curr_thread( malloced_scan_result );

    if (malloced_scan_result->scan_complete != WICED_TRUE)

    {

        wiced_scan_result_t* record = &malloced_scan_result->ap_details;

        record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */

        WPRINT_APP_INFO( ( "%3d ", record_count ) );

        print_scan_result(record);

        ++record_count;

    }

    else

    {

        wiced_time_t scan_end_time;

        wiced_time_get_time(&scan_end_time);

        WPRINT_APP_INFO( ("\r\nScan complete in %lu milliseconds\r\n", scan_end_time - scan_start_time) );

    }

    free( malloced_scan_result );

    return WICED_SUCCESS;

}

1 Solution

Hi,

After scanning the network, all scanned data allocated by the lower level interface needs to be freed by the application by provided handler. The wiced_wifi_scan_networks() call needs to complete before calling the wiced_wifi_join() again. It could be achieved by implementing a semaphore. Get the semaphore before calling wiced_wifi_join() and set the semaphore where there are no data returned to the scan network handler. The posted code is updated with callback_sema for example.

Meanwhile, caller for the wiced_wifi_join() could wait for join to complete by supplying a semaphore to the wiced_wifi_join() call. Again the posted code is updated with connection_sema to show usage.


-----------------------------------------------------------------------------

static wiced_semaphore_t callback_sema;

static wiced_semaphore_t connection_sema;

void application_start( )

{

    uint8_t FirstTimeConneced = 0;

    wiced_init();

    wiced_rtos_init_semaphore(&callback_sema);

    wiced_rtos_set_semaphore(&callback_sema);

    wiced_rtos_init_semaphore(&connection_sema);

    wiced_rtos_set_semaphore(&connection_sema);

    while(1)

    {

        // Wait for scanning network to complete

        wiced_rtos_get_semaphore(&callback_sema, 10000);

        if (!FirstTimeConneced && !wiced_network_is_up( WICED_STA_INTERFACE ))

        {

            char SSIDToConnect[32] = "AP_2.4G"; //Change to connect your AP

            char PassWord[32] = "8888888888"; //Change to connect your AP

            wiced_result_t result = wiced_wifi_join( SSIDToConnect, WICED_SECURITY_WPA2_MIXED_PSK, (uint8_t*)PassWord, strlen(PassWord), &connection_sema ); //Change the security type according to your AP

            WPRINT_APP_INFO(("AP Connect Result = %d\r\n", result));

            result = wiced_rtos_get_semaphore(&connection_sema, 10000);

            if (result != WICED_SUCCESS)

                WPRINT_APP_INFO(("Connection semaphore return = %d\r\n", result));

            if (result == WICED_SUCCESS)

            {

                if (wiced_network_up( WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL ) == WICED_SUCCESS)

                {

                    FirstTimeConneced = 1;

                }

            }

        }

        if (wiced_network_is_up( WICED_STA_INTERFACE ) == WICED_TRUE)

        {

            wiced_network_down(WICED_STA_INTERFACE);

            WPRINT_APP_INFO( ( "NetworkConnection is DOWN\r\n") );

            FirstTimeConneced = 0;

        }

        print_System_memory();

        wiced_result_t scanApiResult = wiced_wifi_scan_networks(scan_result_handler, NULL );

        if (scanApiResult != WICED_SUCCESS)

        {

            WPRINT_APP_INFO( ( "wiced_wifi_scan_networks failed with error code = %d\r\n", scanApiResult) );

        }

    }

}

static void print_System_memory( void )

{

    volatile struct mallinfo mi = mallinfo( );

    WPRINT_APP_INFO( ("\r\n-------------------SYS DBG MEM HEAP DIAGNOSTIC-----------------------\r\n") );

    WPRINT_APP_INFO( ("malloc_info {\r\n"

                      "\tarena:  \t%5d;\t/* total space allocated from system */\r\n"

                      "\tordblks: \t%5d;\t/* number of non-inuse chunks */\r\n"

                      "\tsmblks:  \t%5d;\t/* unused -- always zero */\r\n"

                      "\thblks:  \t%5d;\t/* number of mmapped regions */\r\n"

                      "\thblkhd:  \t%5d;\t/* total space in mmapped regions */\r\n"

                      "\tusmblks: \t%5d;\t/* unused -- always zero */\r\n"

                      "\tfsmblks: \t%5d;\t/* unused -- always zero */\r\n"

                      "\tuordblks:\t%5d;\t/* total allocated space */\r\n"

                      "\tfordblks:\t%5d;\t/* total non-inuse space */\r\n"

                      "\tkeepcost:\t%5d;\t/* top-most, releasable (via malloc_trim) space */\r\n"

                      "};\r\n",

                      mi.arena,

                      mi.ordblks,

                      mi.smblks,

                      mi.hblks,

                      mi.hblkhd,

                      mi.usmblks,

                      mi.fsmblks,

                      mi.uordblks,

                      mi.fordblks,

                      mi.keepcost ));

}

/*

* Callback function to handle scan results

*/

wiced_result_t scan_result_handler( wiced_scan_handler_result_t* malloced_scan_result )

{

    malloc_transfer_to_curr_thread( malloced_scan_result );

    if (malloced_scan_result->scan_complete != WICED_TRUE)

    {

        wiced_scan_result_t* record = &malloced_scan_result->ap_details;

        record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */

        WPRINT_APP_INFO( ( "%3d ", record_count ) );

        print_scan_result(record);

        ++record_count;

    }

    else

    {

        wiced_time_t scan_end_time;

        wiced_time_get_time(&scan_end_time);

        WPRINT_APP_INFO( ("\r\nScan complete in %lu milliseconds\r\n", scan_end_time - scan_start_time) );

        wiced_rtos_set_semaphore(&callback_sema);

    }

    free( malloced_scan_result );

    return WICED_SUCCESS;

}

-----------------------------------------------------------------------------


Hope it would help.

Seyhan

View solution in original post

3 Replies