BriscoeTech / Arduino-FreeRTOS-SAMD21

A port of FreeRTOS that runs on Arduino Samd21 boards
63 stars 19 forks source link

SAMD51 Implementation WDT issue #21

Closed Casey10110 closed 3 years ago

Casey10110 commented 4 years ago

Hi Guys,

I've been working with this library and it is working on SAMD51. I'm not sure if this issue exists on SAMD21, but I am unable to get the watchdog timer to function while freertos tasks are running. The board it is being tested on is an Adafruit Feather M4. Any idea why this breaks it and I wonder if it happens on a SAMD21?

`#include

define SERIAL Serial

//** // global variables //** TaskHandle_t Handle_aTask;

//** // Can use these function for RTOS delays // Takes into account procesor speed //**

void myDelayMs(int ms) { vTaskDelay( (ms * 1000) / portTICK_PERIOD_US );
}

void setup(){ vNopDelayMS(1000); // prevents usb driver crash on startup, do not omit this

Serial.begin(9600); while(!Serial);

//vTaskStartScheduler seems to break WDT: xTaskCreate(aTask, "aTask task", 256, NULL, tskIDLE_PRIORITY + 1, &Handle_aTask); vTaskStartScheduler();

//WDT enabled here REG_WDT_CONFIG = WDT_CONFIG_PER_CYC4096_Val; REG_WDT_CTRLA = WDT_CTRLA_ENABLE; // Enable the WDT in normal mode while(WDT->SYNCBUSY.bit.ENABLE);

}

static void aTask( void *pvParameters ) { for(;;) { //if (!WDT->SYNCBUSY.bit.CLEAR) REG_WDT_CLEAR = WDT_CLEAR_CLEAR_KEY; // Clear the watchdog timer Serial.println("aTask"); myDelayMs(100);

} }

void loop(){ Serial.println("mainLoop"); delay(100); }`

BriscoeTech commented 4 years ago

Hello Casey10110,

The vTaskStartScheduler() function is very special in that when you call it, the function never returns and will forever run the rtos scheduler. vTaskStartScheduler should be the last function you call in your setup loop because anything after it will not be run.

https://www.freertos.org/a00132.html

Try moving your watchdog setup code to be before the task creation and see if it starts working.

ZZ-Cat commented 4 years ago

Yea, nah. Your WDT init code needs to be placed above your call to vTaskStartScheduler().

Pro Tip: Initialize WDT before everything else, & set its timeout to a value slightly longer than your usual expected setup time.

Also, you don't necessarily need that 'vNopDelayMS(1000)' or 'Serial.begin(9600)' functions in your 'setup()' routine. Considering that you're already waiting for the native port to connect, that adds in a delay in its own merit; & 'Serial.begin()' doesn't actually call anything on Cortex M0/M4 MCUs. So, you can omit that altogether.

If your MCU has an Early Warning Interrupt, I find it prudent to use that to clear the WDT. However, it may add in a little more complexity to your program. 'Cause what you can do there is, defer clearing the WDT to a task, that is synchronized to the WDT's Early Warning Interrupt. In my experience, doin' it this way improves program stability, as the WDT won't erroneously reset your program willy-nilly (when shit is actually executing properly).

Casey10110 commented 4 years ago

Thanks to everyone who has helped me with this issue and replied here, I really appreciate it. I ended up not really needing freertos and never solved the issue, just for people's info here. There is good advice here.

BriscoeTech commented 3 years ago

For anyone who stumbles here again someday, there is now an official port for the Samd51 here

https://github.com/BriscoeTech/Arduino-FreeRTOS-SAMD51