How to run an AWS demo again?

Hi.

I’m testing the Shadow demo successfully over Ethernet, but for example, when the hardware is powered up for the first time and there is an error on the network, the following message is printed

IotLogError (“Failed to initialize the demo. Exiting …”);

And then obviously the following message:

IotLogInfo ("------- DEMO FINISHED ------- \ n");

For it to work properly again, I need to reset the hardware.

I would like this to be done automatically, for example it occurs to me to use an instruction that restarts the microcontroller, but I think there must be a better way to restart the task.

Any comment or suggestion is welcome.

Hi,

I am not familiar with the Shadow system, but normally such a condition is handled via a watchdog that is being retriggered as long as the demo runs.

1 Like

Hello @DominusDRR ,

Thanks for reaching out. Are you asking how to restart the hardware or how to restart the demo after hardware has been reset ?

One option is to call the demo entry function only after the hardware initialization is complete. If you have a way check if network controller has initialized successfully, check that first and then call the demo entry function only after hardware has been initialized successfully. By doing so, the demo will not fail.

Thanks.

1 Like

Hi . Thanks for answering.

Sorry for the delay, I was solving some issues with the hardware design that was urgent.

I have an idea how to solve the question, first the RunShadowDemo and runDemoTask functions are defined like this:

int RunShadowDemo( bool awsIotMqttMode,const char * pIdentifier,void * pNetworkServerInfo,void * pNetworkCredentialInfo,const IotNetworkInterface_t * pNetworkInterface )
{
     ...
    if( status == EXIT_SUCCESS )
    {
        /* Clear the Shadow document so that this demo starts with no existing
         * Shadow. */
        _clearShadowDocument( mqttConnection, pIdentifier, thingNameLength );

        /* Send Shadow updates. */
        status = _sendShadowUpdates( &deltaSemaphore,mqttConnection, pIdentifier, thingNameLength );
		/******* Added by MCU manufacturer ******/
		for(;;) 
		{
			 vTaskDelay(100);
		}
		/***********************/
        /* Delete the Shadow document created by this demo to clean up. */
        _clearShadowDocument( mqttConnection, pIdentifier, thingNameLength );
    }

    /* Disconnect the MQTT connection if it was established. */
    if( connectionEstablished == true )
    {
        IotMqtt_Disconnect( mqttConnection, 0 );
    }

    /* Clean up libraries if they were initialized. */
    if( librariesInitialized == true )
    {
        _cleanupDemo();
    }

    /* Destroy the delta semaphore if it was created. */
    if( deltaSemaphoreCreated == true )
    {
        IotSemaphore_Destroy( &deltaSemaphore );
    }

    return status;
}
void runDemoTask( void * pArgument )
{
    /* On FreeRTOS, credentials and server info are defined in a header
     * and set by the initializers. */

    ...
    IotLogInfo( "---------STARTING DEMO---------\n" );

    status = _initialize( pContext );

    if( status == EXIT_SUCCESS )
    {
        IotLogInfo( "Successfully initialized the demo. Network type for the demo: %d", demoConnectedNetwork );

        pNetworkInterface = AwsIotNetworkManager_GetNetworkInterface( demoConnectedNetwork );
        pConnectionParams = AwsIotNetworkManager_GetConnectionParams( demoConnectedNetwork );
        pCredentials = AwsIotNetworkManager_GetCredentials( demoConnectedNetwork );

        /* Run the demo. */
        status = pContext->demoFunction( true,clientcredentialIOT_THING_NAME,pConnectionParams,pCredentials,pNetworkInterface );

        /* Log the demo status. */
        if( status == EXIT_SUCCESS )
        {
            /* DO NOT EDIT - This message is used in the test framework to
             * determine whether or not the demo was successful. */
            IotLogInfo( "Demo completed successfully." );
        }
        else
        {
            IotLogError( "Error running demo." );
        }

        _cleanup();
    }
    else
    {
        IotLogError( "Failed to initialize the demo. exiting..." );
    }

    /* DO NOT EDIT - This demo end marker is used in the test framework to
     * determine the end of a demo. */
    IotLogInfo( "-------DEMO FINISHED-------\n" );
}

It can be seen that in the RunShadowDemo function there is an infinite loop (for(;;)) with a delay. This is a modification that the MCU manufacturer made for an example, and that way the demo is always working. (As long as there is no error in the network).

What I can think of to do is in the runDemoTask function is to wrap the entire process in an infinite loop as indicated below:

void runDemoTask( void * pArgument )
{
    /* On FreeRTOS, credentials and server info are defined in a header
     * and set by the initializers. */

    ...
	for(;;) //infinite loop by me
	{
		IotLogInfo( "---------STARTING DEMO---------\n" );

		status = _initialize( pContext );
		if( status == EXIT_SUCCESS )
		{
			IotLogInfo( "Successfully initialized the demo. Network type for the demo: %d", demoConnectedNetwork );

			pNetworkInterface = AwsIotNetworkManager_GetNetworkInterface( demoConnectedNetwork );
			pConnectionParams = AwsIotNetworkManager_GetConnectionParams( demoConnectedNetwork );
			pCredentials = AwsIotNetworkManager_GetCredentials( demoConnectedNetwork );

			/* Run the demo. */
			status = pContext->demoFunction( true,clientcredentialIOT_THING_NAME,pConnectionParams,pCredentials,pNetworkInterface );

			/* Log the demo status. */
			if( status == EXIT_SUCCESS )
			{
				/* DO NOT EDIT - This message is used in the test framework to
				 * determine whether or not the demo was successful. */
				IotLogInfo( "Demo completed successfully." );
			}
			else
			{
				IotLogError( "Error running demo." );
			}

			_cleanup();
		}
		else
		{
			IotLogError( "Failed to initialize the demo. exiting..." );
		}
	}

    /* DO NOT EDIT - This demo end marker is used in the test framework to
     * determine the end of a demo. */
    IotLogInfo( "-------DEMO FINISHED-------\n" );
}

that way, if an error occurs, the process would start again as many times as necessary.

Do you think it is a good idea?

This is probably not the ideal solution given that you will have to unnecessarily teardown the connection on every iteration. It can make the system unresponsive because you will have to keep establishing a TCP connection and TLS handshake constantly. I would suggest just modifying the demo so that you only reconnect when there is a network error. Also, the code you are using is a deprecated version of the AWS IoT libraries, and I highly suggest using the new coreMQTT and Shadow libraries. A demo of these new libraries is provided here.