BriscoeTech / Arduino-FreeRTOS-SAMD21

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

Delay function #9

Closed Robokishan closed 5 years ago

Robokishan commented 5 years ago

when i use delay function the task hangs everytime. is that any caution i have to take while using delay function thank you.

BriscoeTech commented 5 years ago

Hello Robokishan,

Yes you are correct, the delay function will hang not just your task, but the entire microcontroller. The delay function should never be used in any code while the RTOS is running. The way delay is designed it was never intended to be a thread/RTOS safe function.

The way delay is implemented varies from microcontroller to microcontroller, but essentially what you are doing is stopping the processor from running all code (except for hardware interrupts) for the specified amount of time. The processor is locked up while the delay is running, and not running any code, and not running the rtos. Thats why everything freezes when you use it in tasks.

FreeRTOS has special delays defined that are thread safe and designed to be used inside tasks. Instead of locking up the processor, they put the tasks to sleep and the scheduler will do other things or run other tasks untill the time the task should wake back up. That is how the scheduler makes it seem like you have multiple threads running simultaneously, it is sharing the one processor among all the tasks really fast and efficiently.

Here is the FreeRTOS user guide for the different types of delays https://www.freertos.org/a00112.html

Also, look at the example Basic_RTOS_Example to see how to implement the three most basic FreeRTOS delays. I made the functions myDelayUs, myDelayMs, myDelayMsUntil to be used in my tasks and they will let you do the same thing as delay, but FreeRTOS friendly :-)

Good luck, Hope this helps!

//**************************************************************************
// Can use these function for RTOS delays
// Takes into account processor speed
//**************************************************************************
void myDelayUs(int us)
{
  vTaskDelay( us / portTICK_PERIOD_US );  
}

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

void myDelayMsUntil(TickType_t *previousWakeTime, int ms)
{
  vTaskDelayUntil( previousWakeTime, (ms * 1000) / portTICK_PERIOD_US );  
}
Robokishan commented 5 years ago

but while i am using esp32 freertos it is very easy to use delay function isn't it has to be true for samd21 also. can we modify or overwrite the delay function for arduino source code ?? because we have used delay function all over the code base we couldn't just change all the delay function. can we just override it ?

BriscoeTech commented 5 years ago

What esp32 FreeRTOS repository are you using? Im interested in taking a look at it. I have mixed feelings and not sure its as easy as you think to just overwriting the delay function. It feels like a quick fix and not the correct solution to the problem your having. I'm interested in seeing how your esp FreeRtos implemented this, because it may actually be the esp32 arduino core delay implementation is surprisingly thread safe, when the samd21 is not, and was never intended to be. The arduino standard never makes any claims that Delay is thread safe, its implemented different ways from microcontroller to microcontroller.

In my opinion, if you want to make cross platform RTOS code, I would implement your code to use the FreeRtos delays. That way it does not matter what hardware you take the code to next, it will use the thread delays correctly. The rtos libraries were made to solve the problem you are having right now going from hardware to hardware.

If your code base will always be using some sort of freertos, the best thing is to update your code base with the rtos delays. If you are making libraries that have to work with rtos and non rtos code, you guys have a problem. You would have to make your code interrupt driven, or convert the code from using delays to using the millis command, which is thread safe.

Robokishan commented 5 years ago

https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/FreeRTOS/FreeRTOS.ino

if i replace vTaskDelay with simple delay it doesn't affect try it your self its very cool.

BriscoeTech commented 5 years ago

The esp32 core is built using FreeRtos, that is why they implemented delay to be thread safe. Here is what they did:

delay implementation

void delay(uint32_t ms)
{
    vTaskDelay(ms / portTICK_PERIOD_MS);
}

The best solution for you to replace all your delays with a FreeRtos friendly delay. You accidentally made an assumption that delay is always thread safe and it is not. Replacing your delays will make your code cross platform. Also, it sounds like your code base is strongly tied to FreeRtos, there should be no reason why you cant replace the delays.

Robokishan commented 5 years ago

ok. thank you so finally we made a decision regarding controller. we removed samd from our base line controller and replaced it with esp32. but still i am curious about stm32. is it also thread safe ?