Running MQTT Demo periodically with OTA Update Demo causes firmware to restart

dipen@1337lab.io
Posts: 12
Joined: Wed Jan 29, 2020 8:45 am

Running MQTT Demo periodically with OTA Update Demo causes firmware to restart

Postby dipen@1337lab.io » Sun Sep 06, 2020 4:05 pm

Namaste Forum Members,

I’m using the FreeRTOS V202002.00 downloaded from AWS portal. The MQTT enabled demo was downloaded sometime in the mid of May 2020. Later, by the end of July 2020, I downloaded the OTA enabled demo, again FreeRTOS V202002.00 based. I don’t remember the exact dates when I downloaded the firmware images.

My requirement is to run both MQTT and OTA Update threads in parallel. The OTA Update thread will perform a firmware update whenever initiated from the AWS Cloud. The MQTT thread will periodically publish the application readings to the AWS Cloud and, receive all the messages associated with the topics subscribed for.

My first attempt is to test the existing MQTT Demo and OTA Demo codes, as is. For this, I’ve created two threads for running the two demos.

The code flow is:

1. app_main() --> DEMO_RUNNER_RunDemos() --> runDemoTask() --> Complete the initialisation and establish Wi-Fi connectivity.

2. Instead of calling the RunMqttDemo(), I am calling my RunApplicationFunction().

3. This function creates a thread (pvMqttAndOtaTask), which in-turn creates two more threads (pvOtaUpdateTask and pvMqttTask).

The logic is shared below w/o going into the actual code details.

Code: Select all

void pvMqttAndOtaTask( void * pvParameters )
{
    /* OTA Update Demo Thread */
    status = (int) Iot_CreateDetachedThread( pvOtaUpdateTask,
                                             &otaUpdateDemoContext,
                                             IOT_THREAD_DEFAULT_PRIORITY,
                                             IOT_THREAD_DEFAULT_STACK_SIZE );

    // Delay the MQTT thread creation for allowing the OTA thread to complete
    // establishing the MQTT connection, which will then be used by the MQTT thread.
    ESP_LOGI(TAG, "INFO : Delay before pvMqttTask() thread creation.");
    vTaskDelay( pdMS_TO_TICKS(15000) );

    while(1)
    {
        /* Mqtt Demo Thread */
        status = (int) Iot_CreateDetachedThread( pvMqttTask,
                                                 &mqttDemoContext,
                                                 IOT_THREAD_DEFAULT_PRIORITY,
                                                 IOT_THREAD_DEFAULT_STACK_SIZE );

        // Run the MQTT demo code every one minute. The MQTT demo completes in about 15 seconds.
        vTaskDelay( pdMS_TO_TICKS(60000) );
    }
}

Additional points to be noted are:

1. The OTA Demo thread is created first and then, after a 15 second delay, the MQTT Demo thread is created.

2. OTA Demo code flow is pvOtaUpdateTask thread --> vStartOTAUpdateDemoTask() --> vRunOTAUpdateDemo()

3. OTA Update Demo thread is created only once and the OTA Update Demo runs continuously. However, the MQTT Demo thread is created every minute for the MQTT Demo to run periodically.

4. The same MQTT connection is used, by creating a new IotMqttConnection_t sharedMqttConnection shared by both OTA Update Demo and MQTT Demo.


Both the codes are run as is, w/o any major modifications within the demo codes. The only modifications are

1. In the vRunOTAUpdateDemo(), the sharedMqttConnection = xConnection.xMqttConnection; is added.
2. In the RunMqttDemo(), the _establishMqttConnection() is commented and instead, the mqttConnection = sharedMqttConnection; statement is added.


Observation

1. Both OTA Update Demo and MQTT Demo run in parallel (only once) using the same MQTT connection.

2. The firmware crashes and restarts when the MQTT Demo runs the second time after completing the 1 minute delay.

3. The error is traced back to the Line No. 606 in the iot_mqtt_api.c file --> serializeSubscription = mqttConnection->pSerializer->serialize.subscribe; Below is the code block.

Code: Select all

#if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1
if( mqttConnection->pSerializer != NULL )
{
if( mqttConnection->pSerializer->serialize.subscribe != NULL )
{
serializeSubscription = mqttConnection->pSerializer->serialize.subscribe;
}
else
{
EMPTY_ELSE_MARKER;
}
}
else
{
EMPTY_ELSE_MARKER;
}
#endif /* if IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 */

The partial console error log is provided below.

Code: Select all

Guru Meditation Error: Core 0 panic’ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x40148a58 PS : 0x00060e30 A0 : 0x80148be0 A1 : 0x3ffe7e50
0x40148a58: _subscriptionCommon at D:\gitHub\device\firmware\aws\proj04\FreeRTOS\build/…/libraries/c_sdk/standard/mqtt/src/iot_mqtt_api.c:606

Some Analysis

1. It looks like the mqttConnection->pSerializer->serialize.subscribe parameter is not getting populated from the MQTT connection created via OTA Update.

2. The below code block is present within the _establishMqttConnection(), which does not get executed because the function is commented as mentioned above.

Code: Select all

#if ( IOT_MQTT_ENABLE_SERIALIZER_OVERRIDES == 1 ) && defined( IOT_DEMO_MQTT_SERIALIZER )
networkInfo.pMqttSerializer = IOT_DEMO_MQTT_SERIALIZER;
#endif

Kindly assist in resolving this issue and running the threads as desired.

Thanks | Regards,
Dipen

Who is online

Users browsing this forum: No registered users and 43 guests