ChibiOS/RT RTOS trial port for Arduino

I enabled CH_DBG_FILL_THREADS in chconf.h and hacked the chBlinkPrint example to check the stack usage after it ran for a while.

The result is that ChibiOS allocates a minimal stack size of 69 bytes and the argument to WORKING_AREA is added.

For the LED blink thread 133 = (69 + 64) bytes were allocated and 102 bytes were unused for a max use of 31 bytes.

For the print thread 269 = (69 + 200) bytes were allocated and 198 were unused for a max use of 71 bytes.

Here is the hacked sketch, type any character to trigger the stack use print.

// Simple demo of three threads
// LED blink thread, print thread, and idle loop
#include <ChibiOS.h>
#include <util/atomic.h>
const uint8_t LED_PIN = 13;

volatile uint32_t count = 0;
//------------------------------------------------------------------------------
// thread 1 - high priority for blinking LED
// 64 byte stack beyond task switch and interrupt needs
static WORKING_AREA(waThread1, 64);

static msg_t Thread1(void *arg) {
  pinMode(LED_PIN, OUTPUT);
  while (TRUE) {
    digitalWrite(LED_PIN, HIGH);
    chThdSleepMilliseconds(50);
    digitalWrite(LED_PIN, LOW);
    chThdSleepMilliseconds(150);
  }
  return 0;
}
//------------------------------------------------------------------------------
// thread 2 - print idle loop count every second
// 200 byte stack beyond task switch and interrupt needs
static WORKING_AREA(waThread2, 200);

static msg_t Thread2(void *arg) {
  Serial.begin(9600);
  while (TRUE) {
    Serial.println(count);
    chThdSleepMilliseconds(1000);
  }
  return 0;
}
//------------------------------------------------------------------------------
void setup() {
  // initialize ChibiOS with interrupts disabled
  // ChibiOS will enable interrupts
  cli();
  halInit();
  chSysInit();
  
  // start blink thread
  chThdCreateStatic(waThread1, sizeof(waThread1),
    NORMALPRIO + 2, Thread1, NULL);
    
  // start print thread
  chThdCreateStatic(waThread2, sizeof(waThread2),
    NORMALPRIO + 1, Thread2, NULL);
}
//----------------------------------
size_t get_thd_free_stack(void *wsp, size_t size)
{
  size_t n = 0;
#if CH_DBG_FILL_THREADS
  uint8_t *startp = (uint8_t *)wsp + sizeof(Thread);
  uint8_t *endp = (uint8_t *)wsp + size;
  while (startp < endp)
    if(*startp++ == CH_STACK_FILL_VALUE) ++n;
#endif
  return n;
}
//----------------------------------------------------------------
void stackUse() {

  size_t n1 = get_thd_free_stack(waThread1, sizeof(waThread1));
  size_t n2 = get_thd_free_stack(waThread2, sizeof(waThread2));
  cli();
  Serial.print(sizeof(waThread1) - sizeof(Thread));
  Serial.write(',');
  Serial.println(n1);
  Serial.print(sizeof(waThread2) - sizeof(Thread));  
  Serial.write(',');
  Serial.println(n2);
  
  while(1);
}
//------------------------------------------------------------------------------
// idle loop runs at NORMALPRIO
void loop() {
  // must insure increment is atomic
  // in case of context switch for print
  ATOMIC_BLOCK(ATOMIC_FORCEON) {
    count++;
  }
  if (Serial.available()) stackUse();
}