[TUT][SOFT][CODE]FreeRTOS for ATmega2560/1

22 posts / 0 new
Last post
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have had requests from several folks for my version of FreeRTOS for the ATmega2560. I had always intended to take the latest) version of FreeRTOS, apply my changes, and submit it to the FreeRTOS group as another supported AVR processor, but I simply haven't gotten around to it.

Instead, I'm posting the code here, free for anyone's use. Please note that *all* the licenses from FreeRTOS apply to this version. Also, you get the same support, which is you can ask me for help and I may or may not help, depending on the request and my work load.

This code is based on FreeRTOS 4.8.0, although the grand majority of the changes are fairly simple and would be easy to merge with the latest version of FreeRTOS.

I have not included the co-routine stuff, since I do not use it.

There is a new switch, USE_RTC_TIMER which switches the RTOS timer from a dedicated timer (timer 0) to the RTC-crystal driven timer (timer 2). Your tick is a little longer than 2 mS, but you now have a single OS/RTC timer instead of two timers used for the same task of keeping track of time.

I've included the second level heap manager, heap_2.c, since I've added a routine to report memory usage for each task and for the total managed help.

Note that the task list function has had sprintf patched out in favor of itoa() and ltoa(). I did this because I don't like the added overhead of sprintf.

One of the problems with the ATmega2560/1 series is that GCC uses a 16-bit word to keep track of location. Most of the time this is corrected in the loader, but jump tables and function pointers have trouble with the upper half of the flash memory. (Keep in mind that the AVR addresses instructions by a word pointer so you have direct access to 128 Kbytes of flash. That's exactly half of the total 256 KBytes in the ATmega2560/1).

Since I want to be sure that the task stack initialization is simple, I require that all user-defined task routines reside in lower flash memory. I do that by modifying the portTASK_FUNCTION_PROTO macro to put the task function into the .task linker section. The custom script linker_script.x contains the special section .task located before the main code section.

For the same reason, my command handler defines the following macro:

#define COMMAND_HANDLER   __attribute__ ((section (".fptr_target")))

The .fptr_target section, like .task, is set up before the main code section. I use it in the prototypes of my command routines, like:

CmdError
CmdUnimplementedCommand( CmdPacket* pCmdPkt ) COMMAND_HANDLER;
/*---------------------------------------------------------------------------*\
Usage:
	result = CmdUnimplementedCommand( pCmdPkt );
Description:
	Default command procedure for unimplemented commands
Arguments:
	pCmdPkt - pointer to the command packet for this command
Results:
	CMD_ERROR_FUNCTION_NOT_IMPLEMENTED - always returns this!
\*---------------------------------------------------------------------------*/

The final bit of weirdness in linker_script.x is that I have another of these "pre-main code" sections, .isr, for ISRs. I am unconvinced that this is necessary since the JMP command can easily handle jumps to the top of memory, but I put it in a pique of anger once when an ISR wasn't working and I have never taken it out.

Nonetheless, inside of the projdefs.h file you will find:

/* The following defines the section for ISRs used throughout the code.  
 * This is added to the current ISR() macro as another called argument.
 */
#define ISR_SECTION __attribute__ ((section (".isr")))

This can be appended to the list of arguments in the ISR macro like this:

ISR( SIG_2WIRE_SERIAL, ISR_BLOCK ISR_SECTION )

(Yes, there is not a comma between ISR_BLOCK and ISR_SECTION. That's a weirdity of the way the ISR macro is defined.)

That's pretty much it. I currenlty have more than 70,000 lines of code and 9 tasks running on this. I regularly use queues, semaphores and task suspension without problems.

The problems that crop up regularly are:

1 - Insufficient stack space allocated to a task. Look for this if the machine "reboots" when you don't expect it. Use the task list function to get reports on how much stack your tasks are using. Keep in mind that ISRs can fire in any task, so if you have and ISR that uses lots of RAM (bad idea), make sure your minimumSTACK_SIZE is increased to handle it.

2 - Using a non-ISR function in an ISR. This will almost always lock up the machine.

At any rate, I hope this helps folks along. Enjoy!

Stu

Attachment(s): 

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

can you post a complete project with makefile.(making two dummy tasks)
and thanks in advance for posting this

I love Digital
and you who involved in it!

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

Sorry for being silly. Found the sources (was not logged in...)

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

Hello,

I want to use freeRTOS in a Atmega1280 (The chip that is used by Arduino Mega)

What version o the code should i use? The code to 2560 or the Atmega323?

Many thanks

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

Atmega 2560 gotchas:
You might be aware also that there was a problem when a C++ constructor
had to be called for a global static object in the region of upper flash (past 128KB).
The result was something strange, and the bug was corrected around late 2009 in gcc.
I am wondering what more problems we can find related to this 16-bit addressing. it hurts that 2560 is the only in line aith more than 128KB so that few users will have chance to witness the bugs before the application gets really big and complicated.

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

Hi..
I had decided to work with FreeRTOS. I have found that new version is 6.11.
So I'm little confused: should I start with your now quite old version, or download fresh version from official site.
I have buyed I book "Using the FreeRTOS Real Time Kernel - A Practical Guide wp" to support author.
Could you please review this latest version and give us short description how to start using it, at least with mega2560 as you already do with 4.8.0.
Regards!

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

You don't post AVR studio 5 project files. So how do compile using linker script you provided? :roll:

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

I've taken Stu_San's guidance and made modifications for freeRTOS 7.1.0. The application is Arduino Mega 2560 (specifically a Freetronics EtherMega).
Code here:
http://sourceforge.net/projects/avrfreertos/
Write up here:
http://feilipu.posterous.com/ethermega-arduino-mega-2560-and-freertos
And here:
http://feilipu.posterous.com/freertos-and-libraries-for-avr-atmega
Note the 2560 portion is still incomplete, and probably faulty. But the scheduler is running so, by definition I guess it is working.

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

Thanks stu_san for your contribution. I have posted a link to this thread in the FreeRTOS Interactive! site:
http://interactive.freertos.org/entries/20870227-link-to-discussion-and-source-for-atmega2560-port

There are other contributed AVR ports there too:
http://interactive.freertos.org/forums/103473-atmel

Including this one, which seems to cover quite a lot of parts:
http://interactive.freertos.org/entries/20782373-freertos-winavr-port-for-atmega128-atmega1284p-at90can128-atmega169-atmega16

Please note, this is all contributed, rather than official code:
http://www.freertos.org/differences-between-officially-supported-and-contributed-FreeRTOS-code.html

Regards,
Richard.

+ http://www.FreeRTOS.org
Designed for microcontrollers.
More than 7000 downloads per month.

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

Hi,
I tried to compile the port from feilipu's side [url] http://feilipu.posterous.com/ethermega-arduino-mega-2560-and-freertos
but i always get the error : lib_fatf / cc932.c "This file is not needed in current configuration" line 23
I tried it 4 or 5 times, always the same error ! I followed all the steps on feilipu's tutorial. Can someone tell me where the problem is ?
Regards, Waldemar.

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

Quote:

an someone tell me where the problem is ?

Is the error message not telling you EXACTLY what the problem is? cc932.c contains code to support Japanese Long File Names. (Chan is Japanese after all!). When you configure FatFs you edit ffconf.h and change the line:

/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/----------------------------------------------------------------------------*/

#define _CODE_PAGE	1
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
/  Incorrect setting of the code page can cause a file open failure.
/
/   932  - Japanese Shift-JIS (DBCS, OEM, Windows)
/   936  - Simplified Chinese GBK (DBCS, OEM, Windows)
/   949  - Korean (DBCS, OEM, Windows)
/   950  - Traditional Chinese Big5 (DBCS, OEM, Windows)
/   1250 - Central Europe (Windows)
/   1251 - Cyrillic (Windows)
/   1252 - Latin 1 (Windows)
/   1253 - Greek (Windows)
/   1254 - Turkish (Windows)
/   1255 - Hebrew (Windows)
/   1256 - Arabic (Windows)
/   1257 - Baltic (Windows)
/   1258 - Vietnam (OEM, Windows)
/   437  - U.S. (OEM)
/   720  - Arabic (OEM)
/   737  - Greek (OEM)
/   775  - Baltic (OEM)
/   850  - Multilingual Latin 1 (OEM)
/   858  - Multilingual Latin 1 + Euro (OEM)
/   852  - Latin 2 (OEM)
/   855  - Cyrillic (OEM)
/   866  - Russian (OEM)
/   857  - Turkish (OEM)
/   862  - Hebrew (OEM)
/   874  - Thai (OEM, Windows)
/	1    - ASCII only (Valid for non LFN cfg.)
*/

Like me I bet you have that set to 1 saying you don't need/want foreign symbol support? When you then look in the cc932.c file you find:

#if !_USE_LFN || _CODE_PAGE != 932
#error This file is not needed in current configuration.
#endif

So it deliberately forces a compile time error if either you have not configured for LFNs or (if you have) if the code page is not set to 932. Well it isn't (see ffconf.h) so what this #error is telling you is "modify the list of files being passed to the compiler/linker to be built because cc932.c is no longer needed". (you'll be pleased to hear that this instantly reduces the size of FatFs by many KB!).

 

Pages