Using freeRTOS & Pololu AVR Library with Orangutan SVP

Hi Feilipu,

I used FreeROTS with the Orangutan X2 awhile back for my thesis project.

Haven’t looked at it much since then but you’ve just inspired me to get back into it. Thanks for posting up the modifications. As you said before, I definitely find an RTOS much simpler from a timing point of view when you have to manage a number of concurrent tasks.

Time to start buying parts again :slight_smile:

Thanks Lumos,

Hope you can post your thesis and code at some stage.

My Dogbot is sort of on hold at the moment. I got distracted into making a retrograde (hands rewind back to original position) clock and using this as a project to understand hardware based PWM properly. http://feilipu.posterous.com/freetronics-2010-arduino-duemilanova-freertos
So I wrote a set of little functions to manage the Timer1 or Timer0 PWM hardware, depending upon which timer was being used for the freeRTOS Tick.

As part of this work, I wrote some more extensions to freeRTOSconfig.h file configurations to allow you to use either Timer0 or Timer1 as the Tick timer on the 328p. Though, in hindsight, I think there is no reason to use the more functional Timer1 as the Tick timer at all.

I sort of ran into a wall with Dogbot, in that I wasn’t getting sensible values from the SVP quadrature encoder functions, so the PID couldn’t ever work properly.

100% certain my hardware is right, as the SVP demo code can see the quadrature outputs properly. Need to dig into whether it is a conflict between freeRTOS and the Orangutan libraries, or whether its just bad programming. Will know more once the clock is up on the wall in the next week or so.

One thing to look out for with serial comms and RTOS is that if your comms task is not the highest priority you may end up with some problems if the buffer fills before you have a chance to read it or if the other device depends on some fairly tight timing constraints (or delays) you’ll get some unpredictable behaviour. Although that being said it seems there’s only 5 bytes for the encoder counts + status so I would think it should be okay.

Can also be quite handy to test things before the scheduler takes over just to make sure they work independently. Keep us updated on how the project goes!

When you are retrieving information from the SVP’s auxiliary processor, there should be no issue with the priority of the task. The communication is done over SPI, which means that the master (the AVR ATmega324p/1284p) has total control over when the slave sends the information. It should be fine if the master is a little slow in requesting bytes from the slave because some other task pre-empted the encoder reading task.

The auxiliary processor requires you to have a minimum delay of a few microseconds between SPI bytes so it has time to prepare the next byte, but there is no maximum delay.

–David

Ahh, of course, thanks David.

I’d forgotten about the SPI master/slave setup, the delays are an issue for UART serial comms like a GPS where it’s just streaming data at you that you can miss.
In that case I’m not quite sure what the issue could be, let us know when you work it out.

Been spending some time on a time wasting (its a pun) diversion, building a clock, to learn how to use hardware PWM to drive servos. The reason to use hardware PWM is to allow the servos to work in the background, without interrupting the freeRTOS tick unnecessarily.

The post is here. http://feilipu.posterous.com/freetronics-freertos-retrograde-real-time-clo

As part of that I needed to move one of the OrangutanLCD configured data lines to free both Timer 1 PWM pins to drive two servos. I’ve updated the OrangutanLCD.h file to free Arduino Pins 9 & 10 by moving DB4 onto Pin 11.

The file from the Pololu library is here:

~/libpololu-avr/src/OrangutanLCD/OrangutanLCD.h

Once the change is made, you’ll need to recompile and reinstall the library as described.
https://www.pololu.com/docs/0J20/3

The changes to OrangutanLCD.h are here:

#define LCD_DB4                PORTB3        // Was PORTB1. Use PORTB3 to avoid the Timer1 pins. 
#define LCD_DB5                PORTB4        // PB4 
#define LCD_DB6                PORTB5        // PB5 
#define LCD_DB7                PORTD7        // PD7

//    PortB:     7 6 5 4 3 2 1 0 
//  LCD Data:      2 1 0            Use DB3 to avoid Timer1 pins. 
//  LCD Data:      2 1     0 
// 
//  PortD:     7 6 5 4 3 2 1 0 
//  LCD Data:  3

#define LCD_PORTB_MASK            ((1 << LCD_DB4) | (1 << LCD_DB5) | (1 << LCD_DB6))
#define LCD_PORTD_MASK            (1 << LCD_DB7) 
#define LCD_PORTB_DATA(data)    ((data & 0x07) << 3)  // Modified the data mask to avoid using DB1 
#define LCD_PORTD_DATA(data)    ((data & 0x08) << 4)

I’ve updated the FreeRTOSConfig.h file to allow different timers to be used to drive PWM.
Also, added the use of internal pull up resistors on the I2C SCL and SDA lines.

Also, out of interest, I’ve compiled the Pololu Libraries on a PS3, which uses the PowerPC architecture. Off an Ubuntu 10.4 Lucid platform, it is all surprisingly easy. Here’s a link to the process, though it is exactly the same as with any x86 Ubuntu platform.
http://feilipu.posterous.com/freetronics-freertos-retrograde-real-time-clo-0
freeRTOS_604_retrograde_clock.zip (158 KB)

I had put the Dogbot project aside for a while. It was becoming bad for my state of mind.

But now, it is back on track. This post has some pictures of the new build. Pretty much the same as before, but a little cleaner and more robust.

feilipu.posterous.com/dogbot-pos … k-on-track

More soon. Code to anyone who cares to ask.

Hello.

Thanks for sharing. Your robot looks very cool! Where did you get your standoffs?

Regarding this text from your blog post:

We factory-calibrate each encoder to work properly for input voltages from 4.5 - 5.5 V, and we do not recommend users adjust the pots if their supply voltage is in this range. The only time you should need to touch the pots is if you want to run the encoder from a different voltage (e.g. 3.3 V), or if you are trying to fit it into a custom system for which it wasn’t intended. Had you adjusted the pots prior to your having problems with the encoder?

The SVP doesn’t necessarily require 50% duty cycle signals, it just requires that the transitions on the two quadrature channels always occur in the proper sequence with enough time between successive transitions for the processor to be able to correctly sample the state of both channels on each transition.

- Ben

Hi Ben,

thanks. It remains lots of fun watching my coding (bad as it is) coming to life through a mobile robot. One day, I might get it finished.

The stand-offs come from a hardware store, and are called Wall Plugs in Australia.
http://www.howtoaustralia.com.au/quick_guide/a_quick_guide_to_using_wall_plugs/
There might be other names for them in USA.

I originally used them as spacers, but found that the best mounting method was to use them structurally, by putting an appropriate sized screw in each end. Their slight flexibility allows me to match the square holes in your chassis with the corner holes in the Orangutan SVP, and also keep the solution a little robust.

Regarding the Encoders issues I was having. Initially I had one Encoder counting correctly and one counting about 1/3 of the pulses. I ordered a replacement unit, and installed it during rebuild I described.

Unfortunately, when I got it back together the Encoder that was previously working wasn’t any more. But at least the new one worked properly. At that stage, I hadn’t adjusted anything on the Encoders themselves.

So, I decided to look closely at the waveforms with the motors in motion (which I hadn’t previously done). I found that some times they were not triggering properly. So following your suggested adjustment process, I adjusted them to be 50% duty cycle. And, suddenly everything worked as it should.

I guess that my issue would be that my system is drawing a lot of current, and that the voltage may be hovering around 4.5V or even less as the Backpack unit discharges. Hence my need to adjust them.

Regards, Phillip

For information, I’ve been maintaining the freeRTOS code for the Orangutan and Arduino on Sourceforge on a project called avrfreertos.

http://sourceforge.net/projects/avrfreertos/

freeRTOS implemented for selected AVR ATmega devices.
Arduino AVR ATmega328p supported.
Pololu Orangutan SVP AVR ATmega1284p supported.
Arduino Mega 2560 supported. (digitalAnalogue library addresses wrong pins - avoid temporarily).

Recently, I’ve added these features:
Latest freeRTOS revision v7.10
Added library for Rugged Circuits QuadRAM for ATmega2560
Added ChaN’s FatF v0.9 library, including a SDmonitor project (working but buggy).

Regards, Phillip

Reviving this rather old thread, I recently began using feilipu’s port of FreeRTOS in an Orangutan X2-based project. I thought I’d ask (if you are still here) if you hit any hiccups using the Pololu library functions? I’m planning to use serial comms, tones and motor control from the Pololu library, and from FreeRTOS I’m planning to use task scheduling and possibly timers. Provided you hardware conflicts are avoided, did it all work out OK?

Purely FYI, I’m wanting the X2 to handle basic stuff and will use a Raspberry Pi to do anything else on the robot so I do have options as to how complex the Atmel 1284p stuff is if there is a conflict.

Rob

Yes, it is an old thread, but I’m still around, and still maintaining the
AVRfreeRTOS on Sourceforge.

The code is now on v7.5.0, which is the current version of freeRTOS.

Because I liked the 1284p in the SVP so much, I built an Arduino clone called the Goldilocks. The Goldilocks is the best way to get all the 1284p features, but keeping Arduino Shield compatibility.

To your question around the pololu libraries. To my knowledge there are no problems in using the libraries. The only reason that I stopped using them was that for me a big part of the fun is to understand what is happening at bit / port level, so building my own (borrowing others) is a good way to learn more.

There are some things that I’ve done (copied / repurposed / modified) with libraries, that I’m happy with:

  • Getting the FatFS file system working, means that FAT32 works well.
  • The I2C library supports both Master and Slave modes, from one code base.
  • The SPI library is designed for multibyte transfers, for example with W5200, and performance.
  • Integrating avr-libc time.h code, Contiki timers, and assembly code Timer2 RTC tick solution.
  • Integrating uIP from v0.9 and v1.0 and latest Contiki 2.6 into one codebase.
  • And I’m testing a new ring-buffer USART library, that is about 100x faster than the current code (using freeRTOS queues) on Sourceforge (update soon as I’m happy).

If you just want to use the core of freeRTOS code together with pololu libraries for the X2, then you can basically clean out all of the libraries and just be left with the files in the root of the freeRTOS folder. Really freeRTOS is only a few files to manage tasks, queues, and lists, and then portability macro layer (portable) and memory (MemMang) allocation options.

Excellent! I’m using the core bits from your FreeRTOS port (very useful indeed, thanks for all your work) and have shown that the QBasic demo works so I’m going to start building up functionality on that now. I would be really interested in your ring-buffer USART library work as well; I’ve done those bits with the Pololu functions but since FreeRTOS is working for me it would be a good time to switch over while my relevant test jigs remain extant.

Rob

I’ve updated the Sourceforge AVRfreeRTOS, to use the modified ringbuffer.h code from Dean Camera’s implementation of ring buffers. That’s well tested within LUFA.

I’ve found that sometimes the transmit interrupt will not fire unless the receive flag is cleared, so I implemented a flush function xSerialFlush() to take care of this issue.

If code size is an issue, avr-libc allows a selection of implementation options for vsnprintf() and other string functions. Depending on requirements either the normal, small or full float implementation of string libraries can be linked. See the documentation on avr-libc.

I recommend using the time.h functions for generating a tick timer, and for generating a one second system tick to keep real time. Even without a 32768Hz crystal the normal oscillator keeps good enough time to measure milliseconds and seconds intervals reasonably accurately. I’ve also added simple timer functions (from Contiki) to enable regular millisecond and second intervals to be measured, and checked for expiry.

Having got serial comms going with the standard Pololu Orangutan SVP library functions, I’ve now moved my code across into a freeRTOS tasking structure (containing three tasks and two queues (each of a few 10’s of bytes)) before moving to the freeRTOS serial code. However, I find that I’ve run out of (my 16kbytes) RAM when I enter my very first task (Pololu’s get_free_ram() reports -144 bytes and all malloc()s fail). The linker reports static RAM usage as 829 bytes and I’ve not malloc()ed any memory myself at this point so there must be something up with how I’ve configured the freeRTOS port (I’m using heap_3.c).

Any pointers as to how one goes about debugging the RAM consumption of freeRTOS (aside from taking config items out until it works)? How much RAM should I expect this freeRTOS port to consume (freeRTOSconfig.h attached)?

Rob
FreeRTOSConfig.h (5.51 KB)

Rob,

I’ve attached the freeRTOSBoardDefs.h file that I created to manage all of the different versions of hardware I use. It was getting too complicated to manage just one freeRTOSConfig.h file, so I just leave my freeRTOSConfig.h file pretty much constant.

In the freeRTOSBoardDefs.h file I’ve noted the key things below.

#define portUSE_TIMER2 // portUSE_TIMER2 to use 8 bit RTC Timer2 on 1284p device,
// #define portUSE_TIMER3	// portUSE_TIMER3 to use 16 bit Timer3 on 1284p device, if you don't have a 32768Hz RTC crystal.

#define configTICK_RATE_HZ ( ( portTickType ) 256 )
// Use 500Hz for TIMER3. With a MINIMUM of 128Hz for TIMER2.
// Use 1000Hz to get mSec timing using TIMER3.

#define configCPU_CLOCK_HZ ( ( uint32_t ) F_CPU )
// This F_CPU variable set by Eclipse environment

 #define configTOTAL_HEAP_SIZE	( (size_t )  12000  )
// used for heap_1.c and heap2.c, and heap_4.c only. This is the size of your heap, that I didn't see you set anywhere. heap_3.c just calls malloc() and doesn't use this #define.

 #define portSERIAL_BUFFER_RX	64 // Define the size of the serial receive buffer.
 #define	portSERIAL_BUFFER_TX 255 // Define the size of the serial transmit buffer.
// Tx buffer only as long as the longest xSerialPrintf() text to be sent.

The stack for each task in freeRTOS is managed by greater of configMINIMAL_STACK_SIZE and the stack size created during building the task. Check the free stack size often for each task.

Also, I’ll often check free heap size when debugging.

You can see commented out lines related to both of these functions in my code examples below.

xSerialxPrintf_P(&xSerialPort, PSTR("Free Heap Size: %u\r\n"), xPortGetFreeHeapSize() );
// needs heap_1 or heap_2 or heap_4 for this function to succeed.

xSerialxPrintf_P(&xSerialPort, PSTR("RedLED HighWater @ %u\r\n"), uxTaskGetStackHighWaterMark(NULL));
// call this from the task in question with NULL as the task identifier.

freeRTOSBoardDefs.h (16.2 KB)

Thanks - I’m using heap_3, hence the lack of that particular definition. I take it heap_3 might not be such a good idea?

Rob

Heap3 just brings in malloc(). So it is neither good nor bad. More religion.

For debugging, I like Heap4, though it is overkill too, for what I do.

Have a go with a freertos heap to test memory, at least at the start. Also comment out tasks and add them back one at a time.

P.

OK will switch to heap 4 for debug. I did try one task only but it made no difference, in fact only changing stack sizes seems to have had any effect so far, hence my feeling that it must be a configuration problem.

Rob

FYI, having simplified a lot, used only the FreeRTOS dynamic memory, wrapped all external library functions in RTOS suspend/resume calls (to be completely safe for now) and solved my silly mistakes, I’ve got the basics working. On the Orangutan X2 the serial port I can use easily at the moment via USB from a PC isn’t handled directly by interrupts on the 1284p chip so I’ll get around to using your serial functions once I’ve got something connected to the other USARTs.

Very happy indeed with the port, feels so nice to have a little RTOS running under me. Thanks very much for all your efforts in supporting it.

:smiley:

Rob