Chris O'Byrne - YAVRTOS |
|||||||||||
|
In this example, we will flash two LEDs connected to port A at different rates.
#include "task.h" #include <stdint.h> #include <avr/interrupt.h> #include <avr/io.h> #include <avr/sleep.h> // A semaphore that we will increment at every tick static semaphore_t tick; // We will also create a mutex for port A, as both tasks will be using it potentially "simultaneously" static mutex_t porta_mutex; // This is our first task - blinking port A bit 0 once every 200 ticks void blink1(void *p) { while (1) { // Obtain a lock on the port A mutex lock_on(&porta_mutex); // OK - port A is now all ours, so blink the LED PORTA ^= 0x01; // Release our hold on the port A mutex lock_off(&porta_mutex); // Now, suspend this task for another 200 ticks wait_for_increment_of(&tick, 200); } } // This is our second task - blinking port A bit 1 once every 280 ticks void blink2(void *p) { while (1) { // Obtain a lock on the port A mutex lock_on(&porta_mutex); // OK - port A is now all ours, so blink the LED PORTA ^= 0x02; // Release our hold on the port A mutex lock_off(&porta_mutex); // Now, suspend this task for another 280 ticks wait_for_increment_of(&tick, 280); } } // This is our idle task - the task that runs when all others are suspended. // We sleep the CPU - the CPU will automatically awake when the tick interrupt occurs void idle_task(void *p) { sleep_enable(); sei(); sleep_cpu(); // This task cannot be stopped, so it is automatically re-started whenever it tries to exit } // This is a function that runs every tick interrupt - we use it to increment the tick semaphore value by one uint8_t tick_interrupt() { increment_semaphore_by(&tick,1); // We want a task switch to ALWAYS occur - it is part of the definition of the tick interrupt! return 1; } // Setup the TIMER1_COMPA interrupt - it will be our tick interrupt TASK_ISR(TIMER1_COMPA_vect, tick_interrupt()) // Our entry point int main(void) { // Interrupts should remain disabled - they will be enabled as soon as the first task starts executing cli(); // Set up port A for output DDRA = 0xFF; // Our idle task sleeps the CPU - set the sleep mode to IDLE, as we need the sleep to be // interruptable by the tick interrupt set_sleep_mode(SLEEP_MODE_IDLE); // Create our two tasks create_task(blink1, 0, 0, 55, 100, 0); create_task(blink2, 0, 0, 55, 100, 0); // Set up our TIMER1_COMPA interrupt to tick every 80,000 clock cycles TCCR1B = 0x0A; OCR1A = 9999; TIFR = _BV(OCF1A); TIMSK |= _BV(OCIE1A); // Start the RTOS - note that this function will never return task_switcher_start(idle_task, 0, 55, 55); return 0; } |
||||||||||
YAVRTOS and YAVRTOS documentation Copyright © 2007-2008 Chris O'Byrne. Email - chris <at> obyrne <dot> com