Esempio n. 1
0
/** Tests validity of pointed data */
inline enum IMUErrorMask eIMUDataValid( const struct IMUData * const pxIMUData )
{
enum IMUErrorMask eErrorMask = IMU_ERR_NONE;

	eErrorMask |= prvAltitudeValid( pxIMUData )
			| prvAngleValid( pxIMUData );
			/*
			| prvSpeedValid( pxIMUData )
			| prvAccelValid( pxIMUData );
			*/

	if( eErrorMask == IMU_ERR_NONE )
	{
		ulDebugMsg( xTaskGetTickCount(), "INFO ", pcTaskGetTaskName( NULL ),
				uxTaskPriorityGet( NULL ), MODULE, "eIMUDataValid()",
				"IMU measure is in valid range" );
	}
	else
	{
		ulDebugMsg( xTaskGetTickCount(), "ERROR", pcTaskGetTaskName( NULL ),
				uxTaskPriorityGet( NULL ), MODULE, "eIMUDataValid()",
				"IMU measure is not in valid range !" );
	}

	return eErrorMask;
}
Esempio n. 2
0
void TaskBase::print_status (emstream& ser_dev)
{
	ser_dev.puts (pcTaskGetTaskName (handle));
	ser_dev.putchar ('\t');
	if (strlen ((const char*)(pcTaskGetTaskName (handle))) < 8)
	{
		ser_dev.putchar ('\t');
	}
	ser_dev << (uint8_t)(uxTaskPriorityGet (handle)) << PMS ("\t")
			<< get_state ()
		#if (INCLUDE_uxTaskGetStackHighWaterMark == 1)
			<< PMS ("\t") << uxTaskGetStackHighWaterMark(handle) << PMS ("/") 
			<< (size_t)(get_total_stack ()) << PMS ("\t")
		#endif
			<< PMS ("\t") << runs;
}
Esempio n. 3
0
/** Gets IMU attitude measurements */
inline void vIMUGetData( struct IMUData * const pxIMUData )
{
	ulDebugMsg( xTaskGetTickCount(), "TODO", pcTaskGetTaskName( NULL ),
			uxTaskPriorityGet( NULL ), "imu", "vIMUGetData()", "Does nothing ATM" );

	/* TODO : implement during integration */
}
Esempio n. 4
0
/** Tests correct behavior of the IMU */
inline uint8_t ucIMUTest( void )
{
	ulDebugMsg( xTaskGetTickCount(), "TODO", pcTaskGetTaskName( NULL ),
			uxTaskPriorityGet( NULL ), "imu", "ucIMUTest()", "Does nothing ATM" );

	return 0;
}
/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
#ifdef FREERTOS_CONFIG_H
  CurrentTaskHandle = xTaskGetCurrentTaskHandle();
  pNameCurrentTask = pcTaskGetTaskName(CurrentTaskHandle);    
#endif
  
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}
Esempio n. 6
0
static void task_wdt_isr(void *arg) {
    wdt_task_t *wdttask;
    const char *cpu;
    //Feed the watchdog so we do not reset
    TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
    TIMERG0.wdt_feed=1;
    TIMERG0.wdt_wprotect=0;
    //Ack interrupt
    TIMERG0.int_clr_timers.wdt=1;
    //We are taking a spinlock while doing I/O (ets_printf) here. Normally, that is a pretty
    //bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case,
    //something bad already happened and reporting this is considered more important
    //than the badness caused by a spinlock here.
    portENTER_CRITICAL(&taskwdt_spinlock);
    if (!wdt_task_list) {
        //No task on list. Maybe none registered yet.
        portEXIT_CRITICAL(&taskwdt_spinlock);
        return;
    }
    //Watchdog got triggered because at least one task did not report in.
    ets_printf("Task watchdog got triggered. The following tasks did not feed the watchdog in time:\n");
    for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) {
        if (!wdttask->fed_watchdog) {
            cpu=xTaskGetAffinity(wdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1");
            if (xTaskGetAffinity(wdttask->task_handle)==tskNO_AFFINITY) cpu=DRAM_STR("CPU 0/1");
            ets_printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu);
        }
    }
    ets_printf(DRAM_STR("Tasks currently running:\n"));
    for (int x=0; x<portNUM_PROCESSORS; x++) {
        ets_printf("CPU %d: %s\n", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x)));
    }

#if CONFIG_TASK_WDT_PANIC
    ets_printf("Aborting.\n");
    abort();
#endif
    portEXIT_CRITICAL(&taskwdt_spinlock);
}
Esempio n. 7
0
void putsTaskFunction(void *parameters)
{
  portTickType waketime = xTaskGetTickCount();

  for (;;)
  {
    vTaskDelayUntil(&waketime, (MESSAGE_PERIOD/2 + (lrand48() % (MESSAGE_PERIOD/2)))/portTICK_RATE_MS);

    xSemaphoreTake(console_lock, portMAX_DELAY);
    printf("This is %s\n", pcTaskGetTaskName(NULL));
    xSemaphoreGive(console_lock);
  }
}
/**
  * @brief  This is the code that gets called when the processor receives an 
  *         unexpected interrupt.  This simply enters an infinite loop, 
  *         preserving the system state for examination by a debugger.
  * @param  None
  * @retval None  
  */
static void Default_Handler(void)
{
  /* Go into an infinite loop. */
	int i;

	static char buffer[64];
	snprintf(buffer, 64,"SOMETHING WRONG IN TASK: %s \r\n", pcTaskGetTaskName(NULL) );
	log_func(buffer);
	for( ;; );
  while (1)
  {

  }
}
Esempio n. 9
0
/**************************************************************************//**
 * @brief Simple task which is blinking led
 * @param *pParameters pointer to parameters passed to the function
 *****************************************************************************/
static void LedTask(void *pParameters)
{
    vTaskDelay(1000 / portTICK_RATE_MS);

    LedTaskParams_t     * pData = (LedTaskParams_t*) pParameters;
    const portTickType delay = pData->delay;

    for (;;)
    {
        BSP_LedToggle(pData->ledNo);
        vTaskDelay(delay);
        printf("%s. FreeHeap: %d\n", pcTaskGetTaskName(NULL), xPortGetFreeHeapSize());
    }
}
Esempio n. 10
0
/* This is an entry point for the application.
   All application specific initialization is performed here. */
int main(void)
{
    int ret = 0;
    TaskHandle_t blinkLEDHandle = NULL;
    int priority;

    /* Initializes console on UART0 */
    ret = wmstdio_init(UART0_ID, 0);
    if (ret == -WM_FAIL)
    {
        wmprintf("Failed to initialize console on uart0\r\n");
        return -1;
    }

    wmprintf(" LED demo application started\r\n");
    wmprintf(" This application demonstrates the"
                  " use of blinking led\r\n");

    gpio_led = (board_led_2()).gpio;

    wmprintf(" LED Pin : %d\r\n", gpio_led);

    configure_gpios();

    xTaskCreate(prvBlinkLedTask, "Blink led", ( uint16_t ) BLINK_LED_STACK_SIZE, NULL, ( ( UBaseType_t ) BLINK_LED_TASK_PRIORITY ) | portPRIVILEGE_BIT, &blinkLEDHandle);
    // dump blink led task related information
    if (NULL != blinkLEDHandle)
    {
        priority = uxTaskPriorityGet(blinkLEDHandle);
        wmprintf("blink led priority is %d\r\n", priority);
        wmprintf("blink led task name:%s\r\n", pcTaskGetTaskName(blinkLEDHandle));
    }
    wmprintf("run blink led task for 30 seconds\r\n");
    vTaskDelay(30000);
    wmprintf("delete blink led task\r\n");
    if (NULL != blinkLEDHandle)
    {
        vTaskDelete(blinkLEDHandle);
        blinkLEDHandle = NULL;
    }
    while (1)
    {
        vTaskDelay(1000);
    }
    return 0;
}
Esempio n. 11
0
void UTL_FreeRtosTaskStackCheck(void)
{
  taskInfoArray[PrintTaskIndex].FreeEntries = 
    uxTaskGetStackHighWaterMark(taskInfoArray[PrintTaskIndex].taskHandle);
  
  /* free, used, total */
  PrintF("%s %d %d %d",
    (char*)pcTaskGetTaskName(taskInfoArray[PrintTaskIndex].taskHandle),
     taskInfoArray[PrintTaskIndex].FreeEntries,
     taskInfoArray[PrintTaskIndex].Depth - taskInfoArray[PrintTaskIndex].FreeEntries,
     taskInfoArray[PrintTaskIndex].Depth));
               
  PrintTaskIndex ++;
  if (rintTaskIndex >= TaskIndex)
  {
    PrintTaskIndex = 3;    
    CreateAndSendMessage(&Msg, QueryMemoryMsg, MSG_OPT_NONE);
  }
}
Esempio n. 12
0
/** Gets IMU attitude measurements */
inline void vIMUGetData( struct IMUData * const pxIMUData )
{
	ulDebugMsg( xTaskGetTickCount(), "INFO ", pcTaskGetTaskName( NULL ),
			uxTaskPriorityGet( NULL ), MODULE, "vIMUGetData()", "Receiving IMU measurements" );

	/* Reception is now handled by an interrupt */
	//taskENTER_CRITICAL();
	//imu_receive_frame( pusBuff );
	//taskEXIT_CRITICAL();

	/** @todo  Ensure pusBuff is protected from overwriting while it is being
	parsed. */
	imu_parse_frame( pxIMUData );

	/* Displaced to prvSendStatus() */
//	printf( "\r\n\t\tIMU measurements :"
//			"\r\n\t\t\tPitch = %d\r\n\t\t\tRoll = %d\r\n\t\t\tYaw = %d",
//			pxIMUData->plAngle[ IMU_AXIS_Y ],
//			pxIMUData->plAngle[ IMU_AXIS_X ],
//			pxIMUData->plAngle[ IMU_AXIS_Z ] );
}
Esempio n. 13
0
static void prvDemonstrateTaskStateAndHandleGetFunctions( void )
{
TaskHandle_t xIdleTaskHandle, xTimerTaskHandle;
char *pcTaskName;
static portBASE_TYPE xPerformedOneShotTests = pdFALSE;
TaskHandle_t xTestTask;

	/* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and
	xTaskGetIdleTaskHandle() functions.  Also try using the function that sets
	the task number. */
	xIdleTaskHandle = xTaskGetIdleTaskHandle();
	xTimerTaskHandle = xTimerGetTimerDaemonTaskHandle();

	/* This is the idle hook, so the current task handle should equal the
	returned idle task handle. */
	if( xTaskGetCurrentTaskHandle() != xIdleTaskHandle )
	{
		pcStatusMessage = "Error:  Returned idle task handle was incorrect";
	}

	/* Check the timer task handle was returned correctly. */
	pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );
	if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )
	{
		pcStatusMessage = "Error:  Returned timer task handle was incorrect";
	}

	/* This task is running, make sure it's state is returned as running. */
	if( eTaskStateGet( xIdleTaskHandle ) != eRunning )
	{
		pcStatusMessage = "Error:  Returned idle task state was incorrect";
	}

	/* If this task is running, then the timer task must be blocked. */
	if( eTaskStateGet( xTimerTaskHandle ) != eBlocked )
	{
		pcStatusMessage = "Error:  Returned timer task state was incorrect";
	}

	/* Other tests that should only be performed once follow.  The test task
	is not created on each iteration because to do so would cause the death
	task to report an error (too many tasks running). */
	if( xPerformedOneShotTests == pdFALSE )
	{
		/* Don't run this part of the test again. */
		xPerformedOneShotTests = pdTRUE;

		/* Create a test task to use to test other eTaskStateGet() return values. */
		if( xTaskCreate( prvTestTask, "Test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xTestTask ) == pdPASS )
		{
			/* If this task is running, the test task must be in the ready state. */
			if( eTaskStateGet( xTestTask ) != eReady )
			{
				pcStatusMessage = "Error: Returned test task state was incorrect 1";
			}

			/* Now suspend the test task and check its state is reported correctly. */
			vTaskSuspend( xTestTask );
			if( eTaskStateGet( xTestTask ) != eSuspended )
			{
				pcStatusMessage = "Error: Returned test task state was incorrect 2";
			}

			/* Now delete the task and check its state is reported correctly. */
			vTaskDelete( xTestTask );
			if( eTaskStateGet( xTestTask ) != eDeleted )
			{
				pcStatusMessage = "Error: Returned test task state was incorrect 3";
			}
		}
	}
}
Esempio n. 14
0
void vPortExceptionHandler( void *pvExceptionID )
{
extern void *pxCurrentTCB;

	/* Fill an xPortRegisterDump structure with the MicroBlaze context as it
	was immediately before the exception occurrence. */
	
	/* First fill in the name and handle of the task that was in the Running 
	state when the exception occurred. */
	xRegisterDump.xCurrentTaskHandle = pxCurrentTCB;
	xRegisterDump.pcCurrentTaskName = pcTaskGetTaskName( NULL );

	configASSERT( pulStackPointerOnFunctionEntry );

	/* Obtain the values of registers that were stacked prior to this function
	being called, and may have changed since they were stacked. */
	xRegisterDump.ulR3 = pulStackPointerOnFunctionEntry[ portexR3_STACK_OFFSET ];
	xRegisterDump.ulR4 = pulStackPointerOnFunctionEntry[ portexR4_STACK_OFFSET ];
	xRegisterDump.ulR5 = pulStackPointerOnFunctionEntry[ portexR5_STACK_OFFSET ];
	xRegisterDump.ulR6 = pulStackPointerOnFunctionEntry[ portexR6_STACK_OFFSET ];
	xRegisterDump.ulR7 = pulStackPointerOnFunctionEntry[ portexR7_STACK_OFFSET ];
	xRegisterDump.ulR8 = pulStackPointerOnFunctionEntry[ portexR8_STACK_OFFSET ];
	xRegisterDump.ulR9 = pulStackPointerOnFunctionEntry[ portexR9_STACK_OFFSET ];
	xRegisterDump.ulR10 = pulStackPointerOnFunctionEntry[ portexR10_STACK_OFFSET ];
	xRegisterDump.ulR11 = pulStackPointerOnFunctionEntry[ portexR11_STACK_OFFSET ];
	xRegisterDump.ulR12 = pulStackPointerOnFunctionEntry[ portexR12_STACK_OFFSET ];
	xRegisterDump.ulR15_return_address_from_subroutine = pulStackPointerOnFunctionEntry[ portexR15_STACK_OFFSET ];
	xRegisterDump.ulR18 = pulStackPointerOnFunctionEntry[ portexR18_STACK_OFFSET ];
	xRegisterDump.ulR19 = pulStackPointerOnFunctionEntry[ portexR19_STACK_OFFSET ];
	xRegisterDump.ulMSR = pulStackPointerOnFunctionEntry[ portexMSR_STACK_OFFSET ];
	
	/* Obtain the value of all other registers. */
	xRegisterDump.ulR2_small_data_area = mfgpr( R2 );
	xRegisterDump.ulR13_read_write_small_data_area = mfgpr( R13 );
	xRegisterDump.ulR14_return_address_from_interrupt = mfgpr( R14 );
	xRegisterDump.ulR16_return_address_from_trap = mfgpr( R16 );
	xRegisterDump.ulR17_return_address_from_exceptions = mfgpr( R17 );
	xRegisterDump.ulR20 = mfgpr( R20 );
	xRegisterDump.ulR21 = mfgpr( R21 );
	xRegisterDump.ulR22 = mfgpr( R22 );
	xRegisterDump.ulR23 = mfgpr( R23 );
	xRegisterDump.ulR24 = mfgpr( R24 );
	xRegisterDump.ulR25 = mfgpr( R25 );
	xRegisterDump.ulR26 = mfgpr( R26 );
	xRegisterDump.ulR27 = mfgpr( R27 );
	xRegisterDump.ulR28 = mfgpr( R28 );
	xRegisterDump.ulR29 = mfgpr( R29 );
	xRegisterDump.ulR30 = mfgpr( R30 );
	xRegisterDump.ulR31 = mfgpr( R31 );
	xRegisterDump.ulR1_SP = ( ( unsigned long ) pulStackPointerOnFunctionEntry ) + portexASM_HANDLER_STACK_FRAME_SIZE;
	xRegisterDump.ulEAR = mfear();
	xRegisterDump.ulESR = mfesr();
	xRegisterDump.ulEDR = mfedr();
	
	/* Move the saved program counter back to the instruction that was executed
	when the exception occurred.  This is only valid for certain types of
	exception. */
	xRegisterDump.ulPC = xRegisterDump.ulR17_return_address_from_exceptions - portexINSTRUCTION_SIZE;

	#if XPAR_MICROBLAZE_0_USE_FPU == 1
	{
		xRegisterDump.ulFSR = mffsr();
	}
	#else
	{
		xRegisterDump.ulFSR = 0UL;
	}
	#endif

	/* Also fill in a string that describes what type of exception this is.
	The string uses the same ID names as defined in the MicroBlaze standard
	library exception header files. */
	switch( ( unsigned long ) pvExceptionID )
	{
		case XEXC_ID_FSL :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FSL";
				break;

		case XEXC_ID_UNALIGNED_ACCESS :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_UNALIGNED_ACCESS";
				break;

		case XEXC_ID_ILLEGAL_OPCODE :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_ILLEGAL_OPCODE";
				break;

		case XEXC_ID_M_AXI_I_EXCEPTION :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_M_AXI_I_EXCEPTION or XEXC_ID_IPLB_EXCEPTION";
				break;

		case XEXC_ID_M_AXI_D_EXCEPTION :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_M_AXI_D_EXCEPTION or XEXC_ID_DPLB_EXCEPTION";
				break;

		case XEXC_ID_DIV_BY_ZERO :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_DIV_BY_ZERO";
				break;

		case XEXC_ID_STACK_VIOLATION :
				xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_STACK_VIOLATION or XEXC_ID_MMU";
				break;

		#if XPAR_MICROBLAZE_0_USE_FPU == 1

			case XEXC_ID_FPU :
						xRegisterDump.pcExceptionCause = ( signed char * const ) "XEXC_ID_FPU see ulFSR value";
						break;

		#endif /* XPAR_MICROBLAZE_0_USE_FPU */
	}

	/* vApplicationExceptionRegisterDump() is a callback function that the 
	application can optionally define to receive the populated xPortRegisterDump
	structure.  If the application chooses not to define a version of 
	vApplicationExceptionRegisterDump() then the weekly defined default 
	implementation within this file will be called instead. */
	vApplicationExceptionRegisterDump( &xRegisterDump );

	/* Must not attempt to leave this function! */
	for( ;; )
	{
		portNOP();
	}
}
Esempio n. 15
0
inline void vPWMSet( enum PWMId ePWMId )
{
	ulDebugMsg( xTaskGetTickCount(), "TODO", pcTaskGetTaskName( NULL ),
		uxTaskPriorityGet( NULL ), "pwm", "vPWMSet", "Does nothing ATM" );
}
void aws_iot_task(void *param) {
    char cPayload[100];

    int32_t i = 0;

    IoT_Error_t rc = FAILURE;

    AWS_IoT_Client client;
    IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault;
    IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault;

    IoT_Publish_Message_Params paramsQOS0;
    IoT_Publish_Message_Params paramsQOS1;

    ESP_LOGI(TAG, "AWS IoT SDK Version %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);

    mqttInitParams.enableAutoReconnect = false; // We enable this later below
    mqttInitParams.pHostURL = HostAddress;
    mqttInitParams.port = port;

#if defined(CONFIG_EXAMPLE_EMBEDDED_CERTS)
    mqttInitParams.pRootCALocation = (const char *)aws_root_ca_pem_start;
    mqttInitParams.pDeviceCertLocation = (const char *)certificate_pem_crt_start;
    mqttInitParams.pDevicePrivateKeyLocation = (const char *)private_pem_key_start;

#elif defined(CONFIG_EXAMPLE_FILESYSTEM_CERTS)
    mqttInitParams.pRootCALocation = ROOT_CA_PATH;
    mqttInitParams.pDeviceCertLocation = DEVICE_CERTIFICATE_PATH;
    mqttInitParams.pDevicePrivateKeyLocation = DEVICE_PRIVATE_KEY_PATH;
#endif

    mqttInitParams.mqttCommandTimeout_ms = 20000;
    mqttInitParams.tlsHandshakeTimeout_ms = 5000;
    mqttInitParams.isSSLHostnameVerify = true;
    mqttInitParams.disconnectHandler = disconnectCallbackHandler;
    mqttInitParams.disconnectHandlerData = NULL;

#ifdef CONFIG_EXAMPLE_SDCARD_CERTS
    ESP_LOGI(TAG, "Mounting SD card...");
    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 3,
    };
    sdmmc_card_t* card;
    esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to mount SD card VFAT filesystem. Error: %s", esp_err_to_name(ret));
        abort();
    }
#endif

    rc = aws_iot_mqtt_init(&client, &mqttInitParams);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "aws_iot_mqtt_init returned error : %d ", rc);
        abort();
    }

    /* Wait for WiFI to show as connected */
    xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                        false, true, portMAX_DELAY);

    connectParams.keepAliveIntervalInSec = 10;
    connectParams.isCleanSession = true;
    connectParams.MQTTVersion = MQTT_3_1_1;
    /* Client ID is set in the menuconfig of the example */
    connectParams.pClientID = CONFIG_AWS_EXAMPLE_CLIENT_ID;
    connectParams.clientIDLen = (uint16_t) strlen(CONFIG_AWS_EXAMPLE_CLIENT_ID);
    connectParams.isWillMsgPresent = false;

    ESP_LOGI(TAG, "Connecting to AWS...");
    do {
        rc = aws_iot_mqtt_connect(&client, &connectParams);
        if(SUCCESS != rc) {
            ESP_LOGE(TAG, "Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port);
            vTaskDelay(1000 / portTICK_RATE_MS);
        }
    } while(SUCCESS != rc);

    /*
     * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
     *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
     *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
     */
    rc = aws_iot_mqtt_autoreconnect_set_status(&client, true);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "Unable to set Auto Reconnect to true - %d", rc);
        abort();
    }

    const char *TOPIC = "test_topic/esp32";
    const int TOPIC_LEN = strlen(TOPIC);

    ESP_LOGI(TAG, "Subscribing...");
    rc = aws_iot_mqtt_subscribe(&client, TOPIC, TOPIC_LEN, QOS0, iot_subscribe_callback_handler, NULL);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "Error subscribing : %d ", rc);
        abort();
    }

    sprintf(cPayload, "%s : %d ", "hello from SDK", i);

    paramsQOS0.qos = QOS0;
    paramsQOS0.payload = (void *) cPayload;
    paramsQOS0.isRetained = 0;

    paramsQOS1.qos = QOS1;
    paramsQOS1.payload = (void *) cPayload;
    paramsQOS1.isRetained = 0;

    while(1) {

        //Max time the yield function will wait for read messages
        rc = aws_iot_mqtt_yield(&client, 100);
        if(NETWORK_ATTEMPTING_RECONNECT == rc) {
            // If the client is attempting to reconnect we will skip the rest of the loop.
            continue;
        }

        ESP_LOGI(TAG, "Stack remaining for task '%s' is %lu bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
        vTaskDelay(1000 / portTICK_RATE_MS);
        sprintf(cPayload, "%s : %d ", "hello from ESP32 (QOS0)", i++);
        paramsQOS0.payloadLen = strlen(cPayload);
        rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);

        sprintf(cPayload, "%s : %d ", "hello from ESP32 (QOS1)", i++);
        paramsQOS1.payloadLen = strlen(cPayload);
        rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS1);
        if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
            ESP_LOGW(TAG, "QOS1 publish ack not received.");
            rc = SUCCESS;
        }
    }

    ESP_LOGE(TAG, "An error occurred in the main loop.");
    abort();
}

static void initialise_wifi(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_WIFI_SSID,
            .password = EXAMPLE_WIFI_PASS,
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}