feilipu / miniAVRfreeRTOS

Minimum FreeRTOS implementation - for all AVR ATmega MCU variants.
http://feilipu.me/2015/11/24/arduino_freertos/
MIT License
63 stars 16 forks source link

Timeslicer #1

Closed eresgit closed 8 years ago

eresgit commented 8 years ago

Hello. I have had some trouble getting FreeRTOS working on an ATmega2560, the only set of files I could make work are these, so great work!

However they are using the watchdog as a time slicer which yields a minimum of 18 millis. I need tasks that can run with shorter time slices than 18 millis, so I would like to use a 16bit timer instead, but for some reason this causes tasks that call taskdelay etc to never return..?

Any chance you could provide a "mini soltuion" using a timer instead of the watchdog ?

Sincerely

feilipu commented 8 years ago

Sure. Let me direct your attention over here... avrfreertos.

But first a question. Is there a specific reason why you don't want to use an 8 bit timer for Tick timing? The duty of Tick timing is very basic and regular, the lowest activity on the system. 8 bit timers (Timer0 and Timer2) are perfect for this task. The 16 bit timers have much greater configuration control, and are very useful for PWM management, for example. If you're interested in very accurate Tick timing then an 8 bit timer is sufficient imho, and also Timer2 can count an external 32,768 Hz clock input generated by a DS3231 module (for example) for 2 ppm Tick accuracy (better than your wristwatch).

The avrfreertos version can be operated by any AVR Timer. Timer 0 or Timer 2 are preferred, but Timer 1 and Timer 3 are available too, along with the Watchdog Timer.

To "minimise" this avrfreertos repository, you'll need to delete all of the sub-directories that you don't need. Please keep these below sub-directories for further consideration, and keep all of the root level .c files.

MemMang has the 5 options available for managing the freeRTOS heap. The minimumAVRfreeRTOS only includes the heap_3.c file. I almost never use this pvPortMalloc version, as I prefer to allocate specific heap sizes using either heap_2.c or heap_4.c. You can see the configuration required in FreeRTOSBoardDefs.h.

From inside the include sub-directory the uIP and xbee sub-directories can be deleted. You should retain the lib_util.h and time.h files, for later discussion. The other include files can be matched against those in the miniAVRfreeRTOS repository, and reviewed before eventually being deleted. There's no harm initially to leave these extra unused includes, but perhaps you can remove them later.

lib_time contains the C90 implementation of real time for the AVR. Usually I find that applications I'm building benefit from having knowledge of the clock time (day of week etc). This library provides that capability, integrated into the system Tick. If you remove this library, you will need to dig into the portable layer to remove remove references to this code. If you really don't need this, remove it later.

lib_util has a few simple tools. Can be deleted, but they're often used functions, that are worth keeping. The g711.c file should be removed, as you've probably removed the g711.h header in a previous step.

portable contains the port.c file. This is where the Tick Timer selection is implemented. The Timer is selected in FreeRTOSBoardDefs.h where a definition is made for one or other of the available Timers.

#define portUSE_WDTO     WDTO_15MS    // portUSE_WDTO to use the Watchdog Timer for xTaskIncrementTick
//    #define portUSE_TIMER0    // portUSE_TIMER0 to use 8 bit Timer0 for xTaskIncrementTick
//    #define portUSE_TIMER1    // portUSE_TIMER1 to use 16 bit Timer1 for xTaskIncrementTick
//    #define portUSE_TIMER2    // portUSE_TIMER2 to use 8 bit Timer2 using 32,768Hz for xTaskIncrementTick
//    #define portUSE_TIMER3    // portUSE_TIMER3 to use 16 bit Timer3 for xTaskIncrementTick

The portable.c file first generalises Timer set up, then implements the relevant initialisation and Interrupts to operate from any timer.

That's it. You should have minimum version of freeRTOS that can be operated from any available Timer.

eresgit commented 8 years ago

I looked at this library earlier, but was somewhat overwhelmed by all the extra files and features. Your instructions worked and it did compile in atmel studio 6.2 with no errors.

I'll do some tests on my bot after the weekend, hopefully the issues I had with tasks not returning will now be solved.

Might as well use a 8 bit timer I guess, my problem was that I have several control loops with different periods and the restrictions of 18 ms time slices sort of restricted my options. I think a 16 bit timer will allow for both short and long periodic delays, allthough I have not checked what restrictions using an 8 bit timer instead will have (Is it anything else than restricting max specifiable time period to 255 ticks?)

Thank you, for your fast reply, I will give a feedback on how it worked out once I have tested it.

Sincerely

feilipu commented 8 years ago

The Tick timer is the shortest possible timer interval, without using a specific Timer to manage an event. You can set up the timers to be millisecond timers without issue. That means that you can delay any Task for an even number of milliseconds, using vTaskDelayUntil().

If you have millisecond Ticks running, then you can delay until exactly 243 of them pass (for example).

vTaskDelayUntil( &xLastWakeTime, ( 243 / portTICK_PERIOD_MS ) );

There are many ways to do this though. There's no compulsion to do it a certain way.

If I have something that needs to run regularly, I use a Timer and an Interrupt. For a synthesiser program, I needed to have 62 micro second per cycle (to output audio samples). That is beyond a RTOS to schedule, and it can only be done with a Timer and Interrupt.