====== 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.