6.2 Generazione dei odi i di odi a XML
6.2.2 Il Proxy XML
La odi autilizzatapermetteal
µ
TNetOSdiri evereedinviaremessaggiXML diuna ertalunghezza,peròportaalproblemadell'in ompatibilità onl'interainfrastrutturaRoboti s4.NET: i messaggi he ir olano nell'infrastruttura so-
noinfatti messaggiXML non odi ati, pertanto ène essario interfa iareun
apposito proxy fra il
µ
TNetOS el'infrastruttura. Questo proxyha il dupli e ompitodi:•
Ra oglieretuttii messaggiXML heprovengonodall'infrastruttura, o- di arliepoitrasmetterlialµ
TNetOS,DalpuntodivistadiRoboti s4.NETil
µ
TNetOS eilproxyvengonovisti ome un uni o roblet.An hé l'implementazionedel proxysia indipendente da tut-ta l'infrastruttura ir ostante, il Generatore genera un le XML, denominato
XmlBinMap.xml, he ontiene lamappatura dei tag XML on i relativi odi i
binari. Questo le viene utilizzato dal proxy per eettuare orrettamente le
operazionidi odi aede odi a. Primadiinviareunmessaggioal
µ
TNetOS, ilproxyinviail aratterespe ialeSTXperavvertirlodell'iniziodi unatrasmis-sione. Altermine,inviail arattereETXperindi arelanedellatrasmissione.
Altrettantofail
µ
TNetOS quandoinviamessaggialproxy.Ilproxysvolgean healtredueimportantifunzioni:
1. A ausa dellalimitata memoria dati, non èstato possibile farein modo
heilbuerIn omingBufdel
µ
TNetOS fosseingradodi ontenerepiùdi unmessaggioallavolta1
. Primadipotera ettareunnuovomessaggio,è
ne essarioquindi heil pre edente siastato onsegnatoal(o ai) relativo
task e pro essato, altrimenti si ris hia he il nuovomessaggio sovras ri-
vail pre edente. Ilproxyfunge quindi an he daulteriore `buer' per il
µ
TNetOS. An he in questo asol'infrastruttura Roboti s4.NET non ne vieneinuenzata, al massimo potrà rilevare un ertoritardo di rispostaadundatomessaggio.
Per garantire hetutti i messaggiri evuti sianopro essati, la omuni a-
zioneserialefrail
µ
TNetOS eilproxyutilizzail proto olloXON/XOFF. Dopolari ezionedi unmessaggio,ilµ
TNetOS inviaalproxyil arattere spe iale XOFF .Il arattere XOFFserveperblo are momentaneamente lari ezionedi dati sullaseriale: il proxysi pone in uno statodi attesa (o
meglio,ilthread delpro essoproxy hesio upa dell'inviodeimessaggi
al
µ
TNetOS). Unavolta heilmessaggioèstatopro essato,ilµ
TNetOS inviasulla porta serialeil arattere XON , he sblo a il proxy perl'inviodelprossimomessaggio.
2. Imessaggidi Roboti s4.NETsono messaggi he ir olano sulbus Ether-
netappoggiandosisulproto olloUDP. Le omuni azioni onil
µ
TNetOS devono però avvenire tramite laporta seriale, quindi in mododierenterispettoaquantodenitoin Roboti s4.NET.L'altroimportante ompito
delproxyèquindiquellodirenderetrasparentifraloroquestiduetipidi
omuni azioni, adottandouna politi a di ontrollo dei messaggiri evuti
1
sullaseriale. Latrasmissioneserialepuògenerareerrorieportarequindia
messaggi orrotti;quandosiveri aunasituazionediquestotipo,ilproxy
s arta ilmessaggio. Questo omportamentoèin linea onquantoa ade
subus on l'utilizzodelproto olloUDPepertantononvaadinuenzare
il omportamentodell'interainfrastruttura.
6.3 Generazione dei messaggi
Questaparte del generatoresio upa della generazionedellastruttura dei ti-
pi dei messaggi e delle funzioni per il loro ri onos imento, serializzazione, e
deserializzazione,ne essarieadinteragire onl'infrastrutturaRoboti s4.NET.
Il generatore prende ome parametro in input la spe i a del Roblet he
deveessereeseguitosul
µ
TNetOS assiemeairelativiroblet messageegenerail relativo odi eCdelµ
TNetOS.Laspe i adeveesserefornita omeassembly, in modo da poter sfruttare le proprietà di meta-programming e di ree tiondelC#. Èpossibilepassarealgeneratoreununi ole assembly ontenentela
denizionedelRoblet edei suoimessaggioppurepiùleseparati.
Una volta ri evuta la spe i a, il generatore analizza l'assembly per de-
terminare il numero ed il tipo dei messaggi he devono essere generati. Il li-
stato 30 des rive in pseudo- odi e l'algoritmo per questa prima fase. La ge-
nerazionedel odi e perun dato tipo t di messaggio è adata alla pro edu-
ra GenerateTypeInterfa e(t). Per ognitipot questa pro edura eettua le
seguentioperazioni:
1. Viene generata la struttura asso iata al tipo t . Questa struttura può
essere una stru to una enum ase onda del fatto he il tipo t sia una
lasseounaenumerazione,
2. Viene generata la di hiarazione delle funzioni per il ri onos imento, la
serializzazioneeladeserializzazionedeltipot ,
3. Il odi egeneratoneiduepuntipre edentivienesalvatonelleheaderC
( .h )deltipot .
4. Vienegeneratoil orpodelletrefunzionialpunto2. Più pre isamente:
•
<t> _startsWith: Questafunzione sio upadelri onos imentodel messaggioXML,•
<t> _Read: Questa funzione si o upa della de odi a e della de- serializzazione del messaggio nella struttura dati reata al puntoListato 30Pseudo- odi edell'algoritmoperlaletturadellespe i heininput.
TypesToGenerate[t℄=falseindi a hedeveesseregeneratoil odi eCdeltipo
tperil
µ
TNetOS.forea h (string s in args) {
<Controllo di esistenza del file>
string fn = (new FileInfo(s)).FullName;
Assembly a = Assembly.LoadFile(fn);
forea h (Type t in a.GetTypes()) {
if (t.IsSub lassOf(typeof(Roboti s4.NET.RobletMessage))) {
TypesToGenerate[t℄ = false;
}
else if (t.IsSub lassOf(typeof(Roboti s4.NET.RobletBase))) {
<Generazione del odi e per l'invio dell 'interfa ia del Roblet>
}
}
}
TypesToGenerate[typeof(Roboti s4.NET.MetaDataRequest)℄ = false;
bool exit = false;
while (!exit)
{
exit = true;
forea h (Type t in TypesToGenerate.Keys) {
if (!TypesToGenerate[t℄) {
<Generazione del odi e per il tipo t>
TypesToGenerate[t℄ = true; exit = false; break; } } }
•
<t> _Write: Questafunzionesio upadella odi aedellaserializ- zazionedelmessaggioperl'invioalproxy. L'invioavverràutilizzandol'appositasys allfornitadal
µ
TNetOS.Lagenerazionedel orpodelletrefunzionièpossibilegrazieall'usodiuna
pro edurari orsiva( Visit Fields) he,ri orsivamente,visitai ampidel
messaggioegeneraopportunamenteil odi eCdellalorostrutturaedella
asso iato al messaggio del listato 27, mentre i listati 32, 33, 34 riportano la
generazionedelrelativoleMetaDataRequest. .
Listato 31 File header generato dal Generatore per il messaggio
MetadataRequest.
#ifndef _METADATAREQUEST_H_
#define _METADATAREQUEST_H_
#in lude "..\Messages\Pa ketType.h"
typedef stru t _MetaDataRequest { har
∗
Name; int RobletID; har∗
BrokerHost; int BrokerPort; Pa ketType Type;} MetaDataRequest;
int MetaDataRequest_startsWith( har
∗
buf, int len);int MetaDataRequest_Read(MetaDataRequest
∗
dest, har∗
buf, int len); har∗
MetaDataRequest_Write(MetaDataRequest∗
sr , har∗
dest, int len);Listato 32 MetaDataRequest. generato peril messaggio MetadataRequest.
Vengono riportate le funzioni a essorie e la funzione he si o upa del
ri onos imentodelmessaggio.
#in lude "MetaDataRequest.h"
#in lude <string.h>
#in lude <stdlib.h>
#in lude <stdio.h>
#define CHK(l) {int i = (l);dest += i;len
−
= i;if (len < 0) return 0;} #define MATCH(TOK) if (!(buf = mat h(buf, TOK))) return 0;\if ((n = len
−
(int)(buf−
start)) < 0) return 0; #define GOTO(TOK) buf = find(buf, TOK, n ); \if ((n = len
−
(int)(buf−
start)) < 0) return 0; #define SKIPBLANKS() buf = skipBlanks(buf, n ); \if ((n = len
−
(int)(buf−
start)) < 0) return 0; #define PARSEBOOL(buf) (str mppgm2ram(buf, "true") == 0)stati har
∗
skipBlanks( har∗
s, int len) {while (len
−−
&&∗
s && (∗
s == 0x20 ||∗
s == 0x09 ||∗
s == 0x0a ||∗
s == 0x0d)) s++;return s;
}
stati har
∗
mat h( har∗
b, har t) { if (∗
b == t)return b + 1;
return 0;
}
stati har
∗
find( har∗
b, har t, int len) { while (len−−
&&∗
b && !mat h(b, t)) b++; if (len &&∗
b)return b + 1;
return 0;
}
int MetaDataRequest_startsWith( har
∗
buf, int len) { har∗
start = buf; int n = len; SKIPBLANKS(); MATCH(0x80); SKIPBLANKS(); MATCH(0x81); return 1;Listato 33 MetaDataRequest. generato per il messaggioMetadataRequest.
Vieneriportatalafunzione hesio upadelladeserializzazionedelmessaggio.
int MetaDataRequest_Read(MetaDataRequest
∗
dest, har∗
buf, int len) { har∗
start = buf; har∗
p; int n = len; SKIPBLANKS(); MATCH(0x80) SKIPBLANKS(); MATCH(0x81); SKIPBLANKS(); MATCH(0x83); if (!(p = find(buf, 0x84, n ))) return 0;∗
(p−
1) = '\0'; dest−
>Name= (buf); buf = p;if ((n = len
−
(int)(buf−
start)) < 0) return 0; SKIPBLANKS();MATCH(0x85);
if (!(p = find(buf, 0x86, n ))) return 0;
∗
(p−
1) = '\0';dest
−
>RobletID = atoi(buf); buf = p;if ((n = len
−
(int)(buf−
start)) < 0) return 0; SKIPBLANKS(); MATCH(0x87); if (!(p = find(buf, 0x88, n ))) return 0;∗
(p−
1) = '\0'; dest−
> BrokerHost = (buf); buf = p;if ((n = len
−
(int)(buf−
start)) < 0) return 0; SKIPBLANKS();MATCH(0x89);
if (!(p = find(buf, 0x8a, n ))) return 0;
∗
(p−
1) = '\0';dest
−
>BrokerPort = atoi(buf); buf = p;if ((n = len
−
(int)(buf−
start)) < 0) return 0; SKIPBLANKS();MATCH(0x8b);
if (!(p = find(buf, 0x8 , n ))) return 0;
∗
(p−
1) = '\0';dest
−
>Type = Pa ketType_read(buf); buf = p;if ((n = len
−
(int)(buf−
start)) < 0) return 0; return 1;Listato 34 MetaDataRequest. generato peril messaggio MetadataRequest.
Vieneriportatalafunzione hesio upadellaserializzazionedelmessaggio.
har
∗
MetaDataRequest_Write(MetaDataRequest∗
sr , har∗
dest, int len) {∗
dest = 0x02; CHK(1);∗
dest = 0x80; CHK(1);∗
dest = 0x81; CHK(1);∗
dest = 0x83; CHK(1); CHK(sprintf(dest, "%s", sr−
>Name));∗
dest = 0x84; CHK(1);∗
dest = 0x85; CHK(1);CHK(sprintf(dest, "%d", sr
−
>RobletID));∗
dest = 0x86; CHK(1);∗
dest = 0x87; CHK(1); CHK(sprintf(dest, "%s", sr−
>BrokerHost));∗
dest = 0x88; CHK(1);∗
dest = 0x89; CHK(1);CHK(sprintf(dest, "%d", sr
−
>BrokerPort));∗
dest = 0x8a; CHK(1);∗
dest = 0x8b; CHK(1);CHK(Pa ketType_write(sr
−
>Type, dest, len));∗
dest = 0x8 ; CHK(1);∗
dest = 0x82; CHK(1);∗
dest = 0x03; CHK(1); return dest;Un aso di studio: Controllo
di un motore passo-passo
In questo apitolo mostriamo ome è possibile pilotareunmotore passo-passo
attraversoun PIC utilizzando il
µ
TNetOS e l'infrastruttura Roboti s4.NET. Il paragrafo 7.1 analizza brevemente i motori passo-passo. Il paragrafo 7.2des rive glistrumentiutilizzati, mentre ilparagrafo7.3 des riveil sistema nel
suo omplesso.