Tout ça je le connais et je l'ai fais , ce que je comprend pas c'est l'algorithme,quand commuter quand on a besoin d la semaphore, où l'appeler.
C'est l'algo que je ne comprend pas.
Tout ça je le connais et je l'ai fais , ce que je comprend pas c'est l'algorithme,quand commuter quand on a besoin d la semaphore, où l'appeler.
C'est l'algo que je ne comprend pas.
Au début, l'acquisition SPI prends les DEUX sémaphores, et ENSUITE, le thread d'envoi TCP/IP essaie de prendre le premier (ce qui va le bloquer, bien sûr).
Une fois le premier buffer rempli, le SPI lâche le sémaphore du premier buffer, ce qui permet au thread d'envoi d'avoir la main dessus. Une fois les données envoyées, le thread d'envoi lâche le sémaphore, et attends le second (normalement, il est encore bloqué par l'acquision SPI).
A chaque fois que le buffer est plein, le thread SPI doit effectuer les actions suivantes :
- Prendre l'AUTRE sémaphore, éventuellement avec un timeout négatif pour vérifier s'il est libre (s'il ne l'est pas => erreur critique).
- Relâcher le sémaphore courant (=> libère le thread TCP/IP en attente dessus).
- Acquérir les données jusqu'à remplissage du buffer.
Pour le thread TCP/IP, c'est la séquence suivante :
- Prendre le sémaphore courant (=> on se retrouve bloqué, il est pris par l'acquisition SPI).
- Une fois débloqué, envoyer les données sur le réseau jusqu'à vider le buffer.
- Libérer le sémaphore courant.
- Prendre l'autre (=> bloqué, normalement).
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Merci infiniment , c'est ce que je faisai aussi , sauf que j'ai pas envi de taper des lignes de codes et de ne pas savoir les erreurs proviennent d'où surtout dans une programmation qui me fait perdre !!
Merci
Voilà quelques bouts de code pour assurer les échanges de buffers :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int Current = 0 ; void* Buffers[2] ; int Semaphores[2] ; // Récupération du buffer/sémaphore courant. Buffers[Current] = .... ; Semaphores[Current] = .... ; // Récupération de l'AUTRE buffer/sémaphore. Buffers[1-Current] = .... ; Semaphores[1-Current] = .... ; // Changement de buffer courant. // A ne faire QUE lorsque l'acquisition SPI possède les DEUX sémaphores !!!! Current = 1 - Current ;
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Voila quelque lignes de code que j'ai fait si tu peu jeter un coup d 'oeil je me suis juste occupe de l'envoi pour le moment :
Code de la fonction send :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 while(1) { if (T->Established() == 1) { // recuperer les buf/semaphore Buffers[Current] =data1; Semaphores[Current] =semID1 ; Buffers[1-Current] = data2; Semaphores[1-Current] =semID2; // envoi T->Send(Buffers[Current],8*3,Semaphores[Current]); //echnage de buffer semaphore Current = 1 - Current ; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 short cSocket::Send(unsigned char * bufptr, USHORT bufLen,int far *sem) { int result; RTX_Reserve_Sem(*sem,0); result=send ( sd, bufptr, bufLen, MSG_DONTWAIT, &error ); RTX_Free_Sem(*sem); //if (result==-1) established = 0; //si l'envoi echoue on ferme la connection return result; }
Bon je crois je suis énormément perdu la :
Tu dis que AU DEBUT il faut que le SPI reserve les deux semaphore , comment alors faire sachant que mon SPI fonctionne sur interruption externe.
Dans le main je ne sais pas comment faire le "AU DEBUT", ni l'echange de buffers puisque comme j'ai dit le SPI est en interruption.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 void main() { //installation de l'interruption while(1) { if(connected) //envoi } }
Donc en gros je te demande stp qu'est ce que je dois mettre dans les fonction :
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part void huge Config_SPI_HW::ReadWriteBlock(unsigned char *rbuffer,unsigned char *wbuffer) //Read/Write 8 Bytes
qu'est ce que le main doit contenir et qu'est ce que le thread envoi et l'interruption vont contenir???
Code : Sélectionner tout - Visualiser dans une fenêtre à part short cSocket::Send(unsigned char * bufptr, USHORT bufLen)
Merci
Salut j'attend toujours ta réponse , en attendant je te file mon pseudo code pour voir si c'est ce qu'il faut faire :
Le souci est comment le SPI peut posseder les deux sémaphore tout au début.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 unsigned char data1[8*3]; // les deux buffer unsigned char data2[8*3]; unsigned char zz=0x00; unsigned char wbuffer[8]={zz,zz,zz,zz,zz,zz,zz,zz}; // pour la fonction de la lecture SPI int far *semID1; // semaphore for protecting data1 , et data2 int far *semID2; // variable pour l'échange int Current = 0 ; // variables d'echange cote EVNOI TCP void* Buffers[2] ; int Semaphores[2] ; int _Current = 0 ; //variables d'echange coté SPI void* _Buffers[2] ; int _Semaphores[2] ; short cSocket::Send(USHORT bufLen) { Buffers[Current]=data1; //recupere buffer et semaphore Semaphores[Current]=semID1 ; Buffers[1-Current] = data2; Semaphores[1-Current] =semID2; RTX_Reserve_Sem(Semaphores[Current],0); send ( sd, Buffers[Current], bufLen, MSG_DONTWAIT, &error ); RTX_Free_Sem(Semaphores[Current]); current=1-current; //echange de semaphore et buffer. } void huge Config_SPI_HW::ReadWriteBlock() { spi_waiton_sem_setmode_dyn(SPI_MODE, div); //pour synchroniser les esclaves SPI. _Buffers[_Current]=data1; //recupere buffer et semaphore _Semaphores[_Current]=semID1 ; _Buffers[1-_Current] = data2; _Semaphores[1-_Current] =semID2; RTX_Reserve_Sem(Semaphores[Current],0); //Lecture SPI while(1) { for (i=0;i<8;i++) { spi_read_write_dyn(_Buffers[_Current]+i,wbuffer+i,1); //Introduction de retard while(ctr-->0); ctr = 2; } } RTX_Free_Sem(_Semaphores[_Current]); //liberer la semaphore _Current =1-_Current; //echange de buffer semaphore spi_release_sem(); // liberer le bus SPI } main() { // debut de code while(1) { if(connected) { Send(8*3); } else { // ecoute et réinitialisation de la connection } }
Merci et désolé encore pour le dérangement!
Déjà, il faut vérifier que le SPI peut bien acquérir les sémaphores tout en étant en IT. Normalement, oui, mais c'est à vérifier quand même.
Ensuite : au départ, l'acquisition SPI peut parfaitement locker les deux sémaphores parce qu'ils n'appartiennent à personne.
Enfin : tu ne dois pas échanger les buffers, et encore moins les sémaphores, dans le thread TCP/IP. Seul l'acquisition SPI a le droit de le faire, le thread TCP/IP prenant TOUJOURS le buffer/sémaphore courant.
Dit autrement, le consommateur (thread TCP/IP) boucle sur un seul et même buffer, c'est le producteur (acquisition SPI) qui est maître des deux buffers et autorise la permutation.
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Comment le TCP/IP doit boucler sur un seul buffer???
Prendr l'autre ca veux dire l'autre buffer non!!??Pour le thread TCP/IP, c'est la séquence suivante :
Prendre le sémaphore courant (=> on se retrouve bloqué, il est pris par l'acquisition SPI).
Une fois débloqué, envoyer les données sur le réseau jusqu'à vider le buffer.
Libérer le sémaphore courant.
Prendre l'autre (=> bloqué, normalement).
Ce n'est pas logique si on boucle sur le meme buffer on risque de l'ecraser par l'ecriture SPI a tout moment!!!
Vraiment je comprend plus rien en ce que tu m'a di c'est un peu contradictoire pour moi,l'envoi doit se fair sur un buffer quand ce buffer est plein l'envoi se fera cette fois sur l'autre , il y'a bel et bien 2 buffer quand meme dans le processus TCP/IP , et apres tu di :
Comment ca se fait???Enfin : tu ne dois pas échanger les buffers, et encore moins les sémaphores, dans le thread TCP/IP
Oui, il envoie (par exemple) toujours le contenu du premier buffer.
Prendre le SÉMAPHORE de l'autre buffer. Une fois plein, l'acquisition SPI va échanger buffers et sémaphores.
Mais non. A part sur la première boucle (et encore...), le SPI, lui, remplit systématiquement le SECOND buffer.
Oui, mais regarde de nouveau le schéma que j'avais indiqué en début de sujet, sur le double buffer : à chaque fois, un des accès est coupé pour un des éléments.
Le fait de "changer de buffer" signifie que l'on échange les pointeurs des buffers, et des sémaphores associés, lorsque le buffer SPI est plein.
Parce que le thread TCP/IP est consommateur (= "esclave", si tu préfères). Ce n'est pas lui qui peut décider du taux de remplissage du buffer en cours d'acquisition SPI, mais bel et bien le code d'acquisition SPI lui-même. C'est donc le SPI qui est "maître" des buffers, et qui décide du moment où l'échange se produit.
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Ok ,alors pourquoi tu a expliqué au début que :
Quand le buffer d'acquisition SPI est plein, tu permutes les deux buffers (en fait, simplement le pointeur sur le buffer), et tu préviens par un sémaphore / mutex / flag global que l'envoi doit se faire sur l'autre buffer
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Voila ma dérniere version du code , tu peux me dire si c'est bon là , sinon tu peux editer le code et mettre des explications dessus , genre des commentaires là où ça marche pas
Déclarations :
Code TCP :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int far *semID1; // semaphore for protecting data1 , et data2 int far *semID2; // variable pour l'échange int Current = 0 ; // variables d'echange cote EVNOI TCP void* Buffers[2] ; int Semaphores[2] ;
Code SPI
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 short cSocket::Send(unsigned char * bufptr, USHORT bufLen) { RTX_Reserve_Sem(Semaphores[Current],0); // reserve semaphore courant int result = send ( sd, bufptr, bufLen, MSG_DONTWAIT, &error ); // envoi quand il est débloqué RTX_Free_Sem(Semaphores[Current]); // Quand le buffer est vidé on libére la sémaphore courante if (result==-1) established = 0; //si l'envoi echoue on ferme la connection return result; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 void huge Config_SPI_HW::ReadWriteBlock() //Read/Write 8 Bytes { spi_waiton_sem_setmode_dyn(SPI_MODE, div); //pour synchroniser les esclaves SPI. Buffers[Current]=data1; //recupere buffers et semaphores Semaphores[Current]=semID1 ; Buffers[1-Current] = data2; Semaphores[1-Current] =semID2; RTX_Reserve_Sem(Semaphores[Current],0); //réserve le sémaphore courant. //Lecture SPI while(1) { for (i=0;i<8;i++) { spi_read_write_dyn(Buffers[Current]+i,wbuffer+i,1); //Introduction de retard while(ctr-->0); ctr = 2; } } RTX_Free_Sem(Semaphores[Current]); //liberer la semaphore courante. Current =1-Current; //echange de buffer /semaphore spi_release_sem(); // liberer le bus SPI }
Ah j'ai oublié le main :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 while(1) { if (T->Established() == 1) { T->Send(Buffers[Current],8*3); }
Voilà merci
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager