(Edit: Added updated version of Mark3, and updated the URL for the website)
Hello! Long time Arduino (and vanilla AVR) user, first time poster.
To introduce myself... In 2008 I developed FunkOS for AVR and MSP430 microcontrollers (you can still find it on sourceforge). That project saw modest success on its own- I used it in a bunch of personal projects, but really, it was more of a learning exercise to help me get into the world of RTOS development.
While FunkOS was unofficially discontinued in 2010, I never stopped playing around with RTOS concepts in my spare time, and I've spent countless hours since then researching various OS concepts, and learning how to implement features found in high-end commercial offerings.
Over the last year, I've been working on something brand new which I am incredibly proud of - and hope it might be of interest to the Arduino community as well:
Mark3 is an open-source, object-oriented RTOS built from scratch, written entirely in C++.
Features of Mark3 include:
-Extremely easy-to-use API; Kernel initialization with two threads in six lines of code.
-Fully-deterministic scheduler with 8 priority levels and unlimited threads per priority ( number of threads limited by available RAM)
-Round-robin scheduling within each priority level, with customizable thread quanta
-Tickless/Asynchronous kernel design
-Unlimited number of high-precision timers and thread-sleeps (thanks to tickless kernel design)
-Binary & Counting Semaphores
-Mutexes with priority inheritance and recursive lock support
-Robust IPC based on message queues
-High-resolution profiling timers
-Device driver API
-Interrupt-driven, buffered UART driver for AVR
-Meticulous documentation, including a manual integrated with the doxygen docs (including HTML and a 420-page PDF)
-Full kernel validation test suite, including unit-tests and cycle profiling tests
-Large set of examples
While the kernel is the party-piece of Mark3, I've also developed a fairly large library of middleware to support it, including:
-Thread-safe fixed-block heaps
-Lightweight string/memory-manipulation library
-Raster graphics library including bitmap font rendering, and font creation utilities
-Event-driven GUI framework, including a base set of widgets
-Yet another bootloader
-Shell support library
-Filesystem development framework (Nice Little FileSystem - NLFS)
-A DCPU-16 virtual machine
-Support for PSX joysticks
-HID and graphics devices over serial
Some of the middleware needs a bit more work (or at the very least, examples), but the kernel itself is rock-solid and good to go. At this point, I would have no reservations about putting it up against the likes of FreeRTOS, uCOS, or ThreadX any day of the week.
And, because of how it's been designed (C++/GCC/AVR), porting it to ATMega-based Arduino was trivial - I basically copied the source and headers into a folder, added a keywords.txt file, and that was that.
While I intend for Mark3 to be a stand-alone offering for AVRs, I've become quite interested in making (at least) the kernel available as an Arduino library. Aside from myself, would anybody be interested in seeing this code make its way over?
In the meantime, if anyone is interested in checking out the code as-is, you can check out the SVN repo from google code at http://www.mark3os.com
EDIT:
Alright, since it was so easy to port I just went ahead wrote a script to cut Arduino releases.
See the attached zip file containing the Mark3 library. Simply unzip and copy the Mark3 folder to the libraries folder in your Arduino install path.
The zip contains the kernel source, along with full PDF and HTML documentation for the kernel (taken from the doxygen docs).
There are some good examples in the docs, but here's a quick one showing how to configure the kernel with two threads, performing thread sleeps, and using the UART to alternate printing of the words "Off" and "On" every 200 ms.
#include <kernel.h>
#include <thread.h>
Thread idle_thread;
Thread app_thread;
uint8_t app_stack[192]; // buffers used as stacks for threads
uint8_t idle_stack[192];
void idle_func(void *param_);
void app_func(void *param_);
int main(void)
{
Kernel::Init();
app_thread.Init(app_stack, 192, 1, app_func, 0);
idle_thread.Init(idle_stack, 192, 0, idle_func, 0);
app_thread.Start();
idle_thread.Start();
Kernel::Start();
// !! Kernel::Start() Does not return, it starts the threads
return 0;
}
void app_func(void *param_)
{
// application thread code goes here
Serial.begin(57600);
while(1)
{
Thread::Sleep(200);
Serial.write("On\n");
Thread::Sleep(200);
Serial.write("Off\n");
}
}
void idle_func(void *param_)
{
// idle thread/LPM code goes here
while(1)
{
}
}
Mark3_arduino_r179_20141016.zip (102 KB)