Page 1 of 2

triggering WDT in OTA

Posted: Mon Mar 09, 2020 10:05 pm
by mzimmers
Hi all -

Using a WROVER, IDF release/v4.0.

I have an OTA task with this in it (inside a do loop; hence the continue):

Code: Select all

                ESP_LOGI(TAG, "otaTask(): next update partition is %s.", m_partInfo->label);

                rc = esp_ota_begin(m_partInfo, binSize, &m_handle);
                if (rc != ESP_OK)
                {
                    ESP_LOGE(TAG, "otaTask(): esp_ota_begin() returned: %x.", rc);
                    continue;
                }
                ESP_LOGI(TAG, "otaTask(): esp_ota_begin() successful.");
It usually (though not always) yields this error:

Code: Select all

I (44943) Ota: otaTask(): next update partition is ota_1.
E (49923) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (50063) task_wdt:  - IDLE0 (CPU 0)
E (50063) task_wdt: Tasks currently running:
E (50063) task_wdt: CPU 0: ipc0
E (50063) task_wdt: CPU 1: IDLE1
I (51903) Ota: otaTask(): esp_ota_begin() successful.
Any ideas what might be going on?

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 11:41 am
by username
If its inside a do loop then you need to stick a delay in there. Otherwise your starving the WDT.

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 2:04 pm
by mzimmers
The do loop only executes once:

Code: Select all

do
{

	// initialize the socket.
	rc = setupSocket();
	if (rc != 0)
	{
		ESP_LOGE(TAG, "otaTask(): listening socket setup failed.");
		closeSocket();
		continue;
	}
	//ESP_LOGI(TAG, "otaTask(): listening socket setup successfully.");
	
	// we're ready to rock and roll.
	m_partInfo = const_cast<esp_partition_t *>(esp_ota_get_next_update_partition(m_partInfo));
	ESP_LOGI(TAG, "otaTask(): target partition is %s", m_partInfo->label);
	if (m_partInfo == nullptr)
	{
		ESP_LOGE(TAG, "otaTask(): esp_ota_get_next_update_partition() returned null pointer.");
		closeSocket();
		continue;
	}
	ESP_LOGI(TAG, "otaTask(): next update partition is %s.", m_partInfo->label);

	rc = esp_ota_begin(m_partInfo, binSize, &m_handle);
	if (rc != ESP_OK)
	{
		ESP_LOGE(TAG, "otaTask(): esp_ota_begin() returned: %x.", rc);
		closeSocket();
		continue;
	}
	ESP_LOGI(TAG, "otaTask(): esp_ota_begin() successful.");

	rc = receive(binSize);
	if (rc != 0)
	{
		ESP_LOGE(TAG, "otaTask(): receive failed.");
		closeSocket();
		continue;
	}

	rc = esp_ota_end(m_handle); // do this to free memory used by OTA.
	if (rc != ESP_OK)
	{
		ESP_LOGE(TAG, "otaTask(): esp_ota_end returned %x %s", rc, strerror(rc));
		closeSocket();
		continue;
	}

	rc = esp_ota_set_boot_partition(m_partInfo);
	if (rc != ESP_OK)
	{
		ESP_LOGE(TAG, "otaTask(): esp_ota_set_boot_partition() returned %x %s.", rc, strerror(rc));
	}
	closeSocket();
}
while (false);
(This is a coding style which eliminates the need for nested if statements; it makes for more readable code IMO.)

So the loop isn't the problem here.

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 4:03 pm
by boarchuz
It will be the partition erase. It can take a long time.

Try increasing the priority of the task calling esp_ota_begin.

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 4:15 pm
by mzimmers
Hi Boarchuz - thanks for the suggestion. I increased the priority from 5 to 6, and got the same result.

What if I explicitly erased the partition myself, a little at a time? Would a pre-erased partition speed up esp_ota_begin()?

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 4:33 pm
by boarchuz
For the sake of debugging, try increasing it a lot more (eg. to max).

Manually erasing might be tricky- I don't think there's a way to instruct the OTA component to skip the erase so it will likely do it again anyway. I might be wrong.

Here I broke the erase into chunks with a yield in between to keep FreeRTOS happy:
viewtopic.php?f=13&t=10801#p44310
If the priority thing doesn't work, give that a try. If that doesn't work, then it must be something else.

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 4:56 pm
by mzimmers
I tried increasing the priority to 9 (I believe I remember reading somewhere that's the maximum)...same result.

Your workaround is great, but I don't want to modify the idf. Did you ever submit this as a bug?

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 5:30 pm
by boarchuz
Nope, I actually haven't touched OTA for a long time and I'm still not sure if it's a bug or if we're missing something simple.

Out of curiosity, could you try (configMAX_PRIORITIES – 1 )?

I've just had a quick look and it seems the image_size parameter isn't really checked in any significant way, so a hacky solution for now that doesn't touch the IDF might be to erase the partition manually, then you could give esp_ota_begin image_size == 1 and it will only do the smallest possible erase.

I suppose you could always simply ignore the warning.

Re: triggering WDT in OTA

Posted: Tue Mar 10, 2020 5:40 pm
by mzimmers
Tried the utmost priority; same thing.

I then tried your fix, and the problem went away.

If you don't object, I'd like to submit this as a bug, with your workaround cited.

Re: triggering WDT in OTA

Posted: Fri Aug 05, 2022 4:24 am
by jhnlmn
I found another cause for this persistent problem: CPU1 started DMA/SPI transfer (screen refresh) while CPU0 was calling esp_ota_begin. Apparently, esp_ota_begin was blocked waiting for screen update to finish. Raising task priority did not help.
The fix is to delay screen refresh until esp_ota_begin finished.
(I had this problem with IDF 4.4, CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y is already set, but it did not help in my case).