RTOS for AVR

Go To Last Post
557 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The original csRTOS author (me!) is alive and well.

By chance today I stumbled across the AVR Freaks thread about csRTOS. I was amazed (and pleased) to find that there was so much activity relating to my little CC contest entry several years ago.

Apologies to anyone who tried to contact me by using the email address in the CC entry - it is long gone. My current email is glen@worstell.com

FYI, here is some info and some of my thoughts:

Thanks to all who have contributed and in particular to 'curtvm'. It appears that he has made a better version that has changed so much that it has a new name (seems proper to me). He has given me sufficient credit, IMHO, by putting a reference to my original work near the top of his web page.

Someone posted something on the CC link (I wonder how they did that) that was a most unhelpful comment. It should have had a bit of an explanation about the apparent bug in the original code. Anyway, some of the posts here have indicated that there really was a bug, and I think I know of an easy fix.

I won't work on it now, tho, until I have read and understood curtvm's 4AvrOS, because I think I might like it better.

Hardware is much cheaper and more feature-rich than it was 5 years ago. For little more than the cost of an 8 bit AVR you can get a 32 bit ARM Cortex or an AVR32. Unless you are using large quantities of parts it might be easier to just use one of these instead of a much more limited 8 bit processor.

Even for a big part, tho, something like csRTOS or 4AvrOS might sometimes be better because these simple multitaskers make coding easier for simple projects. Large projects might benefit from a pre-emptive RTOS, which is quite feasible on a part with 32KB ram rather than 128 or 256 bytes, the target market for csRTOS.

The first implementation of csRTOS was for a TI MSP430, and I ported it to a couple of other micros. The port to the AVR was done because of the CC contest, not because I needed it. I did a few projects using csRTOS on the MSP but never did do one for the AVR (except the sample code in the CC entry).

Thanks (again) to Salvo/Pumpkin for some ideas based on their commercial cooperative RTOS (and I recommend that you google on that if you have a serious high-volume project).

Thanks to Adam Dunkels who sent some helpful emails way back when. Thanks also to (sorry - I forget the name) who corresponded with me about his port to a PIC.

My current, just-started project is to write an article for and make a presentation to the homebrew robotics club of Mt. View, CA. The topic is something like 'Moving up from 8 bit micros' or maybe 'my next micro'. It will be a comparison of the MSP430, the ARM Cortex, and the AVR32, from the point of view of a hobbyist who cares about the cost of development software and hardware and suitability for robotic use. I'll briefly discuss why I've narrowed my choices down to these three, rejecting the PIC24/dsPIC, the Renesas and Freescale lines, the Zilog Zeno, and others.

As a benchmark used not only for performance comparisons but also to help in tool evaluation I plan to port csRTOS or 4AvrOS (or something similar) to the 3 micros, along with an application that will have a few tasks, including some serial I/O and (of course) an LED blinker.

I might use tinyOS, another cooperative RTOS (but one that is rather more complicated than csRTOS). When I have something finished I'll post the AVR32 code and docs on the proper AVR Freaks thread.

Finally, note that the AVR32 is high on my list partly because of the excellent hobbyist support from Atmel, with reasonably good free development software, and AVR Freaks, an excellent user-driven forum.

cheers to all,
Glen.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

It will be a comparison of the MSP430, the ARM Cortex, and the AVR32, from the point of view of a hobbyist who cares about the cost of development software and hardware and suitability for robotic use. I'll briefly discuss why I've narrowed my choices down to these three, rejecting the PIC24/dsPIC, the Renesas and Freescale lines, the Zilog Zeno, and others.

What a shame the 8bitter in there wasn't an AVR - an article like that would be great for the Tutorial Forum here as I think a lot of people think there's a "complexity block" between 8bit and 32bit. However the more complex Xmega AVRs are maybe moving 8bit closer to 32bit anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Glen, thanks for the info.

Early on I discovered that the compiler was 'unaware' of the task switching, and didn't 'know' registers may have changed when returning to the task. I then used the idea from protothreads to keep the compiler 'in the know', with the added benefit of no asm. I think there may be an easy fix ('memory'), but have never tried it.

I now have a much simpler 'os', which doesn't have priorites or any other 'complications' (I call it 'Little Round Robin Threads'). I'm not sure priorities were ever necessary for my use, and I think the time deciding what task to run could be better spent just running tasks. Its a cross between 4AvrOS and protothreads.

I am also interested in AVR32/ARM Cortex, so keep us informed on your current project.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not to shamelessly plug my own project... but you might find some value in the FunkOS kernel that I wrote a few months back. It was designed primarily with ease of use in mind, and has quite thorough documentation and many demo apps. While not as widely known as the other AVR kernels out there, I think it's probably among the easiest to understand from a getting started point of view. But I may be biased ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,
I'm using 4avrOS from http://www.mtcnet.net/~henryvm/4... and am having problems figuring out a way to completely restart a task from within another task.

Wrote a small example to illustrate my problem:

#include 
#include "Tasks.h"                           // needs to be before 4AvrOS.h
#include "4AvrOS.h"

static unsigned char task_1_state = 1;

void init_mystuff(void){

}

void do_something(){

}

void do_something_else(){
	
}

BEGIN_TASK(task1_Task)	

	switch(task_1_state)
	{
		case 1:
		{
			do_something();
			osWAIT(200);
			osWAIT(200); //gets called!
			osWAIT(200); //gets called!
		}
		break;

		case 2:
		{
			do_something_else();
			osWAIT(200);
			osWAIT(200);
			osWAIT(200);
		}
		
		break;

		default:
		break;
	} 

END_TASK

BEGIN_TASK(task2_Task)

	//wait a little so task 1 has started executing state 1
	osWAIT(10);

	//I try to change task 1s state and "restart" it
	osDISABLE_TASK(task1_Task);
	task_1_state = 2;
	osENABLE_TASK(task1_Task);
	osSUSPEND;
	
END_TASK

When I run this example I didn't expect all the osWAIT(200) in task1 to get called. I thought the osDISABLE_TASK in task2 would "reset" the task1 completetly, but it seems that's not the case.

How can I reset / force a task to start "from the top"?
Thank you in advance,
/D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
osDISABLE_TASK in task2 would "reset" the task1 completetly, but it seems that's not the case.
A task will always start where it left. You are in a loop (the task), and any time it goes back to the scheduler via osSUSPEND/osWAIT/osYIELD/etc., its current location is saved where you will return when the task runs again.

In your case, it is returning back to inside the switch statement, and the switch is not tested again until the task completes the 'current' switch.

You could make some macros to clear 'gl' (in task struct), which would 'reset' the task, but a better idea would be to split up the task into 2 tasks. I'm sure there are other ways to take care of this without the switch/case, but it seems best if a task does specific jobs, and is mostly in charge of itself (not having other tasks reset it, or determining where it should execute inside the task).

Pages