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