[SOLVED] Best practice to avoid wdt trigger

RichardFalk
Posts: 3
Joined: Mon Oct 11, 2021 7:17 pm

Re: [SOLVED] Best practice to avoid wdt trigger

Postby RichardFalk » Sat Nov 30, 2024 9:43 am

First of all, you don't use a parameter of "1 / portTICK_PERIOD_MS" for vTaskDelay since portTICK_PERIOD_MS is typically 10 ms for a 100Hz tick frequency so the integer divide will truncate to 0.

Using RTOS, the shortest delay is vTaskDelay(1) for 1 tick which with a 100 Hz frequency is 10 ms.

Since you just want to tickle the task watchdog you can just use the function esp_task_wdt_reset().

Note that even this won't fix the RTOS problem of not deleting tasks that were self-deleted (i.e. using vTaskDelete(NULL);). Such self-deleted tasks only get actually deleted in the idle task. The idle task also tickles the watchdog timer. So you can accomplish both by using the FreeRTOS idle hook function you can register with the following done once during startup:

Code: Select all

esp_register_freertos_idle_hook_for_cpu(idle_hook, (UBaseType_t)xPortGetCoreID();
This "idle_hook" function can be something like the following:

Code: Select all

DRAM_ATTR static uint8_t waiting_for_idle = 0;
DRAM_ATTR uint8_t idle_task_was_run = 0;
static bool idle_hook(void)
{
	idle_task_was_run = 1;
	if (waiting_for_idle) {
		waiting_for_idle = 0;  // we only want to notify once
		xTaskNotifyIndexed(mainTaskHandle, TASK_INDEX_IDLE_RUN, 0, eNoAction);
		return false;  // do not idle (i.e. do not wait for interrupt) as we want main task to run
	}

	return true;  // allows idle task to idle (i.e. to wait for interrupt)
}
Then you can call the following "run_idle_task" function whenever you want to run the idle task, but you should only do this when you know nothing else is running in a tight loop. That is, you can call this from your main tight loop.

Code: Select all

void run_idle_task(void)
{
	if (xTaskGetCurrentTaskHandle() != mainTaskHandle) {
		printf( "Must call tasknotify_run_idle_task from main task!\r\n");
		vTaskDelay(1);  // hope that a single 1 tick delay will run the idle task
		return;
	}

	waiting_for_idle = 1;  // will have idle_hook() notify main task when it is run

	// The following suspends the main task so that the idle task can run.
	// It waits for the idle task to finish running so releasing memory from any
	// deleted tasks and resetting the (idle) task watchdog timer.
	xTaskNotifyWaitIndexed(TASK_INDEX_IDLE_RUN, 0, 0, NULL, portMAX_DELAY);

	// waiting_for_idle is set to 0 in idle_hook() just prior to the notify
}
In your startup code you need the following:

Code: Select all

TaskHandle_t mainTaskHandle = 0;
:
// in your app_main function:
	mainTaskHandle = xTaskGetCurrentTaskHandle();

Who is online

Users browsing this forum: Bytespider, ChatGPT-User, YisouSpider and 3 guests