Replies: 3 comments
-
I've had a detailed look at this and there is a fundamental issue with the design of the Watchdog Timer in the older generation of ATmega devices. In the ATmega128, for example, there is no interrupt capability provided by the WDT. Therefore, the WDT is not suitable for use as the System Tick for a RTOS. In contrast, in the ATmega328p, for example, the WDT can trigger an interrupt (without triggering a RESET), which we can use to provide the System Tick. It is very easy to create an alternative RTOS System Tick, using one of the other Timers present on the ATmega128, for example. But, that is not relevant for this generalised library. I've gone out of my way to remove any hardware configuration restraints for all the generally available Arduino AVR boards, so it wouldn't be appropriate to put specific constraints into this library. As you'd be aware, the Arduino environment pre-configures all the regular Timers for its own purposes, so it is not possible to use one of these Timers for a RTOS System Tick, without breaking something else in in the Arduino environment, or developing your own special core. Take a look at the |
Beta Was this translation helpful? Give feedback.
-
Thanks for the detailed answer. I understand that this hardware difference makes the older generation of AVRs difficult to implement in this RTOS library. While I still got your attention; I'm trying to understand the use of semaphores and how they work, so I've created an example project just to ply around with it. The LED (attached to pin 0) should toggle if the button (attached to pin 1) is pressed.
#include <Arduino_FreeRTOS.h> // RTOS
#include <semphr.h> // Semaphores
// Declare a semaphore handle
SemaphoreHandle_t sem;
// Define pins
uint8_t myLed = 0;
uint8_t myButton = 1;
void setup()
{
Serial.begin(9600);
// Initialize semaphore
sem = xSemaphoreCreateMutex();
// Create the button task with priority 1
xTaskCreate(
buttonTask // Function that implements the task.
, (const portCHAR *) F("buttonTask") // A name just for humans
, 150 // This stack size can be checked & adjusted by reading the Stack Highwater
, &myButton // Parameter passed into the task (use NULL if not using parameter)
, 1 // Priority, with 3 being the highest and 0 being the lowest
, NULL);
// Create the led task with priority 2
xTaskCreate(
ledTask // Function that implements the task.
, (const portCHAR *) F("ledTask") // A name just for humans
, 150 // This stack size can be checked & adjusted by reading the Stack Highwater
, &myLed // Parameter passed into the task (use NULL if not using parameter)
, 2 // Priority, with 3 being the highest and 0 being the lowest
, NULL);
// Print stack info
Serial.print("Occupied stack space: ");
Serial.print(uxTaskGetStackHighWaterMark(NULL));
Serial.println(" bytes");
// Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started after setup()
}
void loop()
{
// Empty loop, everything is handled by the tasks
}
// Blink task
void buttonTask(void *pvParameters)
{
// Fetch passed parameter
uint8_t buttonPin = *((uint8_t*)pvParameters);
pinMode(buttonPin, INPUT_PULLUP); // Set ledPin as input with pullup
while(1)
{
if(digitalRead(buttonPin) == 0)
{
vTaskDelay( 100 / portTICK_PERIOD_MS ); // wait 100 ms
xSemaphoreGive(sem); // Give the LED task premission to run
}
}
}
// Blink task
void ledTask(void *pvParameters)
{
// Fetch passed parameter
uint8_t ledPin = *((uint8_t*)pvParameters);
pinMode(ledPin, OUTPUT); // Set ledPin as input with pullup
while(1)
{
xSemaphoreTake(sem, portMAX_DELAY); // Wait for the semaphore to be available
digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle LED
}
} |
Beta Was this translation helpful? Give feedback.
-
FreeRTOS has a few different types of Semaphores, which have different applications. Lots of good info at Richard Barry's site. Follow up there for more info. Mutex Semaphores are used to ensure MUTual EXclusion. This is the type you've created. They're usually used to protect a piece of hardware. They need to be taken, and then are given back, usually by Tasks competing to access the thing being protected (say a serial port). Binary semaphores are used to trigger coordination between tasks, or between an interrupt and a task. A binary semaphore need not be given back once obtained, so task synchronisation can be implemented by one task/interrupt continuously 'giving' the semaphore while another continuously 'takes' the semaphore. Mutexes and binary semaphores are very similar but have some subtle differences: Mutexes include a priority inheritance mechanism, binary semaphores do not. This makes binary semaphores the better choice for implementing synchronisation (between tasks or between tasks and an interrupt), and mutexes the better choice for implementing simple mutual exclusion. In your example, you'd typically have the button on an Interrupt, which detects the Pin Change, writes a status byte, and then gives the Semaphore before finishing. The Task would be blocked waiting to take the semaphore, and when it gets the semaphore it would set the lamp according to the status byte. Once the Task is finished it would wait to take the binary semaphore again. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi!
I'm in the process of learning to use and understand RTOS'es, and I thought it would be wise to start with your library.
In the last year or so I've added Arduino support for a whole bunch of AVRs, and some of them are getting quite popular. Especially the "older" AVRs can be bought for next to nothing from China (less than a $ the ATmega128), and here my problem comes.
The "older" AVRs (ATmega8/16/32/64/128) have some minor changes to their register names that don't make them 100% interchangeable with the newer ones (ATmega164/324/328 etc). This makes them incompatible with your RTOS library.
Below is the compilation error for the Blink_analogRead example, compiled for ATmega128. It seems like it is some kind of WDT issues. Is this something you'd look into? Thanks! 😃
Beta Was this translation helpful? Give feedback.
All reactions