EMS 20 Week 4 Lab 2 Leerdoelen Week
EMS 20 Week 4 Lab 2
Leerdoelen Week 4 Lab 2 EMBEDDED SYSTEMS Leerdoelen week 4 lab 2. Je leert: • • • wat de POSIX standaard is; hoe je taken met behulp van pthreads (POSIX-threads) concurrent kan uitvoeren; hoe pthreads met elkaar kunnen communiceren met behulp van een message queue (mqueue). 2
Vorige lab: TI-RTOS EMBEDDED SYSTEMS TI-RTOS • Je kunt taken (threads) definiëren die concurrent worden uitgevoerd. • Deze taken kunnen met elkaar communiceren met behulp van mailboxen. • Taken worden statisch aangemaakt d. m. v. een config file (m. b. v. een GUI). • Mailboxen (en andere resources) worden ook statisch aangemaakt. 3
Dit lab: POSIX EMBEDDED SYSTEMS POSIX • Portable Operating System Interface (POSIX) is een standaard API voor OSen. • Veel OSen conformen zich (gedeeltelijk) aan deze standaard. Bijvoorbeeld: Linux, Android, OSX, Vx. Works, QNX Neurtino, TI-RTOS enz. • Taken worden dynamisch aangemaakt d. m. v. API calls. • Message Queues (en andere resources) worden ook dynamisch aangemaakt. 4
C EMBEDDED SYSTEMS POSIX maakt gebruik van features uit C die je nog niet (goed) kent: • Pointers naar functies • void pointers 5
Pointers naar functies EMBEDDED SYSTEMS In C kun je een pointer naar een functie definiëren. • De waarde van de pointer is het beginadres (van de code) van de functie. pnf is een pointer naar een functie met #include <stdio. h> int kwadraat(int c) { return c * c; } int dubbel(int c) { return c + c; } een int als parameter en een int returnwaarde int main(void) { int a = 7, b; int (*pnf)(int); pnf = &dubbel; b = (*pnf)(a); Waarom haakjes? 6
Pointers naar functies EMBEDDED SYSTEMS In C kun je een pointer naar een functie definiëren. • De waarde van de pointer is het beginadres (van de code) van de functie. #include <stdio. h> int kwadraat(int c) { return c * c; } int dubbel(int c) { return c + c; } pnf wijst naar de functie dubbel (pnf wordt gelijk aan het adres van de functie dubbel) int main(void) { int a = 7, b; int (*pnf)(int); pnf = &dubbel; b = (*pnf)(a); 7
Pointers naar functies EMBEDDED SYSTEMS In C kun je een pointer naar een functie definiëren. • De waarde van de pointer is het beginadres (van de code) van de functie. De functie waar pnf naar wijst #include <stdio. h> int kwadraat(int c) { return c * c; } int dubbel(int c) { return c + c; } wordt aangeroepen met de waarde van a als argument int main(void) { int a = 7, b; int (*pnf)(int); pnf = &dubbel; b = (*pnf)(a); Waarom haakjes? source 8
Pointers naar functies EMBEDDED SYSTEMS Verkorte schrijfwijze. • Naam van een functie beginadres (van de code) van de functie. #include <stdio. h> int kwadraat(int c) { return c * c; } int dubbel(int c) { return c + c; } int main(void) { int a = 7, b; int (*pnf)(int); pnf = dubbel; b = pnf(a); source 9
Pointers naar functies EMBEDDED SYSTEMS Wat is het nut? • Functie als parameter. #include <stdio. h> /* … */ void print. Tabel(int (*p)(int), int van, int tot, int stap) { for (int x = van; x < tot; x += stap) { printf("%10 dn", x, (*p)(x)); } } int main(void) { printf("De kwadraten van 1 t/m 10n"); print. Tabel(&kwadraat, 1, 1); printf("De dubbelen van de drievouden van 0 t/m 30n"); print. Tabel(&dubbel, 0, 31, 3); source 10
Uitvoer De kwadraten van 1 t/m 10 1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100 De dubbelen van de drievouden van 0 t/m 30 0 0 3 6 6 12 9 18 12 24 15 30 18 36 21 42 24 48 27 54 30 60 EMBEDDED SYSTEMS
void * EMBEDDED SYSTEMS • • Een void * kan wijzen naar elk type. Als je de waarde wilt ophalen waar een void * naar wijst dan moeten we de pointer casten naar het juiste type. int main(void) { int i = 3; double d = 4. 3; void* vp = &i; printf("%dn", *(int*)vp); vp = &d; printf("%lfn", *(double*)vp); return 0; } source
Pthread (1 van 2) #include <pthread. h> void *taak 1(void *) { for (int i = 0; i < 10; i++) { usleep(100000); puts("Taak 1 zegt: hallo"); } return NULL; } void *taak 2(void *) { for (int i = 0; i < 10; i++) { usleep(200000); puts("Taak 2 zegt: ook hallo"); } return NULL; } EMBEDDED SYSTEMS 13
Pthread (2 van 2) EMBEDDED SYSTEMS int main(void) { Board_init(); pthread_t t 1, t 2; pthread_create(&t 1, NULL, &taak 1, NULL); pthread_create(&t 2, NULL, &taak 2, NULL); puts("Ready. . . Go!"); BIOS_start(); return 0; Kan gebruikt worden om attributen (b. v. prioriteit) door te geven (zie labopdracht). } Returnwaarde moet gecontroleerd worden. (0 = OK, !0 = errornummer). 14 source
Uitvoer [Cortex_M 4_0] Ready. . . Go! Taak 1 zegt: hallo Taak 2 zegt: ook hallo Taak 1 zegt: hallo Taak 1 zegt: hallo Taak 2 zegt: ook hallo Taak 2 zegt: ook hallo EMBEDDED SYSTEMS
Pthread met parameter (1 van 2) EMBEDDED SYSTEMS typedef struct { char *msg; long us; int times; } par_t; void *taak(void *pp) { par_t p = *(par_t *)pp; for (int i = 0; i < p. times; i++) { usleep(p. us); puts(p. msg); } return NULL; } 16
Pthread met parameter (2 van 2) EMBEDDED SYSTEMS int main(void) { Board_init(); pthread_t t 1, t 2; par_t p 1 = {"Taak 1 zegt: hallo", 100000, 9}; par_t p 2 = {"Taak 2 zegt: ook hallo", 200000, 11}; pthread_create(&t 1, NULL, &taak, &p 1); pthread_create(&t 2, NULL, &taak, &p 2); puts("Ready. . . Go!"); BIOS_start(); return 0; } 17 source
Uitvoer [Cortex_M 4_0] Ready. . . Go! Taak 1 zegt: hallo Taak 2 zegt: ook hallo Taak 1 zegt: hallo Taak 1 zegt: hallo Taak 2 zegt: ook hallo Taak 2 zegt: ook hallo EMBEDDED SYSTEMS
Communicatie via mqueue (1 van 2) EMBEDDED SYSTEMS int main(void) { Board_init(); Maximale aantal berichten. mqd_t mqdes; struct mq_attr mq. Attrs; Maximale aantal bytes per bericht. mq. Attrs. mq_maxmsg = 3; mq. Attrs. mq_msgsize = sizeof(int); mq. Attrs. mq_flags = 0; mqdes = mq_open("ints", O_RDWR | O_CREAT, 0666, &mq. Attrs); Grotere stack zodat printf pthread_t tp, tc; gebruikt kan worden. pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 1024); pthread_create(&tp, &attr, &producer, &mqdes); pthread_create(&tc, &attr, &consumer, &mqdes); 19
Communicatie via mqueue (1 van 2) EMBEDDED SYSTEMS void *producer(void *pp) { mqd_t mq = *(mqd_t *)pp; for (int i = 0; i < 10; i++) { mq_send(mq , (char *)&i, sizeof(i), 0); } return NULL; } void *consumer(void *pp) { mqd_t mq = *(mqd_t *)pp; while (1) { int msg; mq_receive(mq, (char *)&msg, sizeof(msg), NULL); printf("%dn", msg); } source } 20
Uitvoer [Cortex_M 4_0] Ready. . . Go! 0 1 2 3 4 5 6 7 8 9 EMBEDDED SYSTEMS
Extra producer EMBEDDED SYSTEMS pthread_t tp 1, tp 2, tc; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 1024); pthread_create(&tp 1, &attr, &producer, &mqdes); pthread_create(&tp 2, &attr, &producer, &mqdes); pthread_create(&tc, &attr, &consumer, &mqdes); 22 source
Uitvoer [Cortex_M 4_0] Ready. . . Go! 0 1 2 3 4 0 5 6 1 7 8 2 9 3 4 5 6 7 8 9 EMBEDDED SYSTEMS
Aan de slag! EMBEDDED SYSTEMS Aan de slag met Opdrachten_Week_4_Lab_2. pdf 24
- Slides: 24