FreeRTOS
FreeRTOS is a realtime kernel for many small CPU's.
(See: http://www.freertos.org)
Demo for ATmega168
New Demo project, including a the command line interpreter from Peter Fleury (be carefull with the license):
http://www.kieltech.de/~ufechner/AVR2-ATmega168-Demo2.tar.gz
I am developing this code for my theses with the title:
"Optimization of a security related stepper motor control"
An example project for ATmega168 can be downloaded here:
http://www.kieltech.de/~ufechner/AVR2-ATmega168-Demo.tar.gz
It expects:
- a 32 kHz quarz between TOSC1 and TOSC2 with 22pF C's to GND
- LED's in series with 330 Ohm resistor between VCC and PB0,PB1,PB2,PB3
- Fuses set to internal 8 Mhz oscillator
- Connect RXD and TXD
That's it.
Look into main.c, there are two #defines in line 79 and 80. Chose one of them, because not all tests can run at the same time.
With 1 kBytes of RAM I was able to run 5 Tasks + Idle Task or 4 Tasks + many CoRoutines.
I tested this program with 3,3 Volt power supply.
You might have to adapt the OSCAL value in line 160 to adjust the RC oscillator to 8 Mhz +- 2 %, to avoid problems with serial communication.
(It is set to 38 kBaud.)
Reducing the power to a minimum
Conception:
- use powersave mode most of the time
- use Timer2 with 32 kHz clock quarz, to wakeup the cpu every 1/512 sec
- use internal 8 Mhz oscillator, when active
- for RS232 communication, don't use powersave mode, but idle mode
To reduce the power supply current to about 200 µA, something similar to the following code can be used:
I use PC3 to measure the time when IRQ's are disabled, and PC2 to see when the CPU is active.
Don't forget to enable both hooks in FreeRTOSconfig.h.
unsigned portBASE_TYPE cmd_bSleep;
unsigned portBASE_TYPE cmd_bGotoSleep;
// at the beginning of main()
// don't sleep for 100 tick counts
cmd_bGotoSleep=100;
// use powersave mode; can be disabled for debugging
cmd_bSleep=1;
// check the datasheet, which peripherals you need and which can be disabled
PRR = 0xAD;
void vApplicationIdleHook( void );
void vApplicationIdleHook( void )
{
unsigned portCHAR ucQueuedBytes;
static unsigned portCHAR ucLastQueuedBytes = 0;
vCoRoutineSchedule();
// put cpu into sleep state
ucQueuedBytes=ucBytesInQueues();
cli();
// set IRQ-Disabled output
PORTC |= (1 << PC3);
// start sleep timer for two ticks when queue reaches empty state
if ((ucQueuedBytes==0) && (ucLastQueuedBytes > 0)
&& (cmd_bGotoSleep < 2)){
cmd_bGotoSleep=2;
}
ucLastQueuedBytes=ucQueuedBytes;
// any condition can be testet here atomically
if ((cmd_bSleep > 0) && (ucQueuedBytes==0)
&& (cmd_bGotoSleep==0)) {
// enter power down mode
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
} else {
// enter idle mode
set_sleep_mode(SLEEP_MODE_IDLE);
}
// clear SLEEPQ Ausgang
PORTC &= ~(1 << PC2);
sleep_enable();
// clear IRQ-Disabled output
PORTC &= ~(1 << PC3);
sei();
sleep_cpu();
sleep_disable();
// set SLEEPQ output
PORTC |= (1 << PC2);
sei();
// end of sleep
}
// this interrupt is triggert, when the RX-LINE changes,
// just to wakeup the processor
SIGNAL ( SIG_PIN_CHANGE2 )
{
cmd_bGotoSleep=200;
}
void vApplicationTickHook(void);
void vApplicationTickHook(void){
if (cmd_bGotoSleep) cmd_bGotoSleep--;
}License: Gnu Public License with exception (same as FreeRTOS)
Back to AVR-GCC