Sunteți pe pagina 1din 10

MINISTERUL EDUCAŢIEI, CULTURII ȘI CERCETĂRII AL REPUBLICII

MOLDOVA
Universitatea Tehnică a Moldovei
Facultatea Calculatoare, Informatică și Microelectronică
Departamentul Ingineria Software și Automatică

Sisteme de Operare
Lucrare de laborator nr.2

Student:
Coordonator: Dubac Serghei, asistent universitar

Chişinău, 2020
Sarcina

Realizarea unei aplicații pentru MCU care va rula minim 3 task-uri în două versiuni: Secvențial și cu
FreeRTOS.

Aplicația va rula minim 3 task-uri printre care:


1. Button Led – schimbare stare LED la detecția unei apăsări pe buton;
2. Button Led – intermitent, în faza în care LED-ul de la primul task e stins;
3. Incrementare/decrementare – valoare a unei variabile la apăsarea a două butoane care va reprezenta
numărul de recurențe/timp în care LED-ul de la al doilea task se va afla într-o stare;
4. Idle – afișarea stărilor din program, cum ar fi, afișare stare LED, și afișare mesaj la detecția apăsării
butoanelor, o implementare fiind ca la apăsarea butonului să se seteze o variabilă, iar la afișare mesaj
– resetare, implementând mecanismul provider/consumer.

Indicații

1. Să se implementeze comunicarea între task-uri ca provider/consumer, adică:


 task-ul care generează date, provider, stochează rezultatele într-o variabilă globală/semnal;
 task-ul care utilizează aceste date, consumer, citește aceasta variabilă/semnal.
Exemplu: task de UI (LCD sau Serial) preia informația din niște variabile-semnale globale și raportează.
2. A se urma principiile prezentate la curs Sisteme Secvențiale:
 stabilirea rezonabilă a recurenței pentru a diminua încărcarea procesorului;
 stabilirea offset-ului, întru a activa în ordinea cuvenită task-urilor.
3. Task-ul de raportare pentru Secvențial cu utilizare STDIO printf() către LCD va fi rulat în bucla
infinita/IDLE deoarece este bazat pe un spin lock și ar putea bloca întreruperile, deci secvențial clasic
– printf&delay în main loop, în FreeRtos – un task separat.
4. Versiune cu FreeRtos.

Etapele

Pentru aplicația (anume MCU) noastră vom utiliza un sistem compus din mai multe componente, care
le analizăm din schema 1. Treptat vom testa fiecare din acestea, dând la execuție la programul nostru.
Schema 1. Schema aplicației pentru MCU

După exacutarea în prima priză, LED-ul de culoare roșie este cu statut de stins, iar LED-ul verde este
intermitent timp de 1 secundă.

Schema 2. Executarea în primă repriză

Acțiunea următoare va fi, apăsarea butonului „BTM INCREMENT”. Acesta va mări timpul de ardere
intermitent (de exemplu, 2 secunde arde și 2 secunde în regim stins). În terminal (schema 3) analizăm
valoarea recurenței, LED-ul verde timp de 4 secunde se va afla în regim ON, iar apoi OFF.
Schema 3. Valoarea recurenței pentru Green LED

Testăm butonul „BTN RED LED”, vedem că automat LED-ul de culoare verde se stinge și se aprinde
cel de culoare roșie. De asemenea, acordăm atenție că atât timp cât roșu este activat, LED-ul verde va fi
inactiv (schema 4).

Schema 4. Testarea butonului „BTN RED LED”

Testăm butonul „BTN RESET” (schema 5) – toate valorile anterioare afișate după executări sunt
restate și întreg sistem revine la starea inițială. La final, avem afișat mesajul precum sistemul nostru a trecut
cu succes prin resetare.
Schema 5. Testarea butonului „BTN RESET”

Concluzie

În cadrul lucrării de laborator nr.2, am lucrat la realizarea unei aplicații pentru MCU. În baza unei
scheme, am programat și testat fiecare componentă. Am demontrat schimbarea de stări al unui buton la
detectarea unei acțiuni similare cu altă componentă. În proiect s-a pus accent pe numărul de recurențe per
timp. Fiecare buton are programul său, iar după resetare avem un mesaj afișat, datorită implimentării
mecanismul de provider per consumer.
ANEXA 1

Cod sursă. Sistem FreeRTOS

#include <Arduino_FreeRTOS.h>
#include <HardwareSerial.h>
#include <Arduino.h>

#define BUTTON_PIN 13
#define BUTTON_LED_INCR 10
#define BUTTON_LED_DECR 11

#define LED_PIN 4
#define LED_BLINK_PIN 5
#define LED_ON 1
#define LED_OFF 0
#define TASK_REC 2
#define TASK_OFFSET 5

int led2Rec;
int ledState;
int led2State;
int buttonState;
int led2ReadRec;
int btnResetState;

void GreenLEDblink( void *pvParameters );


void IncDecRecLED( void *pvParameters );
void PrintStates( void *pvParameters );
void RedLEDstatus( void *pvParameters);
void Reset( void *pvParameters);

void setup() {
led2Rec=0;

ledState=0;
led2State=0;
buttonState=0;
led2ReadRec = 1000;
pinMode(BUTTON_LED_DECR, INPUT);
pinMode(BUTTON_LED_INCR, INPUT);
pinMode(LED_BLINK_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(9, INPUT);
Serial.begin(9600);
xTaskCreate(GreenLEDblink, "GreenLedBlink", 128, NULL, 3, NULL);
xTaskCreate(IncDecRecLED, "RecForLed", 128, NULL, 2, NULL);
xTaskCreate(PrintStates, "Print", 128, NULL, 3, NULL);
xTaskCreate(RedLEDstatus, "RedLED", 128, NULL, 1, NULL);
xTaskCreate(Reset, "ResetEverything", 128, NULL, 3, NULL);
vTaskStartScheduler();
}

void loop()
{
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void GreenLEDblink(void *pvParameters){


(void) pvParameters;

for(;;){
if(ledState == 0)
{
if(led2State == 0)
{
led2State = 1;
digitalWrite(LED_BLINK_PIN, HIGH);
}
else
{
led2State = 0;
digitalWrite(LED_BLINK_PIN, LOW);

}
vTaskDelay(led2ReadRec / portTICK_PERIOD_MS);
}
}

void IncDecRecLED(void *pvParameters){


(void) pvParameters;

for(;;){

if(digitalRead(BUTTON_LED_INCR) == 0)
{
led2ReadRec=led2ReadRec+1000;
}
if(digitalRead(BUTTON_LED_DECR) == 0)
{
led2ReadRec=led2ReadRec-1000;
}
vTaskDelay(15);
}

void PrintStates(void *pvParameters){


(void) pvParameters;

for(;;){
Serial.println();
Serial.print("Red LED status:");
if(ledState==1){
Serial.println("ON");
} else Serial.println("OFF");
Serial.print("Green LED status:");
if(led2State==1){
Serial.println("ON");
} else Serial.println("OFF");
Serial.print("Green LED rec:");
Serial.print(led2ReadRec/1000);
Serial.println("s");

vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}

void RedLEDstatus( void *pvParameters){


(void) pvParameters;

for(;;){
buttonState = digitalRead(BUTTON_PIN);

if(buttonState == 0)
{
if(ledState == 1)
{
ledState = 0;
}
else
{
ledState = 1;
led2State=0;
digitalWrite(LED_BLINK_PIN, LOW);
}
digitalWrite(LED_PIN, ledState);
}

vTaskDelay(15);
}

void Reset(void *pvParameters){


(void) pvParameters;

for(;;){
btnResetState = digitalRead(9);

if(btnResetState == 0){
led2Rec=0;
ledState=0;
led2State=0;
digitalWrite(LED_PIN, LOW);
digitalWrite(LED_BLINK_PIN, LOW);
led2ReadRec = 1000;
Serial.println("System Reseted!");
}
vTaskDelay(35);
}
}

ANEXA 2

Cod sursă. Sistem secvențial

#include <Arduino.h>
#include "timer-api.h"
#include <stdio.h>

#define BUTTON_PIN 13
#define BUTTON_LED_INCR 10
#define BUTTON_LED_DECR 11
#define BUTTON_PRESSED 0
#define BUTTON_NOT_PRESSED 1
#define LED_PIN 4
#define LED_BLINK_PIN 5
#define LED_ON 1
#define LED_OFF 0
#define TASK_REC 2
#define TASK_OFFSET 5

int led2Rec = 0;
int ledState = 0;
int led2State = 0;
int buttonState = 0;
int led2ReadRec = 0;

void setup() {
// put your setup code here, to run once:
pinMode(LED_PIN, OUTPUT);
pinMode(LED_BLINK_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode(BUTTON_LED_DECR, INPUT);
pinMode(BUTTON_LED_INCR, INPUT);
//timer_init_ISR_1Hz(TIMER_DEFAULT);
timer_init_ISR_2Hz(TIMER_DEFAULT);
Serial.begin(9600);
led2Rec = TASK_OFFSET;
}

void taskLedWithButton() // change led1 state when press button


{
buttonState = digitalRead(BUTTON_PIN);
if(buttonState == BUTTON_PRESSED)
{
if(ledState == 1)
{
ledState = 0;
}
else
{
ledState = 1;
digitalWrite(LED_BLINK_PIN, LOW);
}
digitalWrite(LED_PIN, ledState);
}
}

void taskLedBlink() // blinking led


{
if(ledState == 0)
{
if(led2State == 0)
{
led2State = 1;
digitalWrite(LED_BLINK_PIN, HIGH);
}
else
{
led2State = 0;
digitalWrite(LED_BLINK_PIN, LOW);
}
}
}

void taskButton2LedReadRec() // read recurency for blink led


{
if(digitalRead(BUTTON_LED_INCR) == BUTTON_PRESSED)
{
led2ReadRec++;
}
if(digitalRead(BUTTON_LED_DECR) == BUTTON_PRESSED)
{
led2ReadRec--;
}
}

void timer_handle_interrupts(int timer)


{
taskLedWithButton();
taskButton2LedReadRec();
if(--led2Rec <= 0){
taskLedBlink();
led2Rec = led2ReadRec;
}
}

void loop()
{
Serial.println();
Serial.print("Led state: ");
Serial.println(ledState);
Serial.print("Led 2 state: ");
Serial.println(led2State);
Serial.print("Led2 offset: ");
Serial.println(led2Rec);
Serial.print("Read rec for led2: ");
Serial.println(led2ReadRec);
delay(1000);
// put your main code here, to run repeatedly:
}

S-ar putea să vă placă și