I decided to try the ChibiOS/RT RTOS on a m328 Arduino since I had good luck with it on ARM Cortex M3 processors.
http://www.chibios.org/dokuwiki/doku.php?id=startI selected a striped down version and packaged it as an Arduino library. The results are impressive for a preemptive kernel on avr.
The test sketch below runs two threads and is designed to check the time for one thread to signal another thread and do a context switch.
The lower priority thread, thread2, toggles an LED so I can determine the time for digitalWrite and then uses a semaphore to activate a higher priority task that turns the LED off.
The total time for the semaphore and context switch is 15 usec. This is much faster than other RTOSes I have tried on the Arduino. It is more than three times as fast as a popular popular RTOS that forbids publishing benchmarks.
The total flash used by this sketch with 0022 is 2972 bytes.
// scope test to determine ChibiOS context switch time
#include <ChibiOS.h>
const uint8_t LED_PIN = 3;
// semaphore to trigger thread2
Semaphore sem;
//------------------------------------------------------------------------------
// thread for LED off
static WORKING_AREA(waThread1, 64);
static msg_t Thread1(void *arg) {
while (TRUE) {
chSemWait(&sem);
digitalWrite(LED_PIN, LOW);
}
return 0;
}
//------------------------------------------------------------------------------
// thread 2 - cause context switch to thread 1 with semaphore
static WORKING_AREA(waThread2, 64);
static msg_t Thread2(void *arg) {
while (TRUE) {
// toggle LED to get time for digitalWrite
digitalWrite(LED_PIN, HIGH);
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_PIN, HIGH);
// signal to switch to thread1 to get context switch time
chSemSignal(&sem);
// wait 10 ms
chThdSleepMilliseconds(10);
}
return 0;
}
//------------------------------------------------------------------------------
void setup() {
pinMode(LED_PIN, OUTPUT);
halInit();
chSysInit();
chSemInit(&sem, 0);
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 2, Thread1, NULL);
chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO + 1, Thread2, NULL);
while(TRUE){}
}
void loop() {
// never called
}