Archive 07/10/2020.

TP7 : Pourquoi utiliser des threads?

GiLe

Bonjour,

A part un intéret purement didactique (Apprendre à utiliser des threads) pourquoi utiliser des threads pour lire les données des péripheriques?
Je sais cela rend le code plus lisible avec un gros programme mais dans le TP7 tout pourrait être fait dans la boucle principale du main, non?

Question complémentaire: Dans un environnement contraint en memoire quel est le coût de création d’un thread en mémoire sous RIOT?

baroudeur-techno

Bonjour GiLe,
votre remarque m’a intrigué, j’ai donc fait un “main.c” avec le code ci-dessous ;
il en résulte dans l’affichage des résultats, que seul le premier capteur renvoie ses valeurs ; je pense que c’est dû au fait que l’exécution ne peut sortir de la première boucle sans fin ; seul un autre thread tournant en parallèle permet donc d’activer la lecture du deuxième capteur.
Cordialement.

int main(void)
{
/* Initialize the lps331ap sensor here */
lpsxxx_init(&lpsxxx, &lpsxxx_params[0]);

/* Initialize the lsm303dlhc sensor here */
lsm303dlhc_init(&lsm303dlhc, lsm303dlhc_params);

/* Add the lps331ap sensor polling endless loop here */
while (1) {
    uint16_t pres = 0;
    int16_t temp = 0;
    lpsxxx_read_temp(&lpsxxx, &temp);
    lpsxxx_read_pres(&lpsxxx, &pres);
    printf("Pressure: %uhPa, Temperature: %u.%u°C\n",
           pres, (temp / 100), (temp % 100));
    xtimer_sleep(2);
}
/* Add the lsm303dlhc sensor polling endless loop here */
while (1) {
    lsm303dlhc_3d_data_t mag_value;
    lsm303dlhc_3d_data_t acc_value;
    lsm303dlhc_read_acc(&lsm303dlhc, &acc_value);
    printf("Accelerometer x: %i y: %i z: %i\n",
           acc_value.x_axis, acc_value.y_axis, acc_value.z_axis);
    lsm303dlhc_read_mag(&lsm303dlhc, &mag_value);
    printf("Magnetometer x: %i y: %i z: %i\n",
           mag_value.x_axis, mag_value.y_axis, mag_value.z_axis);
    xtimer_usleep(500 * US_PER_MS);
}

return 0;

}

aabadie2

Bonjour,

pourquoi utiliser des threads pour lire les données des péripheriques?

Comme vous l’avez remarqué vous même, l’intérêt est uniquement didactique. Cela montre qu’une fois le thread bloqué (à cause du xtimer_sleep), le scheduler repasse la main à un autre thread prêt à éxécuter du code.

Dans un environnement contraint en memoire quel est le coût de création d’un thread en mémoire sour RIOT?

Il y a un cout en terme de mémoire flash, puisque le code supplémentaire utlisé pour implémenter la logique du thread se traduira par une place plus importante en ROM.
Le coût le plus important à prendre en compte est surtout l’espace en RAM, puisque la stack mémoire allouée pour chaque thread est placée directement en RAM. Et c’est surtout la RAM qui est la contrainte majeure.
Il est cenpendant possible de paraméter plus finement, à la compilation, la taille de la stack allouée pour chaque thread.

@baroudeur-techno, en lisant votre code, il parait assez évident que le programme n’arrive jamais dans la deuxième boucle while :slight_smile:

baroudeur-techno

Ah oui,
j’aurais dû illustrer ma remarque d’un code possédant une seule boucle sans fin, comme ci-dessous ; mais alors cela oblige à tester tous les capteurs en même temps.

int main(void)
{
/* Initialize the lps331ap sensor here */
lpsxxx_init(&lpsxxx, &lpsxxx_params[0]);

/* Initialize the lsm303dlhc sensor here */
lsm303dlhc_init(&lsm303dlhc, lsm303dlhc_params);

while (1) {
    /* lps331ap sensor here */
    uint16_t pres = 0;
    int16_t temp = 0;
    lpsxxx_read_temp(&lpsxxx, &temp);
    lpsxxx_read_pres(&lpsxxx, &pres);
    printf("Pressure: %uhPa, Temperature: %u.%u°C\n",
           pres, (temp / 100), (temp % 100));
    /* lsm303dlhc sensor here */
    lsm303dlhc_3d_data_t mag_value;
    lsm303dlhc_3d_data_t acc_value;
    lsm303dlhc_read_acc(&lsm303dlhc, &acc_value);
    printf("Accelerometer x: %i y: %i z: %i\n",
           acc_value.x_axis, acc_value.y_axis, acc_value.z_axis);
    lsm303dlhc_read_mag(&lsm303dlhc, &mag_value);
    printf("Magnetometer x: %i y: %i z: %i\n",
           mag_value.x_axis, mag_value.y_axis, mag_value.z_axis);

    xtimer_sleep(1);
}
return 0;

}