Jump to content
NicholasLindan

CoRTOS: An open source minimalist RTOS

Recommended Posts

CoRTOS is a Cooperative Real Time Operating System for bare-metal applications.

Its advantages over other systems are that it is fully documented with a manual and examples, is easy to understand and use and is astonishingly simple: The kernel is just 16 lines of C.  The CoRTOS module compiles to ~200 bytes of code.  The system includes optional modules implementing delays, timers, messaging, mutexes and signaling. It is intended for smaller microprocessors, such as the MSP430, Cortex M0+, AVR and PIC24, and for smaller systems of maybe a dozen tasks.

CoRTOS is not a task scheduler.

CoRTOS works like any other RTOS. Tasks schedule themselves, picking up where they left off after making a call to the OS.

Please feel free to send questions to nolindan@ix.netcom.com

The intended audience includes:
• Those needing a small footprint RTOS;
• Students learning about real time systems;
• Makers wanting to program "close to the metal"

Features

  • World's simplest RTOS

CoRTOSV1d.zip

Share this post


Link to post
Share on other sites

CoRTOS is, possibly, the world's simplest RTOS.  After 35 years of writing RTOS systems I had the thought: "How simple can you make it?"

It is a naked system meant for use in product, teaching and maker applications.  The CoRTOS kernel compiles to ~200 bytes of code.  You add features as needed: delays, mutexes, signaling, messaging - each feature adding, again, about 200 bytes.  The development environment is CCS and GCC or the equivalent.  It has been adopted in teaching environments as It is easy to trace through the code to see what is going on behind the scenes.  It is well documented with a 30 page manual and extensive source code comments - every attempt has been made to make it as straightforward as possible.

My understanding of Energia is that it is an Arduino-like environment using TI-RTOS and runs on Launch-Pad boards.  Code is interpreted rather than compiled.

There really isn't a comparison - a bit like comparing a crate engine to an automobile.  But if you only need an engine...

Share this post


Link to post
Share on other sites

@NicholasLindan

Do you have any blog posts or example projects that you can show case for us?

It's kind of like a new flavour of ice cream - "you are not sure that you want to get it if you don't know what it tastes like so I'll just take vanilla".

Share this post


Link to post
Share on other sites
8 hours ago, NicholasLindan said:

It is a naked system meant for use in product, teaching and maker applications.  The CoRTOS kernel compiles to ~200 bytes of code.  You add features as needed: delays, mutexes, signaling, messaging - each feature adding, again, about 200 bytes.  The development environment is CCS and GCC or the equivalent.  It has been adopted in teaching environments as It is easy to trace through the code to see what is going on behind the scenes.  It is well documented with a 30 page manual and extensive source code comments - every attempt has been made to make it as straightforward as possible.

Interesting chunk of code, however it doesn't seem like you've invested much effort in your msp430 port or cross platform compatibility. The code only seems to attempt only one msp430 mcu (msp430fr6989).  As there is no project file for CCS or a makefile, I created an empty CCS project using the TI C compiler for an msp430fr6989.  I imported the CoRTOSblinkyMSP.c source and all the headers. It has a bunch of obvious errors.  Have you tried to compile that file?  It doesn't compile, at least with CCS 7 on ubuntu.

Hint 1: you can't use msp430-elf-gcc

Hint 2: Edit CoRTOSuP.h and make the processor uP_MSP430 the default 

Hint 3: Don't try this on a files system that is case sensitive. The source code and files provided uses a mix of upper and lower case. You need to fix the incorrect file name references or rename the files to match the names.

 

First batch of errors:

Description    Resource    Path    Location    Type
#150 variable "task_stack_size" has already been initialized    CoRTOStask.c    /cortos    line 33    C/C++ Problem
.. defined multiple times in the source


#1965 cannot open source file "msp430FR6989.h"    CoRTOSkernel.c    /cortos    line 18    C/C++ Problem
needs to be msp430fr6989.h" .. probably should be just <msp430.h>


#20 identifier "t" is undefined    CoRTOSblinkyMSP.c    /cortos/apps    line 202    C/C++ Problem
I don't see this declared anywhere, I'm assuming you meant "n" not "t"

 

#20 identifier "tn" is undefined    CoRTOSblinkyMSP.c    /cortos/apps    line 208    C/C++ Problem
not sure what you meant to pass to resume_task() .. guessing it is also "n" ?

 

After I addressed those problems, I changed the code around so I could run it on an msp430fr5969 launchpad. The release build results in a multi-tasking blinky app that uses about 1k of code and 200 bytes of ram.  That seems to work, maybe I'll try a little more tomorrow.

-rick

 

Share this post


Link to post
Share on other sites

Rick - thanks very much for the review and bug catch.

I have attached a V1d01 zip file with updates.

There are two "Blinky" demonstration projects.  I don't know if you made one or (as it seems) both.

  • CoRTOSblinkyxxx.c is a one-file project that is specific to a processor.
  • CoRTOSsuperblinky.c is a more elaborate demonstration that links into CoRTOS modules and is processor independent.

In both cases, though, the processor is specified in CoRTOSuP.h.

Yes, it isn't universal to the all the MSP430 variants.  This isn't my day job, so some of the work will just have to be done by the users.

On the errors you had with compilation:

  • #20 identifier "t" is undefined (line 202); identifier "tn" is undefined (line 208) CoRTOSblinkyMSP.c
    •  CoRTOSblinkyMSP.c was --- well, damned if I know what happened.  A corrected version is attached - the corrected version now mirrors the example in the manual.
  • #150 variable "task_stack_size" has already been initialized CoRTOStask.c /cortos line 33
    • The file "CoRTOStask.c" is a placeholder to use when making your own system.  Just eliminate it from the directory when making the CoRTOSsuperblinky demonstration project.
    • The various CoRTOSblinkyxxx.c files should also be removed from the directory if you are making superblinky or you will end up with two main()'s.  CoRTOSblinkyMSP.c file is only used with the blinky example/tutorial in the manual, it only needs the CoRTOSuP.h and CoRTOScomdefs.h files.
    • I have added some notes on this to the manual.
  • #1965 cannot open source file "msp430FR6989.h" CoRTOSkernel.c /cortos line 18
    • This hasn't been flagged on my system, but my system is Windows rather than a Linux variant.  Indeed, the file name is msp430fr..., the caps are likely due to copying the part# from the TI box/literature.  It has been changed to all lower case in the source code.
    • I have a recollection that using <msp430.h> gave some problems, this may be from some time ago and has since been resolved.

A lot of people don't like the file naming convention.  I use it because, after so many years, I have an almost infinite number like function/name files.  Please feel free to strip off the CoRTOS prefix and also to edit out the processor specific code that isn't for your processor.

Again, thanks for your help.

 

 

CoRTOSV1d01.zip

Share this post


Link to post
Share on other sites
23 hours ago, zeke said:

It's kind of like a new flavour of ice cream - "you are not sure that you want to get it if you don't know what it tastes like so I'll just take vanilla".

Well, it's a really small container of ice cream, almost the size of the free sample spoonful you might get with other RTOS's.  Dive in and think "Peach."

For those who don't want to do the download, here is the kernel:

#include "common_defs.h"
#include "CoRTOSkernel.h"
#include "CoRTOStask.h"

uint8_t current_task;

static uint16_t sp_save [number_of_tasks];
static uint16_t starting_stack [number_of_tasks];
static boolean start_from_beginning [number_of_tasks];
static boolean suspended [number_of_tasks];

void relinquish (void) {
   asm volatile ("NOP":::"r2","r3","r4","r5","r6","r7","r8","r9","r10",\
      "r11","r12","r13","r14","r15","r16","r17");
   sp_save[current_task] = _SP;
   while (true) {
      do {
         if (++current_task == number_of_tasks) current_task = 0;
      } while (suspended[current_task] == true);
      if (start_from_beginning[current_task] == true) {
         start_from_beginning[current_task] = false;
         _SP = starting_stack[current_task];
         start_addresses[current_task] ();
         suspended[current_task] = true;
         start_from_beginning[current_task] = true;
      }
      else {
         _SP = sp_save[current_task];
         return;
      }
   }
}

void suspend (void) {
   suspended[current_task] = true;
}

void resume_task (uint8_t tn) {
   suspended[tn] = false;
}

void start_CoRTOS (void) {
   uint8_t tn;
   uint16_t spv;

   spv = _SP;
   for (tn = 0; tn < number_of_tasks; tn++) {
      starting_stack[tn] = spv;
      spv -= task_stack_size[tn];
      start_from_beginning[tn] = true;
      suspended[tn] = false;
   }
   start_from_beginning[0] = false;
   current_task = 0;
   start_addresses[0] ();
}

The OS proper is the function relinquish() - about 15 lines of executable code.

Share this post


Link to post
Share on other sites
On 5/17/2018 at 5:02 PM, NicholasLindan said:

My understanding of Energia is that it is an Arduino-like environment using TI-RTOS and runs on Launch-Pad boards.  Code is interpreted rather than compiled.

There really isn't a comparison - a bit like comparing a crate engine to an automobile.  But if you only need an engine...

You seem to misunderstand Energia. It is based on the Arduino IDE source code (java based), with customized c++ cores that work with a variety of different TI processors. The msp430, arm cortex, and C2xxxx are all represented. There is no interpreted mcu code, it is C/C++ source that implements the Arduino API. It gets compiled using a cross compiler appropriate for the architecture selected (msp430-gcc, arm-none-eabi-gcc etc) and runs on Windows, Mac, and linux.

The TI RTOS (previously called SYSBIOS) has been available for a long time and is fully documented. http://www.ti.com/tool/TI-RTOS  Energia implements the TI RTOS in a novel way. You create tasks by creating a new tab in the Energia IDE that contain a setup() and loop() for each task. It automatically  uses those tabs to start the tasks.  However, that is just skimming the surface.  See more info here http://energia.nu/guide/multitasking/  Granted the multitasking implementation hasn't been done for the msp430 chip, however it would be possible.

-rick

Share this post


Link to post
Share on other sites
9 minutes ago, Rickta59 said:

There is no interpreted mcu code, it is C/C++ source that implements the Arduino API

 

I make no claim to Energia mavenship.  I was under the impression that the user's code was interpreted - it seems that is not the case.

Share this post


Link to post
Share on other sites
18 hours ago, NicholasLindan said:

Rick - thanks very much for the review and bug catch.

I have attached a V1d01 zip file with updates.

Still an issue with upper / lower case naming conflicts:

diff -r ./fixed/CoRTOSmessage.c ../../Downloads/cortos_d1/CoRTOSmessage.c
18c18
< #include "CoRTOSuP.h"
---
> #include "CoRTOSup.h"

the file is named 'CoRTOSuP.h' the code uses 'CoRTOSup.h'
 

Share this post


Link to post
Share on other sites

Some general first impressions about CoRTOS:

  • I can spell yield() but I have to ask merriam-webster how to spell relinquish()
  • <msp430.h> would allow people to use whichever MCU they select in CCS without having to edit the source files
  • #include <stdint.h> is a better way to grab uint8_t and friends
  • #include <stdbool.h> is a better way to grab true, false and bool
  • GPL isn't the best license for RTOS code. Even the TI-RTOS (SYS/BIOS) is BSD. FreeRTOS is MIT. nuttx is BSD. RIOT is LPGL. mbed-rtos is MIT.
  • it would be nice if the code would compile with both msp430-elf-gcc and the TI cl430 compiler. inline asm is easier with msp430-elf-gcc and would match your other platforms
  • Although I haven't tried, it doesn't seem like this code would work properly with large model code (where registers are 20 bits instead of 16 bits) look at switching to uintptr_t and intptr_t . uintptr_t is either int16 or _int20 depending on the compiler mode selected. (this would help with 32bit stuff too uintptr_t is uint32_t there)
  • MSP430s have extensive low power features. It isn't just one sleep mode. These modes rely on the SR being properly saved and restored, not sure how this fits into the tasking code. Look into using LPM1, LPM3, etc...
  • using uint8_t results in slower code on an msp430 when you are really just trying to use a natural integer. A locally declared uint8_t is still going to use 2 bytes on the stack.
  • UpperAndLowerCaseIsTediousToReadAndTediousToTypeAndRememberWhenToSwitchCase

-rick

Share this post


Link to post
Share on other sites

Rick:

I know that every time I grab code I edit it so it conforms to my needs, prejudices and sensibilities -- that makes the code mine, in a sense, and less foreign - and as I make the changes I get to mutter under my breath about the original author: "Bloody fool, what does he think he is doing."  I expect any one using CoRTOS will want to and have to change it in some way and utter their own mutterings.

So please, make changes to your heart's content with the source.  In any work, everyone finds something to disagree on.  What some find terminally annoying others find full of virtue. I can't please everyone and I'm not going try.  That path is the surest way to please no one.

The Shakers would put a purposeful gouge in their furniture lest their attempt at perfection offend God.  I leave plenty of gouges in my work.

As the manual states: "Worth price charged."

Nicholas

Share this post


Link to post
Share on other sites

Sure I understand that. I'm just passing along my biased observations :) 

What I've seen with the msp430 and RTOS support in general is this. People/groups make a simplistic stab at supporting the msp430 and then just as quickly abandon the effort.  It is hard to compete with the fully featured TI-RTOS/SYS-BIOS code. TI-RTOS is free with a BSD license. TI actually supports it on their e2e.ti.com forum.  However, it is a beast. TI-RTOS tames you, you don't tame it. I've heard it is slow and bloated on the msp430.  It uses an arcane set of TI custom command line based tools that force you to conform.  I don't want to be tamed.  In my opinion, TI is good with hardware and software is an afterthought that some marketing guy needs to be able to check boxes on a specification sheet.

I think there is a niche for a small and simple RTOS, not unlike what you have posted, that actually fully takes advantage of the lower power features of the msp430 chips.  However,  it would be easier to pass on fixes and identify real software issues if you put the source code on some public repository. That is assuming your goal is to get a group of people actively using the code.  It might eliminate the muttering of 100 people making the same fix in some snapshot in time of a zip file you randomly post on various web forums.

Other users here have posted some simple tasking code. However, there is always some catch or no followup.

This guy posted some promising code. Sadly it was writtten to work only with the $1500 IAR compiler and after he posted it there wasn't any follow up.

FreeRTOS supposedly works on the msp430 chips.  

So don't think I'm discouraging your efforts. I applaud it. Seems like a good first start.  If you want feedback, I'll provide it.

Share this post


Link to post
Share on other sites

The code is on Sourceforge https://sourceforge.net/projects/cortos-simple/

As far as being a "good first start" - well, I've been doing this for an awfully long time, as the picture of the old fart on the left should attest.  Started with the 8008 in 1974...  It's more of a "last start."

If someone is doing something serious with the code I would be more than happy to help with support.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×