====== Multitasking pentru Sparrow ======
In acest laborator vom studia implementarea unui mediu multi-tasking pentru platforma Sparrow. Pentru simplitate, functionalitatea multi-tasking este implementata peste IDE-ul Arduino sub forma unei biblioteci ce permite planificarea diferitelor task-uri, salvarea si refacerea contextului si rularea efectiva a diferitelor procese intr-o maniera concurenta.
Biblioteca folosita este o versiune modificata a [[https://github.com/chrismoos/avr-os|avr-os]] ce pune la dispozitie un mediu de execuie de baza pentru rularea de procese in regim de multitasking.
Biblioteca foloseste un planificator preemptiv pentru a face schimbarea de context si fiecare task are propria stiva ce este salvata si refacuta la reluarea executiei. Un timer AVR este initializat si folosit pentru a furniza tick-urile de ceas pe baza carora se face temporizarea executiei si schimbarea de context.
===== Instalare si configurare =====
Biblioteca o puteti descarca de {{:avr_os.zip|aici}}. Copiati continutul arhivei in directorul Libraries al Arduino si restartati IDE-ul.
Un exemplu de folosire a bibliotecii il aveti in exemplul de mai jos:
#include
spinlock_t testLock;
// Create instance of OS multitasker
AVR_OS os = AVR_OS();
// Define task 1
void task1(void *arg) {
uint8_t val=0;
while(1) {
os.spinlock_acquire(&testLock);
Serial.println("task1: " + String((long)os.os_get_uptime()));
os.spinlock_release(&testLock);
os.os_sleep(10000);
}
}
// Define task 2
void task2(void *arg) {
int x = 0;
uint8_t val = 0;
while(1) {
os.spinlock_acquire(&testLock);
Serial.println("task2: " + String(x++));
os.spinlock_release(&testLock);
os.os_sleep(1000);
}
}
// Define task 3
void task3(void *arg) {
while(1) {
os.spinlock_acquire(&testLock);
Serial.println("task3: HELLO- this is a long message to make sure spinlock is working");
os.spinlock_release(&testLock);
os.os_sleep(15000);
}
}
void setup() {
Serial.begin(115200);
Serial.println("\n\nStarting up...\n\n");
os.spinlock_init(&testLock);
os.os_schedule_task(task1, NULL, 0);
os.os_schedule_task(task2, NULL, 0);
os.os_schedule_task(task3, NULL, 0);
}
void loop() {
os.os_loop();
}
Task-urile sunt declarate ca functii apoi inscrise in planificator la initializare, in functia setup(). Numarul total de task-uri ce pot fi declarate este limitat la 5 in avr_os.cpp, din ratiuni de dimensiune redusa a stivei.
**Task 0:** Rulați exemplul de mai sus.
**Task 1:** Definiti trei task-uri, cu o perioada de 1s, 2s, respectiv 3s. Fiecare task modifica starea unui LED (task1 pentru LED-ul rosu, task2 pentru LED-ul verde, task3 modifica LED-ul albastru). Un al patrulea task va comunica starea fiecarui LED pe interfata seriala, atunci cand aceasta se schimba. In Arduino, led-urile sunt mapate pe pinii 8, 10 si 11 ai Sparrow.
**Task 2:** Rulati un program de achizitie de date si transmisie la gateway prin interfata radio folosind multitasking-ul. Un task se ocupa cu achizitia de date de la senzorul de umiditate/temperatura, alt task pentru senzorul de lumina iar un al treilea task colecteaza datele culese si le transmite pe interfata radio folosind biblioteca SparrowTransfer implementata la laboratorul 3.