freeRTOS and libraries for AVR ATMEGA with Eclipse IDE
I've created a Sourceforge project as a place to host all my current tools and working environment.
Sourceforge freeRTOS & libraries for AVR ATMEGA
That's the thing about open source. Sometime you have to give back.
Things I'm really happy about:
- Freetronics EtherMega (Arduino Mega2560) ATmega2560 scheduling and IO works.
- Being able to use any Timer on the AVR as the system Tick. In practice this means Timer0 on 328p (Arduino) and Timer3 on 1284p (Pololu SVP) and 2560 (Arduino).
- Converting all of the relevant libraries to be friendly to a RTOS system. No nasty delay wait loops etc. Everything defers to (is interruptible by) the scheduler when waiting, or is driven from interrupts.
- Having several finished projects, that are good demonstrations of lots of AVR and freeRTOS capabilities.
- Having the Sparkfun LCD Shield working properly, with printf string formatting.
- Having the Rugged Circuits QuadRAM and MegaRAM working on ATmega2560.
- Porting ChaN FatF microSD card support for Freetronics EtherMega.
- Porting Wiznet W5100 Ethernet drivers for Freetronics EtherMega.
- Properly implementing semaphores for access to resources (ports, interfaces, ADC, LCD).
- Properly implementing queues for transferring data between tasks (threads).
The repository of files is a working collection for a freeRTOS based platform using the AVR-GCC and AVRDUDE platform. The development environment used was Eclipse IDE. With some luck the included file structures will simply import into Eclipse.
With Eclipse the AVR plug-in is needed. It is assumed that the AVR libraries are installed. For the retrograde project, it is assumed that Pololu libraries are installed. I've added an old (now unmaintained) make file in case the compile and link parameters for Eclipse are not readily available.
The freeRTOS folder contains the most recent version 7.1.0 of freeRTOS, but it has been abridged down to only those files relevant for AVR GCC. The port.c file has been extensively modified to allow the use of either of the 328p Timer0 or Timer1 timers. And, the use of Timer3 on the Pololu SVP which has uses a 1284p. Timer 3 for EtherMega (Arduino Mega 2560) also works.
If you want to use 16bit PWM on Arduino 328p platform, then you'll need to enable the Timer0 system Tick. The freeRTOSConfig.h file contains most of the variables that you'll need to change.
There are some relevant and often used libraries added to the basic freeRTOS capabilities.
- lib_digitalAnalog: contains often used I/O routines borrowed from Pololu.
- lib_i2c: contains the tools to use the TWI or I2C bus. contains integrated master and slave routines. Multi-master arbitration / back-off has not been tested.
- lib_spi: contains the tools to use the SPI bus.
- lib_servo: contains routines to enable accurate PWM using the 16 bit Timer1, used in the retrograde clock example.
- lib_serial: contains routines to drive the serial interface. there are two versions; avrSerial for use before the freeRTOS scheduler has been enabled, and xSerial for normal operations. xSerial is interupt driven.
- lib_ext_ram: contains routines to drive the Rugged Circuits QuadRam on Arduino Mega2560, or Freetronics EtherMega.
- lib_crc: simple 8 bit CRC calculation.
- lib_rtc: drivers for the DS1307 RTC using I2C.
- lib_fatf: contains ChaN's FatF libraries for driving the microSD card on the Freetronics EtherMega.
- lib_W5100: contains the W5100 drivers from Wiznet v1.6. Even fixed a subtle bug caused by not waiting for Tx to complete before additional packets are written to Tx buffer.
- lib_inet: contains a DHCP implementation. This will grow.
Some more recent posts are here:
Melding freeRTOS with ChaN's FatF & HD44780 LCD on Freetronics EtherMega
Rugged Circuits QuadRAM on Freetronics EtherMega
Quick review of Freetronics EtherMega
Description of the AVR Pong multi-processor game.
Step-by-step Instructions
Our Destination:
On completing these instructions you should have an Eclipse IDE (Integrated Development Environment) installed with all relevant libraries installed, to use the freeRTOS, and the libraries I've modified, to build projects (Eclipse term for a set of code) of your own.
We're Assuming:
These instructions are based on a Ubuntu 11.10 install, but the path to the destination is not complex, and can be roughly followed for any installation platform.
Step 0. As usual on an Ubuntu (Debian) system, refresh the software sources.
sudo apt-get update
Step 1a. Install the AVR Libraries.
Step 1b. Install the Arduino environment.
Doesn't hurt to have the Arduino environment available. It can be used for programming bootloaders (using AVR-ISP code), and generally for checking health of equipment, using known good example code.
This will pull in some extra libraries that the Arduino platform needs.
Step 2a. Obtain the Pololu Libraries (optional).
The Pololu Libraries are used for the multi-line LCD tools (such as in the retrograde clock) together with their quite powerful and efficient methods of doing many things. Where I'm using a Pololu controller such as an Orangutan SVP it makes sense to use their libraries too.
Rather than incorporating all their libraries in all my projects, I integrated the analogue and digital line control libraries (the functions I used most) into another smaller library of my own, so I tend not to use their libraries because it makes for one additional dependency.
Never-the-less, we will install the Pololu libraries, as they are needed for the retrograde clock project. If you don't want to use their libraries, just skip this Step 2.
Download the Pololu libraries from here, to a suitable place.
http://www.pololu.com/docs/0J20/2
Unpack the entire archive and open a command prompt within the libpololu-avr directory. If avr-gcc is correctly installed on your system (Step 1a), you will be able to type "make" to compile the entire library. Pay attention to any errors that occur during the build process.
Step 2b. Change the LCD pin definitions in lib-pololu to allow access to both 16 bit PWM lines on an arduino compatible device.
If there are no compile or linking errors, then you can grab my updated OrangutanLCD.h file from sourceforge, and swap it for the one in the source folder of Pololu, then recompile.
This only needed for retrograde clock project. If it seems too difficult, come back and do it later. The retrograde clock project needs to use 16bit PWM to drive 2 servo motors. One of the needed PWM pins is in conflict with Pololu's standard LCD pin assigment. See the file for the changes.
sudo make clean
sudo make
Step 2c. Install the Pololu Libraries.
The libraries will be found in the same directory branch as the avr libraries when this step is successful.
Step 3. Fix avrdude chip erase delays.
There is a long standing bug in avrdude configuration files, that prevents proper programming of the 324p, 644, 644p and 1284p devices. These are relevant to Sanguino and Pololu users.
http://savannah.nongnu.org/bugs/?28344
The chip_erase delay for four AVRs in avrdude.conf is too short, so the chip erase command times out and avrdude prints an error message. The error is not fatal; it doesn't prevent the user from programming the chip. This bug should be very easy to fix.
In avrdude.conf, change the chip_erase_delays to the following values:
part chip_erase_delay =
ATmega324P: 45000 (us)
ATmega644: 55000
ATmega644P: 55000
ATmega1284P: 55000
Currently they are all 9000, which is too short. So in your favourite editor, open the avrdude.conf file, and make the changes to the chip definitions.
sudo gedit /etc/avrdude.conf
Step 4. Install the Eclipse IDE.
It is not necessary to use or install an IDE to develop with freeRTOS, or with any other system. It is easy to use makefiles and the command line. In fact, I didn't use Eclipse for a long time. And, when I first started to use it, it felt very unnatural and clumsy.
However now I've been using it for some time I highly recommend it, for the ability to see deeper into the code (definitions are detailed on mouse over), and to compare (live differences) and roll-back code to any step of your editing process.
Again, installation is easy with Ubuntu (Debian), but it can take a while. Lots of things get installed along with it.
sudo aptitude install eclipse
Step 5a. Select the C & C++ development tools within Eclipse.
Eclipse is a Java based platform, but it works just as well with C, and C++, as it does with a wide variety of languages. Getting the C Development Tools (CDT) is the first step to a C environment that we'll be using.
Open Eclipse, and lock it to your launcher. You'll be using it frequently.
Using the Menus, click:
Help>>Install New Software...>>Add...
CDT Indigo http://download.eclipse.org/tools/cdt/releases/indigo
Select only "CDT Main Features", and install these plugin development tools.
Step 5b. Select the AVR development environment within Eclipse.
The AVR environment includes direct access to the avrdude downloading tool for one-click programming of your AVR devices.
Using the Menus, click:
Help>>Install New Software...>>Add...
AVR Plugin http://avr-eclipse.sourceforge.net/updatesite/
Select "CDT Optional Features", and install these plugin development tools.
Step 5c. Select C/C++ Perspective
First you need to select the right perspective, being C/C++. Top right there is a button showing "Java". Just to the left is a button (like a window) for selecting perspective. Select
Other...>>C/C++
When that is finished, you should have Eclipse menu button containing a AVR* with a green down arrow. That is the button used to program the arduino or Pololu device.
Step 6. Define a freeRTOS static library project.
There are lots of short cuts, and alternative ways to achieve things using context sensitive menus in Eclipse. I'll concentrate on the top menu bar options, though you can get most things from a context menu click in the right window.
File>>New>>C Project: AVR Cross Target Static Library: Empty Project
A static library project is never run by itself. It is always linked to by other projects, called AVR Cross Target Applications.
Give the project a name (perhaps freeRTOS710).
Now a project will apear in the "Project Explorer" window. Select it. We are going to set some options relating to this project.
Project>>Build Configurations>>Set Active>>Release
Project>>Properties
AVR:Target Hardware: MCU Type: ATmega328p (or other depending on hardware)
AVR:Target Hardware: MCU Clock Frequency: 16000000 (or other depending on your hardware)
C/C++ Build: Configuration: [All Configurations] (make sure this is set for all following configurations)
C/C++ Build: Environment: AVRTARGETFCPU: 16000000
C/C++ Build: Environment: AVRTARGETMCU: atmega328p
C/C++ Build: Settings: AVR Compiler: Symbols: Define Syms (-D): Add... GCC_MEGA_AVR
C/C++ Build: Settings: AVR Compiler: Optimisation: Other Optimisation Flags: -mcall-prologues -mrelax (and use -Os or -O2)
Now we are going to add the freeRTOS files, from the freeRTOS710.zip file that you have downloaded from sourceforge, and extracted somewhere sensible.
File>>Import...>>General:File System
Select the "into folder" as the project name you just created, and "Select All" for the import. That should import the entire file system. Spend some time browsing, if you like.
Now we define the include library for the build. Remember to select [All Configurations] first.
Project>>Properties>>C/C++ Build>>Settings: AVR Compiler: Directories
Add the from the "Workspace...": freeRTOS710/include
"${workspace_loc:/${ProjName}/include}"
Now there are three alternative memory management routines, explained in the freeRTOS documentation. We are going to use the heap_2.c version, so we need to exclude the other two files from the build. In the project explorer RIGHT CLICK (context menu) each one then exclude them.
./MemMang/heap_1.c
./MemMang.heap.3.c
Resource Configurations>>Exclude from Build...: Select All
Following this step, it should be possible to compile the library.
Project>>Build All
If there are any ERRORS, then go back and check the configurations for the project. Sometimes they may be changed, forgotten, or otherwise different from what you expected.
There will be some WARNINGS, relating to the usage of different Timers. I added these warnings to keep these things front of mind, as depending on which hardware I'm using the ./include/FreeRTOSConfig.h file needs to be managed to suit.
Step 7. Define an Application Project.
An Application will generate the final hex code that you upload to the AVR with avrdude. This final code is created from the freeRTOS static library code generated above, together with code contained in the avr-libc and pololu-avr libraries, and any other linked projects.
We are going to import the MegaBlink project (or the retrograde project, using the pololu-avr libraries) as it makes a good example. Without a display, or real-time-clock module, it will only flash a LED. But, least we know it is alive.
To get started create a new project as below.
Give the project a name (perhaps MegaBlink or retrograde).
Now a project will apear in the "Project Explorer" window. Select it. We are going to set some options relating to this project.
Project>>Build Configurations>>Set Active>>Release
Project>>Properties
AVR:AVRDUDE:Programmer:New...
Configuration name: Arduino or Freetronics 2010
Programmer Hardware: Atmel STK500 Version 1.x firmware
Override default port: /dev/ttyUSB0
Override default baudrate: as or if required.
AVR:Target Hardware: MCU Type: ATmega328p (or other depending on hardware)
AVR:Target Hardware: MCU Clock Frequency: 16000000 (or other depending on hardware)
C/C++ Build: Configuration: [All Configurations] (make sure this is set for all following configurations)
C/C++ Build: Environment: AVRTARGETFCPU: 16000000
C/C++ Build: Environment: AVRTARGETMCU: atmega328p
C/C++ Build: Settings: AVR Compiler: Directories: "${workspace_loc:/freeRTOS710/include}"
C/C++ Build: Settings: AVR Compiler: Symbols: Define Syms (-D): Add... GCC_MEGA_AVR
C/C++ Build: Settings: AVR Compiler: Optimisation: Other Optimisation Flags: -mcall-prologues -mrelax (and use -Os or -O2)
C/C++ Build: Settings: AVR C Linker: General: Other Arguments -Wl,--gc-sections
C/C++ Build: Settings: AVR C Linker: Libraries: Add two "m" & "pololu_$(AVRTARGETMCU)" without quotes. m is the standard math library, which should be included in most projects. (pololu library is an optional step, if using the retrograde project).
C/C++ Build: Settings: AVR C Linker: Objects: Other Objects Here you need to add the compiled freeRTOS library. And this is the only place where the Debug and Release builds are different.
With Release Build selected, paste "${workspace_loc:/freeRTOS710/Release/libfreeRTOS710.a}"
With Debug Build selected, paste "${workspace_loc:/freeRTOS710/Debug/libfreeRTOS710.a}"
Or select the Workspace option to navigate to the actual assembler files to be linked into the project.
Project References: freeRTOS710 ticked.
Now we are going to add the MegaBlink (or retrograde) files, from the MegaBlink.zip (or retrograde.zip) file that you have downloaded from sourceforge, and extracted somewhere sensible. If you downloaded the freeRTOSxxx_All_Files.zip, you have all the sources.
File>>Import...>>General:File System
Select the "into folder" as the project name you just created, and "Select All" for the import. That should import the 2 files shown inro the project file system. Spend some time browsing, if you like.
Following this step, it should be possible to compile and link the project.
Project>>Build All
If this step completes successfully, with no additional ERRORS, then the final step is to upload the new application into your Arduino or Freetronics device.
Make sure that you have your device plugged into the USB port, then simply hit the AVR* button in the row of buttons. You will see some green text showing the status of the upload, finishing with the words
avrdude done. Thank you.
Now, you should have a flashing LED.
Now you can import any additional projects, in the same way. However, the Pololu library can be omitted for most of my other code.
Step 8. Things to watch.
Turn on the serial port by removing the comments around the serial port definitions, and watch to see aspects of the program in action.
Expect to manage the amount of heap allocated in the ./include/FreeRTOSConfig.h file, to ensure that the total SRAM utilised (as noted in the final link stage when using heap_1.c or heap_2.c) remains less than 100% or for ATmega328p 2048 bytes.
Expect to manage the amount of stack space allocated to each task during the set up, to ensure you're not wasting space, nor (worse) you're over writing another task's stack.
Keep the total number of tasks to below 4, otherwise too much SRAM is consumed.
We could really do with a ATmega1284p based Arduino. It has 16kbyte of SRAM available. Which leaves about 15,000 Bytes SRAM available, rather than just 1,500 Bytes with 328p. Party on!
