Désolé pour ma réponse tardive, mais je n'étais pas trop disponible ces derniers jours.
@ Bud Spencer : oui, pourquoi pas car après tout, je ne connais pas node.js.
@ destroyedlolo : oui, j'ai vraiment envie de jouer avec les threads, mais aussi de comprendre comment fonctionne le GPIO.
Voici le programme écrit en 'C' qui permet de gérer trois timer :
Code : Tout sélectionner
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#define sigev_notify_function _sigev_un._sigev_thread._function
#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
#define sigev_notify_thread_id _sigev_un._tid
#define _PERIOD_SIG SIGRTMIN
#define _PERIOD_SEC 0
#define _PERIOD_NSEC 100000000 /* 100ms */
#define _NBRE 3
/******************************/
/* */
/* Variables Globales */
/* */
/******************************/
pthread_cond_t cond;
pthread_mutex_t mutex;
/*================================*/
/* Passage des paramètres */
/*================================*/
typedef struct
{
pthread_t iThread;
int iNumero;
void *function;
int period_sec;
int period_nsec;
} PARAMS, *LPARAMS;
PARAMS params[3] =
{{0, 1, 0, _PERIOD_SEC, _PERIOD_NSEC},
{0, 2, 0, _PERIOD_SEC, _PERIOD_NSEC},
{0, 3, 0, _PERIOD_SEC, _PERIOD_NSEC}};
int flag;
/********************************/
/* */
/* Création des Threads */
/* */
/********************************/
void button1(union sigval arg)
{
static int i = 0;
pthread_mutex_lock(&mutex);
printf("Button 1 : %d\n", ++i);
if (i>=10)
flag=1;
/*=====================================*/
/* Condition d'arrêt du Thread */
/*=====================================*/
if (flag)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void button2(union sigval arg)
{
static int i = 0;
pthread_mutex_lock(&mutex);
printf("\t\tButton 2 : %d\n", ++i);
/*=====================================*/
/* Condition d'arrêt du Thread */
/*=====================================*/
if (flag)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void led(union sigval arg)
{
static int i = 0;
pthread_mutex_lock(&mutex);
printf("\t\t\t\tLed : %d\n", ++i);
/*=====================================*/
/* Condition d'arrêt du Thread */
/*=====================================*/
if (flag)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
/*******************************/
/* */
/* Création des Timers */
/* */
/*******************************/
void *timer(void *arg)
{
int status;
timer_t timerid;
struct sigevent sevt;
struct itimerspec its;
/*======================*/
/* Verrouillage */
/*======================*/
pthread_mutex_lock(&mutex);
/*================================*/
/* Passage des paramètres */
/*================================*/
LPARAMS lparams = arg;
/*===========================*/
/* Création du Timer */
/*===========================*/
sevt.sigev_notify = SIGEV_THREAD;
sevt.sigev_notify_function = lparams->function;
sevt.sigev_notify_attributes = NULL;
sevt.sigev_value.sival_ptr = &timerid;
if ((status = timer_create(CLOCK_REALTIME, &sevt, &timerid)) == -1)
{
printf("%s : %d : timer %d create failed : %d\n", __FILE__, __LINE__, lparams->iNumero, status);
pthread_exit(NULL);
}
/*============================*/
/* Lancement du Timer */
/*============================*/
its.it_value.tv_sec = lparams->period_sec;
its.it_value.tv_nsec = lparams->period_nsec;
its.it_interval.tv_sec = lparams->period_sec;
its.it_interval.tv_nsec = lparams->period_nsec;
if ((status = timer_settime(timerid, 0, &its, NULL)) == -1)
{
printf("%s : %d : timer %d settime start failed : %d\n", __FILE__, __LINE__, lparams->iNumero, status);
pthread_exit(NULL);
}
/*=================================================*/
/* Condition d'attente de la fin du timer */
/*=================================================*/
pthread_cond_wait(&cond, &mutex);
/*========================*/
/* Arrêt du Timer */
/*========================*/
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0L;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0L;
if ((status = timer_settime(timerid, 0, &its, NULL)) == -1)
{
printf("%s : %d : timer %d settime stop failed : %d\n", __FILE__, __LINE__, lparams->iNumero, status);
pthread_exit(NULL);
}
/*==============================*/
/* Destruction du Timer */
/*==============================*/
if ((status = timer_delete(timerid)) == -1)
{
printf("%s : %d : timer %d delete failed : %d\n", __FILE__, __LINE__, lparams->iNumero, status);
pthread_exit(NULL);
}
/*=======================*/
/* Déverouillage */
/*=======================*/
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
/********************************/
/* */
/* Procédure Principale */
/* */
/********************************/
int main(int argc, char *argv[])
{
int i,status;
/*========================*/
/* Initialisation */
/*========================*/
flag=0;
/*=============================*/
/* Création d'un mutex */
/*=============================*/
if ((status = pthread_mutex_init(&mutex, NULL)))
{
printf("%s : %d : mutex init failed : %d\n", __FILE__, __LINE__, status);
exit(0);
}
/*===========================================*/
/* Création d'une variable condition */
/*===========================================*/
if ((status = pthread_cond_init(&cond, NULL)))
{
printf("%s : %d : condition variable init failed : %d\n", __FILE__, __LINE__, status);
exit(0);
}
/*=======================================*/
/* Démarrage de tous les threads */
/*=======================================*/
for (i=0; i<_NBRE; i++)
{
switch(i)
{
case 0: params[i].function = button1;
break;
case 1: params[i].function = button2;
break;
case 2: params[i].function = led;
break;
}
if ((status = pthread_create(¶ms[i].iThread, NULL, timer, (void *) ¶ms[i])))
{
printf("%s : %d : thread %4d create failed : %d\n", __FILE__, __LINE__, params[i].iNumero, status);
exit(0);
}
}
/*======================================================*/
/* Attente que tous les Threads soient terminés */
/*======================================================*/
for (i=0; i<_NBRE; i++)
{
if ((status = pthread_join(params[i].iThread, NULL)))
{
printf("%s : %d : thread %4d join failed : %d\n", __FILE__, __LINE__, params[i].iNumero, status);
exit(0);
}
}
/*==============================================*/
/* Destruction de la variable condition */
/*==============================================*/
if ((status = pthread_cond_destroy(&cond)))
{
printf("%s : %d : condition variable destroy failed : %d\n", __FILE__, __LINE__, status);
exit(0);
}
/*==============================*/
/* Destruction du Mutex */
/*==============================*/
if ((status = pthread_mutex_destroy(&mutex)))
{
printf("%s : %d : mutex destroy failed : %d\n", __FILE__, __LINE__, status);
exit(0);
}
exit(0);
}
Code : Tout sélectionner
~/Prog_C/ex_04> timer
Button 2 : 1
Led : 1
Button 1 : 1
Button 1 : 2
Led : 2
Button 2 : 2
Button 1 : 3
Button 2 : 3
Led : 3
Button 1 : 4
Led : 4
Button 2 : 4
Button 1 : 5
Button 2 : 5
Led : 5
Button 1 : 6
Button 2 : 6
Led : 6
Button 1 : 7
Button 2 : 7
Led : 7
Button 1 : 8
Led : 8
Button 2 : 8
Button 1 : 9
Button 2 : 9
Led : 9
Button 2 : 10
Button 1 : 10
Led : 10
Led : 11
~/Prog_C/ex_04>
Je ne l'ai pas terminé car je n'ai pas encore introduit la partie consacré aux GPIO, que j'ai testé par ailleurs.
La tâche "Button 1" gère l'arrêt de tous les timers.
J'ai considéré que chaque timer était une seule file d'attente répétitive qu'il fallait géré séparément.
Et voici le programme 'C' où j'ai testé mon montage électronique :
Code : Tout sélectionner
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
/*-----------+--------*/
#define KEY RPI_GPIO_P1_11 /* Broche 11 | GPIO17 */
#define LED_a RPI_GPIO_P1_12 /* Broche 12 | GPIO18 */
#define LED_b RPI_GPIO_P1_15 /* Broche 15 | GPIO22 */
#define LED_c RPI_GPIO_P1_16 /* Broche 16 | GPIO23 */
#define LED_d RPI_GPIO_P1_18 /* Broche 18 | GPIO24 */
#define LED_e RPI_GPIO_P1_22 /* Broche 22 | GPIO25 */
#define LED_f RPI_GPIO_P1_07 /* Broche 7 | GPIO04 */
#define LED_g RPI_GPIO_P1_24 /* Broche 24 | GPIO08 */
/*-----------+--------*/
void raz_leds(void)
{
bcm2835_gpio_write(LED_a, LOW);
bcm2835_gpio_write(LED_b, LOW);
bcm2835_gpio_write(LED_c, LOW);
bcm2835_gpio_write(LED_d, LOW);
bcm2835_gpio_write(LED_e, LOW);
bcm2835_gpio_write(LED_f, LOW);
bcm2835_gpio_write(LED_g, LOW);
}
int main(void)
{
int y, z, press, prev, rang;
printf("Début: Bouton et Leds clignotantes\n");
/*---------------------*/
/* Initialisation GPIO */
/*---------------------*/
if (!bcm2835_init()) exit(-1);
bcm2835_gpio_fsel( KEY, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(KEY, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_fsel( LED_a, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_b, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_c, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_d, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_e, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_f, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel( LED_g, BCM2835_GPIO_FSEL_OUTP);
/*-----------------*/
/* Boucle Générale */
/*-----------------*/
prev = 0;
for(y=0; y<5;)
{
while ((press = bcm2835_gpio_lev(KEY)) == prev)
bcm2835_delay(100);
prev = press;
switch (press)
{
/*-----------------------------------------*/
/* Bouton relaché : Remise à zéro des leds */
/*-----------------------------------------*/
case 0:
printf("(%d) Bouton relaché\n\n", y+1);
y++;
raz_leds();
break;
/*----------------------------------*/
/* Bouton pressé : effet chenillard */
/*----------------------------------*/
case 1:
printf("(%d) Bouton Pressé\n", y+1);
for (z=0, rang=0; z<49; z++, rang=z%7)
{
switch (rang)
{
case 0:
bcm2835_gpio_write(LED_g, LOW);
bcm2835_gpio_write(LED_a, HIGH);
break;
case 1:
bcm2835_gpio_write(LED_a, LOW);
bcm2835_gpio_write(LED_b, HIGH);
break;
case 2:
bcm2835_gpio_write(LED_b, LOW);
bcm2835_gpio_write(LED_c, HIGH);
break;
case 3:
bcm2835_gpio_write(LED_c, LOW);
bcm2835_gpio_write(LED_d, HIGH);
break;
case 4:
bcm2835_gpio_write(LED_d, LOW);
bcm2835_gpio_write(LED_e, HIGH);
break;
case 5:
bcm2835_gpio_write(LED_e, LOW);
bcm2835_gpio_write(LED_f, HIGH);
break;
case 6:
bcm2835_gpio_write(LED_f, LOW);
bcm2835_gpio_write(LED_g, HIGH);
break;
}
bcm2835_delay (100);
}
break;
}
}
/*-------------------*/
/* Fin du Traitement */
/*-------------------*/
raz_leds();
bcm2835_close();
printf("Fin: Bouton et Leds clignotantes\n");
exit(EXIT_SUCCESS);
}