PCM pour MBED

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
En analysant mes logs, j'ai vu que l'idée de Guinness a été utile (en tous les cas elle ne peut pas être néfaste). 1 % des trames environ étaient traités dans une concurrence entre la boucle while et l'appel sur interruption. Et c'était l'appel sur interruption qui gagnait. Encore que le fait de mettre des traces dans la boucle rallonge la durée de la boucle et peut-être suffisamment pour que la condition de la boucle soit remplie.

Aujourd'hui, contrôle au niveau de la lecture du ring buffer. Les motifs sont dans le bin. Mais je sens que c'est dans la comme bluetooth avec PCM qui ne marche pas bien. Mais comment dans ce cas les trames seraient doublaient ou inversaient. A suivre.

Priusfan n'a surement pas mes problèmes car il a beaucoup moins de trames passives, et aussi car il transmet assez peu en bluetooth.
 

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
6,514
Score de réaction
9,382
Localisation
conflans ste honorine
Véhicule
UX250h, Pijot iOn, ex Rav4h
....Mais je sens que c'est dans la comme bluetooth avec PCM qui ne marche pas bien. Mais comment dans ce cas les trames seraient doublées ou inversées ?. A suivre.
saturation serialbuffer ???? (mauvaise gestion ringbuffer du serial?)
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
Je ne comprends toujours pas, mais je me rapproche du nœud.
J'enregistre coté MBED (au moment de la lecture du ring buffer, mais il se passe ensuite dans choses avant que cela soit envoyé PCM), puis lorsque c'est reçu par PCM.
J'ai du chaos (désolé pour la faute depuis quelques postes, pour ceux qui veulent apprendre :
http://grammaire.reverso.net/2_1_12_cahot_chaos.shtml )
des deux cotés, même s'ils n'ont pas la même forme. Coté PCM, c'est décrit plus haut : frame manquante, frame inversée, frame doublée, mais frame propre. Coté MBED, pendant la phase chaotique, la forme est différente, avec plus de trames que coté PCM (ou plutôt ce serait PCM qui aurait moins de trames), mais malformées. Puis quand cela s'arrange d'un coté, cela s'arrange de l'autre et c'est en phase comme coté lecture du Can.
cahotreadbuffer.PNG


voici à quoi ressemble les trames

3C800282A000023A3DCA37E39
3C800282A000023A3DDA38B70
3C800282A000023A3DEA395A0
3C800282A000023A3E4A3D7CA
3C8B3E302000000D1A3E4C86AD1
3C800282A0000003FA3E5CECF03
3C800282A000119562CA3E8AE3195
3C800282A000023A3E4A3D7CA
3C810000000091E2BB0A3EACFBBFB
3C800282B000024A3EBA5B923
3C800A300DFD1A3EBD4AC2B
3C800001EB2A3ECC0855A
3C800282A000023A3EDA43985
3C8007A020000006DA3EECBFBC3
3C800282A0000A3EFBC7BF0
3C800282A000023A3F0A78E1D
3C800000000092A2BBCA3F0CF6C23
3C800282A0001198D63A3F1C42552
3C800282A000023A3EDA43985
3C800282A000023A3F3A4C9B2

à suivre. Mais du coup, cela pourrait ne pas venir de bluetooth.
 

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
6,514
Score de réaction
9,382
Localisation
conflans ste honorine
Véhicule
UX250h, Pijot iOn, ex Rav4h
je n'ai pas d'idées sur l'origine réelle du pb...

suggestion: alléger au max l'application en recréant

  • a) une appli minimale de collecte (avec les filtres) qui seulement fait un "forward" en USB.
  • b) on la complète jusqu'au moment où cela coince..


coté consommation électrique 12V de l'interface mbed:
sur la iOn, elle oscille aux alentours de 60 mA.
le fait de passer en mode sommeil est à peine visible.

quand j'aurai le courage, je tenterai de couper le régulateur de tension dans le cas de faible trafic.
c'est quand meme assez lourd car je dois utiliser un oscilloscope, un potar de xxx MOhms et qqs capas de différentes valeurs et de bonne qualité pour ajuster la constante de temps (et le résultat est loin d'etre garanti 8) ).
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
en fait j'avais un doute sur ce qui se passait entre le stockage et la lecture du ring buffer.
c'est pas le chaos (maintenant que je sais l'écrire), mais le b????l (que je ne peux écrire).
et dès la première microseconde

juste pour vous donner un idée, voici les premières microsecondes :
<<038070478B64F00800008000000C7
debug:1,0,0
>153F051D61003701D601375480
>253F051D61003701D601375480
<<039041D62536A012E00006B
debug:2,1,0
>1038070478D65302800008000000C7
>2038070478D65302800008000000C7
<<039041D627367022E000F7A
debug:3,2,0
>103B050478DD6D03000000E020
<<3C8061D6277A203003400000005
>23C8061D6277A203003400000005
debug:4,3,0
>1038070478F65804800008000000C7
>2038070478F65804800008000000C7
<<039041D629368042E000F7A

pour vous aider à comprendre
<< c'est écrit au moment de la mise dans le ring buffer
>1 c'est écrit au début de la boucle de lecture du ring buffer
>2 c'est écrit à la fin de la boucle de lecture du ring buffer

ensuite :
les 3 octets qui suivent : le pid
les 2 octets qui suivent : la longueur des données
les 8 octets qui suivent : le timestamp de la trame au moment du stockage dans le ring buffer
les 2 octets qui suivent : la position dans le ring buffer
les octets qui suivent : les données

les lignes debug sont dans la boucle de lecture et sont au tout début de la boucle; elles indiquent dans l'ordre : la position à lire dans le ring buffer, la position à écrire dans le ring buffer, et la taille du ring buffer sans la donnée en cours de lecture

donc la première trame est une 038, elle est stockée en 00, à l'heure 0478B64F, mais elle ne ressort jamais
la première qui ressort est une 53F, stockée en 01, à l'heure 1D610037

il ne lit pas la 00, mais la 01, qui a probablement été stockée lors du dernier démarrage de la Prius.

bref déjà un problème.

deuxième problème :
la deuxième trame stockée est une 039, dans la position 01, à l'heure 1D62536A, ne ressortira pas
mais celle qui ressort est une 038, en position 02, à l'heure 0478D653

c'est à ce demander si ce qui est imprimé est juste.

mais encore pire, la troisième trame qui ressort pendant que la quatrième arrive
en début de boucle >1 c'est une trame 03B, mais comme avant de finir la boucle il arrive << une trame 3C8, c'est elle qui ressort en fin de boucle >2

j'avais dit que c'était le b????l

il suffit de revoir le code, imaginer que la lecture et l'écriture se font en parallèle, concurrence, pour comprendre que cela ne va pas.

juste un exemple, en début de boucle d'écriture dans le buffer, j'incrémente la taille du buffer. Comme la taille est non nulle, la boucle de lecture du buffer peut lire, mais je n'ai peut-être rien écrit encore.

bref le code n'est pas écrit en pensant à la concurrence.

et bien je vais essayer de rendre plus robuste cela même sans guiness et sans guiness.

à demain
 
Dernière édition:

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
En mettant les incréments et les décréments à la fin des boucles, cela devrait marcher.
See you tomorrow. Too late to try now in the car.

Code:
volatile bool inside_can_check = false ;
volatile unsigned int rb_write_pointer = 0; // ring buffer write pointer
volatile unsigned int rb_read_pointer = 0;  // ring buffer read pointer
volatile unsigned int rb_data_size = 0;     // ring buffer number of entries

void can_check(void) { // called by interrupt

    if (!inside_can_check) {
      inside_can_check = true ;
      while ( can2.read(can_MsgRx) ) {

        // add entries in the ring buffer
        second[rb_write_pointer] = timer.read_us();
        can_id[rb_write_pointer] = can_MsgRx.id & 0xFFF;
        msg_length[rb_write_pointer] = can_MsgRx.len;
        for (char i=0; i<can_MsgRx.len; i++) {
            data[rb_write_pointer][i] = can_MsgRx.data[i];
        } // for

        rb_write_pointer++ ;                //  increase write_pointer
        rb_write_pointer &= BUFFER_MASK;    //  loop if at end of array
        rb_data_size++ ;                    //  ring buffer number of entries

        if ( rb_write_pointer == rb_read_pointer && rb_data_size == BUFFER_SIZE) {  // buffer overflow
            fprintf(stderr, "buffer overflow\r\n");
            led4=!led4;
            bufferoverflow=true;
            rb_data_size = 0;
            rb_write_pointer = 0;
            rb_read_pointer = 0;
        }       // error

      } // while
      inside_can_check = false ;
    }
} // can_check

int main() {
    init();  //  executes:     can2.attach(&can_check);
       
    while (1) {
        // read CAN messages from the buffer       
        if ( rb_data_size > 0 ) {               // new message is available

            // we store in w_vars the results : it is not funny to manage all these [][]
            w_id=can_id[rb_read_pointer];
            w_len=msg_length[rb_read_pointer];
            w_sec=second[rb_read_pointer];
            w_num=rb_read_pointer;
            for (int i=0; i<w_len; i++) {
                w_data[i]=data[rb_read_pointer][i];
            } // for

            wrkmsg();               //  decide what to do with the message  (w_vars)

            rb_read_pointer++;                      // position to next
            rb_read_pointer &= BUFFER_MASK;         // loop if at end of array
            rb_data_size--;                         // update nbr of entries in the ring buffer
            
        } //        end // if ( rb_data_size > 0 )
    } // while
} // main
 

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
6,514
Score de réaction
9,382
Localisation
conflans ste honorine
Véhicule
UX250h, Pijot iOn, ex Rav4h
je te suggère de reprendre le pgm initial de yoshi en y adaptant tes filtres;
il est ici : http://priusfan.info/canmonitor/mbed/CAN_MONITOR_YM.zip

(c'est de cela que j'avais démarré)

tu y ajoutes tous tes points de debug et on fait le bilan...

ce qu'il y a d'amusant, c'est que dans ce truc initial, il n'y avait aucun besoin de buffers supplémentaires
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
Merci, j'y jetterai un œil si je craque.
La il me semble que je tiens le bon bout.
Depuis que tu m'as fabriqué mon boitier, je n'ai pas arrêté de progresser.
Alors tout va bien, et j'ai passé d'excellentes vacances dans ma voiture.
C'est juste Tripmaster qui a été ralenti.
 

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
6,514
Score de réaction
9,382
Localisation
conflans ste honorine
Véhicule
UX250h, Pijot iOn, ex Rav4h
@thierry

:ovation:
cette histoire de gestion des pointeurs,c'est trop cong (comme ils disent dans le 31).
j'avais hésité à créer un modèle (que ce soit en excel ou en c++) pour vérifier la cinématique, mais je m'étais dit que les recettes de la toile étaient bonnes :oops: .
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
T'inquiètes. Je ne te serai jamais assez reconnaissant.
 

guinness

Participant hyperactif
Inscrit
23 Juil. 2009
messages
510
Score de réaction
126
Localisation
Ile de France
Véhicule
Prius3 et Nissan Leaf
Désolé je n'ai pas le temps de me plonger dans le code, mais s'il y a concurrence en C, vous allez devoir regarder les fonctions pthread_mutex_lock et pthread_mutex_unlock afin de regrouper l'écriture d'un buffer et l'incrément du pointeur dans un seul bloc ininterruptible (de même pour la lecture et le décrément). Il faut veiller à isoler uniquement le code critique et ne pas faire d'opération lente (genre du logging) dans un tel bloc car sinon on peut perdre bcp en rapidité.
Have fun!
 

guinness

Participant hyperactif
Inscrit
23 Juil. 2009
messages
510
Score de réaction
126
Localisation
Ile de France
Véhicule
Prius3 et Nissan Leaf
Je ne connais rien à l'env de dev sur MBED, donc j'avoue que j'ai dit ça au pif, mais s'il y a conccurence il faut forcément un système pour gérer des sections critiques (s'il n'y en a pas il faut le faire soi-même à la main et perso je trouve les mutex bcp plus simples à utiliser).

En tout cas je trouve le concept très intéressant et je regrette de ne pas avoir de temps à lui consacrer...
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
non je ne l'utilise pas. Je n'en ai pas eu besoin.
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
C'est mieux mais il y encore des problèmes.

<0300C2A61D7000400000027200083
<0B40C2A639D0000000000000000BC
<2300C2A64F30100052224000084
>0B40C2A639D0000000000000000BC
<0300C2A7BE4020400000027200083
<0300C2A93F7030400000026200082
<0B40C2A95BD0400000000000000BC
<0300C2AACA4050400000026200082
<0300C2AC4CE060400000026200082
<0B40C2AC7850700000000000000BC
<2300C2AC8DB0800052224000084
<0300C2ADD01090400000026200082
>2300C2A64F30100052224000084
>0300C2A7BE4020400000027200083

on a bien un problème de concurrence même avec l'astuce de Guinness à la lecture du Can.
les deux premières trames, la 030 et la 0B4, lues respectivement aux timestamps 0C2A61D7 et 0C2A639D ont été toutes les deux stockées à la position 00 et seule la deuxième ressort.
Mais cela un effet de bord dévastateur, le programme pense qu'il a en buffer 2 trames (ou plutôt une trame de plus). Et donc si à un moment la lecture du buffer va plus vite que les trames qui arrivent du bus Can dans le buffer, il va lire dans le buffer la trame stockée dans le cycle précédent.

Cela se produit finalement très vite (voila la suite):
>0300C2A93F7030400000026200082
>0B40C2A95BD0400000000000000BC
>0300C2AACA4050400000026200082
>0300C2AC4CE060400000026200082
<0300C2AF5260A0400000026200082
<0B40C2AF7DB0B00000000000000BC
>0B40C2AC7850700000000000000BC
>2300C2AC8DB0800052224000084
>0300C2ADD01090400000026200082
>0300C2AF5260A0400000026200082
<0300C2B0D2F0C0400000026200082
>0B40C2AF7DB0B00000000000000BC
>0300C2B0D2F0C0400000026200082
>03B0149ADD9 0D 000000D919 <=====
<0300C2B2558 0D 0400000026200082 <=====
<0B40C2B2809 0E 00000000000000BC
<2300C2B295E0F00052224000084
>0B40C2B2809 0E 00000000000000BC

Il sort du ring buffer la trame no OD alors qu'il ne va la stocker qu'après
Dans la plupart des cas, cela n'a pas d'importance.
Mais dans certains cas, malheureusement, c'est très embêtant.
Ceci explique les trames perdues, en double, ou inversées.

Mais on peut voir que comme la trame no 0E arrive très vite derrière, elle est bien empilée à temps dans le buffer pour être lue.

Je vais regarder comment résoudre le problème sans mutex, à la Guinness.
 

thierryb

Participant hyperactif
Inscrit
20 Janv. 2011
messages
1,968
Score de réaction
1,032
Localisation
Yvelines
Véhicule
Prius 2 sol pack ipa 2008 verte
J'arrive pas, et j'arrive pas à importer la library qui me donnerait les mutex.
Il faut que je réfléchisse plus.
 

guinness

Participant hyperactif
Inscrit
23 Juil. 2009
messages
510
Score de réaction
126
Localisation
Ile de France
Véhicule
Prius3 et Nissan Leaf
A ta place je chercherais à utiliser un vrai mutex car j'ai l'impression à te lire qu'il faut vraiment protéger la lecture et écriture dans le ring buffer contre les accès conccurents et en C je ne sais pas comment me mettre en attente sur un changement de valeur d'un bool sans consommer de ressources (ce que fait très bien un mutex).
Si la librairie est open-source, tu peux regarder le code de mutex_lock pour comment ils font?
 

priusfan

darwiniste
Prius Touring Club
Inscrit
22 Oct. 2005
messages
6,514
Score de réaction
9,382
Localisation
conflans ste honorine
Véhicule
UX250h, Pijot iOn, ex Rav4h
en analysant le pb mentionné dans le msg 57, je me pose la question suivante:

le pb provient d'écrire 2 fois au même endroit, après effectivement, c'est le souk dans les pointeurs car le nb d'entrées dans le buffer est faux.

or cela se passe, dans le cas que tu montres, avec le pointeur 0.
mon petit doigt me dit qu'il y a un loupé dans l'algo lors du bouclage du ringbuffer.
typiquement le rb_write_pointer qui n'est pas incrémenté dans ce cas...

je vais essayer d'aller jusqu'au bout de cette intuition...
@suivre

en fait, peux tu communiquer ce que tu avais un peu avant, de façon à voir comment est géré le bouclage du buffer ?
 
Pages vues depuis le 20 Oct 2005: 283,152,763
Haut Bas