0% found this document useful (0 votes)
99 views

Problem e Lab

The document describes several C programs that: 1. Display the scan and ASCII codes of a pressed key by installing a custom interrupt handler for the keyboard. 2. Displays the last pressed key every 2 seconds by installing custom interrupt handlers for the keyboard and timer. 3. Plays a melody by sending tone signals when ALT+H is pressed using custom interrupt handlers. 4. Creates three tasks (T1, T2, T3) with different priorities that toggle LEDs and have T2 or T3 destroy T1 to take the processor.

Uploaded by

aleahim576
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
99 views

Problem e Lab

The document describes several C programs that: 1. Display the scan and ASCII codes of a pressed key by installing a custom interrupt handler for the keyboard. 2. Displays the last pressed key every 2 seconds by installing custom interrupt handlers for the keyboard and timer. 3. Plays a melody by sending tone signals when ALT+H is pressed using custom interrupt handlers. 4. Creates three tasks (T1, T2, T3) with different priorities that toggle LEDs and have T2 or T3 destroy T1 to take the processor.

Uploaded by

aleahim576
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 60

L1.P3.

Sa se scrie un program care, la apasarea unei taste, afiseaza codurile SCAN si ASCII ale
tastei

apasate. Cele doua coduri vor fi preluate din zona tampon a tastaturii.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

int loop;

void interrupt (*oldfunc)();

//noua rutina de tratare intrerupere

void interrupt func()

loop++;

(*oldfunc)();

void main()

int off_coada,next;

char coda,cods;

loop = 0; next = 0;

oldfunc=getvect(9);

setvect(9,func); //instalare rutina proprie

puts("Apasati taste! Pentru iesire, apasati ESC");

while (loop == 0);

while (1)

{
1
if (next<loop)

off_coada = peek(0x040,0x1c);

if (off_coada == 0x1e)

cods = peekb(0x40,0x3d);

coda = peekb(0x40,0x3c);

else

cods = peekb(0x40,off_coada-1);

coda = peekb(0x40,off_coada-2);

printf("\nCodul SCAN este: %x",cods);

printf("\nCodul ASCII este: %x",coda);

next = next + 2;

if (loop == 20) break;

puts("Gata!");

setvect(9,oldfunc);

getch();

L2.P3. Scrieti un program care la fiecare 2. 2 secunde sa afiseze care a fost ultima tasta
apasata de

utilizator (se va instala si o rutina proprie pentru tratarea intreruperii de tastatura).

#include <stdio.h>

#include <dos.h>
2
#include <conio.h>

void interrupt (*oldc)();

void interrupt (*oldt)();

int c=0;

int flag=0;

void interrupt funcc()

c++;

if(c==40)

flag=1;

c=0;

(*oldc)();

void interrupt funct()

(*oldt)();

main()

int i;

int codscan;

clrscr();

oldclk=getvect(8);

setvect(8,funcc);

oldtst=getvect(9);

setvect(9,funct);

3
for(i=1;i<=5;i++)

while(flag==0)

{}

if(nr>0)

codscan=inportb(0x60);

printf("cod scan al ultimei taste apasate:%d\n",codscan);

nr=0;

flag=0;

while(flag==0)

{}

setvect(9,oldt);

setvect(8,oldc);

L3.P2. Sa se realizeze un program C care la fiecare apasare a tastelor ALT H sa cânte o melodie
(se vor

trimite în ordine catre bell semnale de frecventa 100Hz, 1500Hz, 2000Hz, fiecare pentru un
interval

de 1.1 sec). Apasarea tastelor pe durata interpretarii meoldiei este neglijata. Programul va
instala

rutina proprie de ceas si tastatura.

#include <stdio.h>

#include <dos.h>

#include <conio.h>

4
void interrupt (*oldceas)();

void interrupt (*oldtast)();

unsigned int flag, flag_cald, flagc;

int contor=20;

char c;

void interrupt newtast(void)

c=inport(0x60);

if((c&0x7f)==0x38)

flag=1;

else

if(c==0x23&&flag==1)

flag_cald=1;

else

flag=0;

(*oldtast)();

void interrupt newceas(void)

contor--;

if(contor==0)

contor=20;

flagc=1;

(*oldceas)();

5
void suna(int frecventa)

int c_div;

c_div=1190000L/frecventa;

printf("cdiv=%d\n", c_div);

outportb(0x43,0xb6);

outportb(0x42, c_div%256);

outportb(0x42,c_div/256);

outportb(0x61,inportb(0x61)|0x03);

while(flagc==0);

outportb(0x61, inportb(0x61)&0xfc);

flagc=0;

void main(void)

int i;

clrscr();

oldceas=getvect(0x08);

setvect(8,newceas);

oldtast=getvect(9);

setvect(9,newtast);

printf("Apasa ALT+H");

while((c&0x7f)!=0x01)

if(flag_cald==1)

6
{

suna(100);

suna(1500);

suna(2000);

flag_cald=0;

setvect(9,oldtast);

setvect(8,oldceas);

L4.P3. Realizati o aplicatie in care taskul T1 (prioritate 2) creeaza Task T2 dupa 1 sec, Task T3

dupa 2 sec, iar ulterior este distrus de primul task creat (T2 sau T3) care preia procesorul.

Task T2 (prioritate 3) trebuie sa modifice starea ledului 15 la fiecare 2 sec. Task T3

(prioritate 2) trebuie sa modifice starea ledului 14 la fiecare 1sec.

Indicati ordinea de executie a taskurilor si verificati experimental. Se va considera modul

preemtiv.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

7
/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

xTaskHandle *t1;

void Task1(void *params);

void Task2(void *params);

void Task3(void *params);

void Task1(void *params) {

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

vTaskDelay(1000);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

vTaskDelay(1000);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

8
}

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

vTaskDelete(t1); // stergere Task1

vParTestToggleLED(15);

vTaskDelay(2000);

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

vTaskDelete(t1); // stergere Task1

vParTestToggleLED(14);

vTaskDelay(1000);

void Task4(void *params)

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

vParTestToggleLED(12);

9
vTaskDelay(1000);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, t1);

//xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

//xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

//xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

10
CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

5.2. Realizati o aplicatie cu trei task-uri T1 (prioritate 1, perioada 2s), T2 (prioritate 1,


perioada

0.5s) si T3 (prioritate 3, perioada 250ms). Task-ul T1 va comuta starea LED-ului 15 iar taskul

T2 va comuta starea LED-ului 14. Task-ul T3 va citi prioritatile celorlalte doua task-uri

cu ajutorul serviciului uxTaskPriorityGet si va salva valorile in doua variabile globale

numite prioT1 si prioT2. Tot task-ul T3 va incrementa cu 2 valorile prioritatilor task-urilor

T1 si T2, atunci cind au trecut 12345 tick-uri de la lansarea planificatorului. Valorile


11
variabilelor prioT1 si prioT2 vor fi puse in evidenta in permanenta prin intermediul

facilitatilor de depanare oferite de mediul MPLAB. Indicati ordinea de executie a taskurilor

si verificati experimental. Se va considera modul preemtiv.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

int prioT1,prioT2;

xTaskHandle *t1,*t2;

void Task1(void *params) {

for (;;)

12
{

//PORTBbits.RB15 = ~PORTBbits.RB15;

vParTestToggleLED(15);

vTaskDelay(2000);

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

vParTestToggleLED(14);

vTaskDelay(500);

void Task3(void *params) {

volatile portTickType nr;

portTickType xLastWakeTime;

xLastWakeTime = xTaskGetTickCount();

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

// vParTestToggleLED(13);

prioT1=uxTaskPriorityGet(t1);

prioT2=uxTaskPriorityGet(t2);

//vTaskDelayUntil( &xLastWakeTime, 12345);

nr=xTaskGetTickCount();

if(nr==12345){

13
vTaskPrioritySet(t1,prioT1+2);

vTaskPrioritySet(t2,prioT2+2);

void Task4(void *params)

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

vParTestToggleLED(12);

vTaskDelay(1000);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, t1);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, t2);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

// xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

14
/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

15
{

//ADPCFG = 0xFFFF; //make ADC pins all digital – adaugat


vParTestInitialise();

initPLL();

L5P3. Realizati o aplicatie cu doua taskuri T1 si T2. T1 (prioritate 1) trebuie sa modifice starea

ledului 15 la fiecare 2,5 sec, iar T2 (prioritate 3) trebuie sa modifice starea ledului 12 la

fiecare 0,5 sec. Task-ul T2 va crea la 4 secunde de la pornirea aplicatiei task-ul T3

(prioritate 2, perioada 1s) ce comuta starea ledului 13 la fiecare perioada a sa. Task-ul T3 va

fi suspendat de catre task-ul T1 la 10 secunde de la pornirea aplicatiei si reactivat la 15

secunde de la pornirea aplicatiei. Indicati ordinea de executie a taskurilor si verificati

experimental. Se va considera modul preemtiv.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure


16
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

int contorT1=0;

int contorT2=0;

xTaskHandle handle_Ts1;

xTaskHandle handle_Ts2;

xTaskHandle handle_Ts3;

int T3_creat=0;

int T3_suspendat=0;

void Task3(void *params);

void Task1(void *params);

void Task1(void *params) {

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

contorT1++;

vParTestToggleLED(15);

vTaskDelay(2500);

if(contorT1==4 && T3_creat==1)

17
vTaskSuspend(Handle_T3);

T3_suspendat=1;

if(contorT1==6 && T3_suspendat==1)

vTaskResume(Handle_T3);

T3_suspendat=0;

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

contorT2++;

vParTestToggleLED(12);

vTaskDelay(500);

if(contorT2==8)

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, xTaskHandle *Handle_T3);

void Task3(void *params) {


18
for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

T3_creat=1;

vParTestToggleLED(13);

vTaskDelay(1000);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

19
// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

L7P1. Realizaţi o aplicaţie cu doua task-uri T1 si T2. Task-ul T1 transmite mesaje către T2 la

fiecare 500ms. Conţinutul mesajului va fi o valoare întreagă incrementată la fiecare activare

a task-ului T1 şi va fi afişat de către task-ul T2 pe LED-urile conectate la pinii 15, 14 , 13 şi

20
12 ai portului B al microcontroller-ului. Priorităţile task-urilor si modul de comunicatie intre

task-uri (implementat in varianta proprie) vor fi alese astfel încât toate mesajele să fie

prelucrate corect.

P2. Modificati aplicatia dezvoltata la punctul 1 astfel incit comunicatia intre task-uri sa se

execute cu ajutorul cozilor de mesaje implementate in FreeRTOS si a serviciilor specifice

acestora. Timpii de aşteptare folosiţi în operaţiunile cu coada, lungimea cozii precum şi

priorităţile task-urilor vor fi alese astfel încât toate mesajele să fie prelucrate corect.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

21
static void prvSetupHardware( void );

unsigned int msj_T1 = 0;

unsigned int msj_T2 = 0;

unsigned int msj_T3 = 0;

unsigned int msj_citit_T2 = 0;

unsigned int msj_citit_T4 = 0;

xQueueHandle xQueue1;

xQueueHandle xQueue2;

void Task1(void *params) {

for (;;)

contor_T1++;

msj_T1++;

xQueueSend( xQueue1, &msj_T1, 10 );

vTaskDelay(500);

void Task2(void *params) {

for (;;)

xQueueReceive( xQueue1, &msj_citit_T2, 10)

PORTB = PORTB | 0x0FFF0;

PORTB = PORTB & (~(msj_citit_T2 << 12 ));

vTaskDelay(500);

22
msj_T2 = ( ( msj_T2 + 1000 ) % 3000 ) + 1000;//se variaza de la 1 sec la 3 sec

xQueueSend( xQueue2, &msj_T2, (portTickType) 10 );

void Task3(void *params) {

for (;;)

msj_T3++;

xQueueSend( xQueue1, &msj_T3, (portTickType) 10 );

vTaskDelay(10000);

void Task4(void *params) {

for (;;)

xQueueReceive( xQueue2, &msj_citit_T4,10)

vTaskDelay(msj_citit_T4);

PORTBbits.RB0 = ~PORTBbits.RB0;

23
int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

xQueue1 = xQueueCreate(10,sizeof(char *));

xQueue2 = xQueueCreate(1,sizeof(char *));

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

24
// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

L7.P3. Modificaţi aplicaţia creată la exerciţiul precedent astfel încât să mai existe două task-
uri (T3

şi T4). Task-ul T3 depune mesaje în coadă cu o perioadă de 10s. Task-ul T4 va primi mesaje

de la T2 prin intermediul unei cozi de un element şi va comuta LED-ul conectat la pinul 0 al

portului B cu perioada indicată de conţinutul mesajului primit (1-3s). Toate mesajele

recepţionate de T2 vor avea un câmp suplimentar ce va indica destinatarul final al mesajului

(T2 – valoarea 1 sau T4 – valoarea 2).


25
#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

xQueueHandle myQueue, myQueue2;

struct AMessage {

portCHAR ucMessageID;

portCHAR ucData[ 20 ];

} xMessage;

int inc=0;

portBASE_TYPE msg,msg2;

26
void Task1(void *params) {

struct AMessage *pxMessage;

int k=1;

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

if(k%15==1){

if(inc > 15) inc = 0; else inc++;

pxMessage = inc;

xQueueSend( myQueue, ( void * ) &pxMessage, ( portTickType ) 10 );

vTaskDelay(500);

k++;

void Task2(void *params) {

struct AMessage *pxMessage;

int l=1,t=1,change=0;

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

//vParTestToggleLED(14);

if(l%2==1){

if(inc > 3) t = 1; else t++;

27
if(l%1==1){

if(change == 1) change = 2; else change=1; //destinatarul mesajului T4 / T2

xQueueReceive( myQueue, &msg, (portTickType) 10 );

if(change == 1){ // trimitere mesaj la destinatar

PORTB = (msg&&0xF000)<<12;

} else if(change == 2){

pxMessage = t;

xQueueSend( myQueue2, ( void * ) &pxMessage, ( portTickType ) 10 );

vTaskDelay(15000);

l++;

void Task3(void *params) {

struct AMessage *pxMessage;

int m=1;

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

//vParTestToggleLED(13);

//xQueueSend( myQueue2, ( void * ) &pxMessage, ( portTickType ) 10 );

if(m%15==1){

if(inc > 15) inc = 0; else inc++;

pxMessage = inc;

xQueueSend( myQueue, ( void * ) &pxMessage, ( portTickType ) 10 );

28
vTaskDelay(10000);

m++;

void Task4(void *params)

int switchled = 0,old_msg=1;

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

xQueueReceive( myQueue, &msg2, (portTickType) 10 );

if(msg2 != old_msg) vParTestToggleLED(0); else old_msg = msg2; // se schimba starea


pinului 0 din PORTB atunci cand apare alt mesaj

vTaskDelay(msg2*1000);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

myQueue = xQueueCreate( 10, sizeof( unsigned portLONG ) );

if(myQueue == 0){

// eroare la creare coada

myQueue2 = xQueueCreate( 1, sizeof( unsigned portLONG ) );

if(myQueue2 == 0){
29
// eroare la creare coada 2

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 4, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

30
// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

8.1. Realizaţi o aplicaţie cu patru task-uri: T1, T2, T3 si T4. Task-urile T1, T2 si T3 au

perioadele de 1s, 2s si respectiv 3s si transmit mesaje către task-ul T4 prin intermediul unei

cozi de mesaje. Fiecare mesaj va fi format din trei valori intregi reprezentind identificatorul

task-ului expeditor (1,2,3 sau 4), o valoare intreaga (intre 1 si 15) ce va fi afisata pe LEDurile

conectate la pinii 15, 14 , 13 şi 12 ai portului B al microcontroller-ului si respectiv

timpul minim pentru care trebuie afisata cea de a doua valoare. Timpii de aşteptare folosiţi

în operaţiunile cu coada, lungimea cozii precum şi priorităţile task-urilor vor fi alese astfel

încât toate mesajele să fie prelucrate corect. Sa se evidentieze in MPLAB valorile mesajelor

transmise prin folosirea programatoarelor ICD2 ca depanatoare.

#include <stdio.h>

/* Scheduler includes. */

31
#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

typedef struct {

int val;

int exp;

int delay;

} xMessage;

xQueueHandle myQueue;

xMessage msg = {0,0,0};

void Task1(void *params) {

for (;;)

32
//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

//if(msg.val > 15) msg.val = 0; else msg.val++;

msg.exp = 1;

msg.delay = 1000;

xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

vTaskDelay(1000);

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

//vParTestToggleLED(14);

//if(msg.val > 15) msg.val = 0; else msg.val++;

msg.exp = 2;

msg.delay = 2000;

xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

vTaskDelay(2000);

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

//vParTestToggleLED(13);

//if(msg.val > 15) msg.val = 0; else msg.val++;

33
msg.exp = 3;

msg.delay = 3000;

xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

vTaskDelay(3000);

void Task4(void *params)

xMessage outmsg;

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

//vParTestToggleLED(12);

//vTaskDelay(1000);

xQueueReceive( myQueue, &outmsg, (portTickType) 4000 );

if(msg.exp == 1) vParTestToggleLED(15);

else if(msg.exp == 2) vParTestToggleLED(14);

else if(msg.exp == 3) vParTestToggleLED(13);

else if(msg.exp == 4) vParTestToggleLED(12);

//PORTB = (outmsg.val&&0xF000)<<12;

//PORTB=~(outmsg.val<<12);

int main( void )

/* Configure any hardware required for this demo. */

34
prvSetupHardware();

myQueue = xQueueCreate( 20, sizeof( xMessage * ) );

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 4, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

35
// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

8.3. Modificati aplicatia de la primul exercitiu astfel incit task-urile T1 si T2 sa depuna mesaje
in

coada, T4 sa afiseze valoarea intreaga (intre 1 si 15) pe LED-urile conectate la pinii 15, 14 ,

13 şi 12 ai portului B al microcontroller-ului iar T3 sa citeasca (fara a-l sterge) primul mesaj

disponibil din coada cu o frecventa de 0.5s, continutul acestuia fiind salvat intr-o variabila

globala. In cazul in care coada este vida, elementele variabilei globale vor primi valoarea 0.

Determinati si analizati in ce cazuri coada poate sa fie vida si in ce cazuri coada poate

acumula elemente.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"
36
#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

typedef struct {

int val;

int exp;

int delay;

} xMessage;

xQueueHandle myQueue;

int firstMsg;

xMessage msg = {0,0,0};

void Task1(void *params) {

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

37
if(msg.val > 15) msg.val = 0; else msg.val = msg.val+1;

msg.exp = 1;

msg.delay = 1000;

xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

vTaskDelay(1000);

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

//vParTestToggleLED(14);

if(msg.val > 15) msg.val = 0; else msg.val = msg.val+2;

msg.exp = 2;

msg.delay = 2000;

xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

vTaskDelay(2000);

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

//vParTestToggleLED(13);

//if(msg.val > 15) msg.val = 0; else msg.val++;

// msg.exp = 3;

//msg.delay = 3000;

38
//xQueueSend( myQueue, ( void * ) &msg, ( portTickType ) 10 );

if(uxQueueMessagesWaiting(myQueue) > 0){

xQueuePeek(myQueue, ( void * ) firstMsg, ( portTickType ) 10 ); // citeste mesajul


din coada fara sa-l stearga

} else {

firstMsg = 0;

vTaskDelay(500);

void Task4(void *params)

xMessage outmsg;

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

//vParTestToggleLED(12);

//vTaskDelay(1000);

xQueueReceive( myQueue, &outmsg, (portTickType) 4000 );

/*

if(msg.exp == 1) vParTestToggleLED(15);

else if(msg.exp == 2) vParTestToggleLED(14);

else if(msg.exp == 3) vParTestToggleLED(13);

else if(msg.exp == 4) vParTestToggleLED(12);

*/

//PORTB = (outmsg.val&&0xF000)<<12;
39
PORTB=~(outmsg.val<<12);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

myQueue = xQueueCreate( 20, sizeof( xMessage * ) );

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 4, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

40
CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

9.1. Realizati o aplicatie in care sa folositi un semafor binar pentru implementarea


sincronizarii

intre doua task-uri. Task-ul T1, cu perioada de 0,5s, va comuta starea LED-ului conectat la

pinul RB14 al microcontroller-ului. Task-ul T2 va comuta starea LED-ului conectat la pinul

RB12 atunci cind va aparea un eveniment semnalat (prin intermediul semaforului) de catre

task-ul T1. Evenimentele vor fi simulate prin intermediul unui vector, fiecare element al

vectorului indicand la a cita executare a task-ului T1 apare evenimentul corespunzator.


41
Puneti in evidenta functionarea semaforului prin intermediul facilitatilor de depanare ale

dispozitivelor ICD2.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

#include "semphr.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

int v[4] = {20,30,40,50};

int i,j;

void Task1(void *params) {

for (;;)

42
{

vParTestToggleLED(14);

for(j=1; j<=4; j++){

for(i=1;i<v[j])

xSemaphoreGive(mySemaphore);

vTaskDelay(500);

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

if(xSemaphoreTake(mySemaphore, 60) == true) vParTestToggleLED(12);

//vTaskDelay(2000);

/*

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

vParTestToggleLED(13);

vTaskDelay(1000);

43
}

void Task4(void *params)

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

vParTestToggleLED(12);

vTaskDelay(1000);

*/

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

vSemaphoreCreateBinary(mySemaphore);

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

//xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

//xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

/* Finally start the scheduler. */

44
vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

45
//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

L10.P1. Realizaţi o aplicaţie cu patru task-uri T1, T2, T3 si T4 ce au perioadele de 1s, 1,5s, 2s si

respectiv 3s si afiseaza cite o valoare intreaga (intre 1 si 15) pe LED-urile conectate la pinii

15, 14 , 13 şi 12 ai portului B al microcontroller-ului pentru un interval de timp minim,

corespunzator fiecarui task. Controlul accesului la LED-uri va fi facut prin intermediul unui

mutex. Timpii minimi de afisare şi priorităţile task-urilor vor fi alese astfel încât sa se poata

pune in evidenta controlul accesului la resursa partajata. Puneti in evidenta functionarea

mutex-ului prin intermediul facilitatilor de depanare ale dispozitivelor ICD2.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

#include "semphr.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

46
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

void Task1(void *params);

void Task2(void *params);

void Task3(void *params);

void Task4(void *params);

static void prvSetupHardware( void );

xSemaphoreHandle mySemMutex = NULL;

void Task1(void *params) {

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

if(xSemaphoreTake(mySemMutex, 0xFFFF) == pdTRUE){

PORTB = ((PORTB&0xFFFF)|0<<12)^0xFFFF;

vTaskDelay(500);

xSemaphoreGive(mySemMutex);

vTaskDelay(500);

void Task2(void *params) {

for (;;)

47
//PORTBbits.RB14 = ~PORTBbits.RB14;

//vParTestToggleLED(14);

if(xSemaphoreTake(mySemMutex, 0xFFFF) == pdTRUE){

PORTB = ((PORTB&0xFFFF)|1<<12)^0xFFFF;

vTaskDelay(500);

xSemaphoreGive(mySemMutex);

vTaskDelay(1000);

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

//vParTestToggleLED(13);

if(xSemaphoreTake(mySemMutex, 0xFFFF) == pdTRUE){

PORTB = ((PORTB&0xFFFF)|2<<12)^0xFFFF;

vTaskDelay(500);

xSemaphoreGive(mySemMutex);

vTaskDelay(1500);

void Task4(void *params)

for (;;)

48
//PORTBbits.RB12 = ~PORTBbits.RB12;

//vParTestToggleLED(12);

if(xSemaphoreTake(mySemMutex, 0xFFFF) == pdTRUE){

PORTB = ((PORTB&0xFFFF)|3<<12)^0xFFFF;

vTaskDelay(500);

xSemaphoreGive(mySemMutex);

vTaskDelay(2500);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

mySemMutex = xSemaphoreCreateMutex();

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 2, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 3, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 4, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

49
}

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

50
}

1. Utilizand-se exemplul de lucru cu intreruperea INT0, sa se modifice aplicatia initiala din

laborator astfel incit starea LED-ului conectat la pinul RB12 al microcontroller-ului sa fie

comutata la fiecare intrerupere INT0 generata de apasarea butonului conectat la pinul

RB7/INT0. Task-urile Task1, Task2 si Task3 vor pastra caracteristicile din aplicatia initiala.

2. Sa se modifice aplicatia dezvoltata la exercitiul 1 astfel incit task-ul Task4 sa suspende


taskul

Task3 la fiecare 10 secunde. Task-ul Task3 va fi scos din starea de suspendat la aparitia

intreruperii INT0.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software


51
static void prvSetupHardware( void );

void __attribute__ ((interrupt, no_auto_psv)) _INT0Interrupt(void)

// P2

// ceva = xTaskResume(handler t3)

vParTestToggleLED(12);

IFS0bits.INT0IF = 0;// Resetam flagul corespunzator intreruperii

// INT0 pentru a nu se reapela rutina de intrerupere

void Task1(void *params) {

for (;;)

//PORTBbits.RB15 = ~PORTBbits.RB15;

//vParTestToggleLED(15);

//vTaskDelay(3000);

void Task2(void *params) {

for (;;)

//PORTBbits.RB14 = ~PORTBbits.RB14;

//vParTestToggleLED(14);

52
//vTaskDelay(2000);

void Task3(void *params) {

for (;;)

//PORTBbits.RB13 = ~PORTBbits.RB13;

//vParTestToggleLED(13);

//vTaskDelay(1000);

// P2

// handler T4

void Task4(void *params)

for (;;)

//PORTBbits.RB12 = ~PORTBbits.RB12;

//vParTestToggleLED(12);

//vTaskDelay(1000);

// P2

//vTaskDelay(10000);

//vTaskSuspend();

53
int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

RCONbits.SWDTEN = 0;

TRISB = 0x00FF;

LATB = 0x0E000;

IFS0bits.INT0IF = 0; // Resetem flagul coresp. intreruperii INT0

IEC0bits.INT0IE = 1; // Se permite lucrul cu întreruperea INT0

INTCON2 = 0x0001; // Se stabileste pe ce front se genereaza INT0

xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

54
{

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

1. Sa se modifice aplicatia de la numarul 2 a referatului de laborator 12 astfel incat valoarea

contorului sa fie modificata in interiorul task-ului T1, modificarea fiind sincronizata cu

55
aparitia intreruperii INT0. Sincronizarea se va face prin intermediul unui semafor binar.

#include <stdio.h>

/* Scheduler includes. */

#include "FreeRTOS.h"

#include "semphr.h"

#include "task.h"

#include "queue.h"

#include "croutine.h"

/* Demo application includes. */

#include "partest.h"

// Select Internal FRC at POR

_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure

_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); // FRC + PLL

//_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // XT + PLL

_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

static void prvSetupHardware( void );

//xQueueHandle pxQueue;

xSemaphoreHandle xSemafor1;

xSemaphoreHandle xSemafor2;

portBASE_TYPE pxHPTW;

56
void __attribute__ ((interrupt, no_auto_psv)) _INT0Interrupt(void)

IFS0bits.INT0IF = 0;// Resetam flagul corespunzator intreruperii

xSemaphoreGiveFromISR(xSemafor1,&pxHPTW);

if(pxHPTW==pdTRUE) taskYIELD();

void Task1(void *params) {

for (;;)

if(xSemaphoreTake(xSemafor1,(portTickType)0xFFFF)==pdTRUE)

if(xSemaphoreTake(xSemafor2,(portTickType)0xFFFF)==pdTRUE){

PORTB=((PORTB&0x0FFF)|(0x0A<<12))^0xF000;

vTaskDelay(500);

xSemaphoreGive(xSemafor2);

void Task2(void *params){

int val=0;

portTickType xLastWakeTime;

xLastWakeTime=xTaskGetTickCount();

for (;;)

val++;

val=val%15;

if(xSemaphoreTake(xSemafor2,(portTickType)0xFFFF)==pdTRUE){

57
PORTB=((PORTB&0x0FFF)|(val<<12))^0xF000;

vTaskDelay(500);

xSemaphoreGive(xSemafor2);

vTaskDelayUntil(&xLastWakeTime,1500);

int main( void )

/* Configure any hardware required for this demo. */

prvSetupHardware();

TRISB = 0x00FF;

LATB = 0x0E000;

IFS0bits.INT0IF = 0; // Resetem flagul coresp. intreruperii INT0

IEC0bits.INT0IE = 1; // Se permite lucrul cu întreruperea INT0

INTCON2 = 0x0001; // Se stabileste pe ce front se genereaza INT0

//pxQueue=xQueueCreate(1,sizeof(int));

vSemaphoreCreateBinary(xSemafor1);

vSemaphoreCreateBinary(xSemafor2);

if(xSemafor1!=NULL) {

// semafor creat cu succes.

if(xSemafor2!=NULL) {

// semafor creat cu succes.

58
xTaskCreate(Task1, (signed portCHAR *) "Ts1", configMINIMAL_STACK_SIZE, NULL,
tskIDLE_PRIORITY + 1, NULL);

xTaskCreate(Task2, (signed portCHAR *) "Ts2", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

// xTaskCreate(Task3, (signed portCHAR *) "Ts3", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

// xTaskCreate(Task4, (signed portCHAR *) "Ts4", configMINIMAL_STACK_SIZE, NULL,


tskIDLE_PRIORITY + 1, NULL);

/* Finally start the scheduler. */

vTaskStartScheduler();

return 0;

/*-----------------------------------------------------------*/

void initPLL(void)

// Configure PLL prescaler, PLL postscaler, PLL divisor

PLLFBD = 41; // M = 43 FRC

//PLLFBD = 30; // M = 32 XT

CLKDIVbits.PLLPOST=0; // N1 = 2

CLKDIVbits.PLLPRE=0; // N2 = 2

// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)

__builtin_write_OSCCONH(0x01); // FRC

//__builtin_write_OSCCONH(0x03); // XT

__builtin_write_OSCCONL(0x01);

// Wait for Clock switch to occur

while (OSCCONbits.COSC != 0b001); // FRC

59
//while (OSCCONbits.COSC != 0b011); // XT

// Wait for PLL to lock

while(OSCCONbits.LOCK!=1) {};

static void prvSetupHardware( void )

//ADPCFG = 0xFFFF; //make ADC pins all digital - adaugat

vParTestInitialise();

initPLL();

60

You might also like