dll rfid programmation

32
Projet de Fin d’Etudes Conception de la DLL d’exploitation des RFID III.1 Introduction Ce chapitre sera consacré dans un premier temps à la présentation des différentes procédures nécessaires à l’exploitation des unités RFID de la cellule flexible ainsi que leur développement dans un projet de DLL par Mr Chevance Julien Nous allons ensuite présenter les difficultés rencontrées lors du chargement de la DLL dans WinCC et les solutions possibles pour leur résolution. Enfin nous allons présenter et décrire les fonctions de la DLL que nous avons développé pour l’exploitation des unités RFID. Mais étant donnée la nature de communication avec les unités RFID, nous nous attarderons tout d’abord à expliquer l’utilisation de la liaison série RS 232. III.2 La liaison série RS 232 Dans cette transmission, on utilise une seule ligne pour transmettre les données bit par bit. La donnée transférée en série est souvent envoyée en groupe de bits constituant un caractère ou un mot. Dans notre cas, les unités RFID disposent d’une liaison série de type RS232 pour communiquer avec un ordinateur. Etant donne la nature de la liaison RS232, des unités de multiplexage supplémentaires sont utilisées pour la liaison des huit unités RFID à l’ordinateur via deux ports de communication (COM1 et COM2). Chaque groupe de quatre unités est donc relié à un port de communication via une unité de multiplexage comme la montre la figure ci-dessous. Iyad MANSOUR ENIT 2006/2007 40

Upload: wassim-mansour

Post on 29-Sep-2015

251 views

Category:

Documents


6 download

DESCRIPTION

Cours sur la programmation d'une DLL pour communication avec RFID

TRANSCRIPT

Projet de Fin dEtudes Conception de la DLL dexploitation des RFID

III.1 IntroductionCe chapitre sera consacr dans un premier temps la prsentation des diffrentes procdures ncessaires lexploitation des units RFID de la cellule flexible ainsi que leur dveloppement dans un projet de DLL par Mr Chevance Julien Nous allons ensuite prsenter les difficults rencontres lors du chargement de la DLL dans WinCC et les solutions possibles pour leur rsolution.Enfin nous allons prsenter et dcrire les fonctions de la DLL que nous avons dvelopp pour lexploitation des units RFID.

Mais tant donne la nature de communication avec les units RFID, nous nous attarderons tout dabord expliquer lutilisation de la liaison srie RS 232.

III.2 La liaison srie RS 232Dans cette transmission, on utilise une seule ligne pour transmettre les donnes bit par bit. La donne transfre en srie est souvent envoye en groupe de bits constituant un caractre ou un mot.

Dans notre cas, les units RFID disposent dune liaison srie de type RS232 pour communiquer avec un ordinateur. Etant donne la nature de la liaison RS232, des units de multiplexage supplmentaires sont utilises pour la liaison des huit units RFID lordinateur via deux ports de communication (COM1 et COM2). Chaque groupe de quatre units est donc reli un port de communication via une unit de multiplexage comme la montre la figure ci-dessous.

Figure III. 1 : Cblage des units RFIDDiffrents paramtres entrent en jeu lors dune communication srie:

Longueur des mots: sur le PC, le BIOS ne permet une longueur de mots que de 7 ou 8 bits; Parit: Un mot transmis peut tre suivi dun bit de parit qui permet de dtecter les erreurs ventuelles de transmission. Il existe deux parits: la parit paire et la parit impaire; Bit de start: ce bit signale le dbut de la transmission;

Bit de stop: ce bit signale la fin de la transmission; Vitesse de transmission: la plupart des cartes srie permettent de choisir une vitesse entre 300 et 9600 bauds. Dans notre cas, nous utilisons une vitesse de 9600 bauds.

Afin de mieux comprendre la transmission srie nous allons crer, pour commencer, une communication srie entre deux ordinateurs.III.3 Procdures [4]La ralisation de linterface de communication entre le superviseur et les units de lecture/criture nous a amens la programmation et limplmentation des fonctions suivantes:Init_port ()Taper_commande ()

Init_port3 ()Lecture_octet ()

Fermeture ()Ok_donnees ()

Choix_com ()Ecriture_texte ()

Choix_head ()Read_all_octet ()

Trame_quit ()Lecture_32 ()

Trame_init ()Trame_c ()

Calcul_CHCK ()

Tableau III. 1 : Fonctions de la DLLLe dtail des fonctions se trouve en annexe 3.Nous allons maintenant expliquer les diffrentes fonctions utilises pour lexploitation des units RFID: Les fonctions dinitialisationInit_port () et Init_port3 () : ces deux fonctions permettent de configurer les deux ports srie (Com2 et Com3) qui sont utiliss pour la liaison avec les deux units dvaluation. Chaque unit dvaluation communique suivant la figure III.1.Les deux ports sont initialiss partir de lunique fonction dinitialisation Init_port (), mais si lon dsire crire ou lire partir de toutes les units RFID, il est ncessaire de crer une deuxime fonction dinitialisation pour utiliser les deux ports en mme temps. La fonction Fermeture (): ferme les ports aprs utilisation afin quils ne restent pas ouvert et quils puissent tre utiliss par dautres interfaces de communications. Les fonctions Choix_Com () : permet de renvoyer le numro du port srie utiliser ce qui revient choisir lunit dvaluation travers laquelle la communication sera tablie. La fonctiont Choix_Head () : permet de renvoyer le numro de lunit RFID utilis par cette unit. La fonction Trame_quit (): cette fonction permet denvoyer une trame qui permet dannuler les commandes antrieurs. Le premier caractre de cette trame est q pour dire quit.

Le format de la commande envoyer est: q Qui sera cod en hexadcimale par: 71 71 03. Le premier octet correspond au code ASCII de q au format hexadcimal, le deuxime correspond au checksum qui est le mme que le premier octet tant donn que dans cet exemple nous avons envoy uniquement un octet. Le dernier octet correspond au code ASCII du caractre de contrle ETX

Si la commande a t bien envoye on devrait recevoir la trame suivante: q=0)

{

dwComNum=com;switch(com)

{

case 1 : hThread[0] = CreateThread (NULL, 0, ReadComData1 , &dwComNum, 0, &dwThreadId[0]);

break;case 2 : hThread[1] = CreateThread (NULL, 0, ReadComData2, &dwComNum, 0, &dwThreadId[1]); break;

}

if (hThread[com-1]!=NULL)

{ SetThreadPriority(hThread[com-1],THREAD_PRIORITY_HIGHEST);

ret = TRUE;} }else... { dwLastError=GetLastError();

switch(dwLastError)

{ case ERROR_FILE_NOT_FOUND: ComSetError = CSERROR_PORT_DOES_ NOT_EXIST ; break;

default: ComSetError = CSERROR_OF_UNKNOWN_QUANTITY_ERROR; break; }

}

return ret;}Fonction de fermeture du port:int comreset(int com)

{ int ret;

ret=-1;

if (hCom[com-1]!=(HANDLE)0xffffffff)

{

if (hThread[com-1]!=NULL)

TerminateThread(hThread[com-1],0);

if (comin_buf[com-1]!=NULL)

delete comin_buf[com-1];

comin_buf[com-1]=NULL;

ret=CloseHandle(hCom[com-1]);

hCom[com-1]=(HANDLE)0xffffffff;

CloseHandle(comWriteOverlapped[com-1].hEvent);

CloseHandle(comReadOverlapped[com-1].hEvent);

} return ret;}Diffrence:

Le remplissage de la structure DCB se fait travers un passage des paramtres en arguments dans un tableau. Ensuite la fonction BuildCommDCB construit la structure de donnes avec les paramtres dsirs.

Les paramtres dsirs passent eux aussi en paramtre dans la nouvelle fonction Comset qui tait auparavant init_port() et init_port3().

Les fonctions dcriture et de lecture du port srie sont dfinies dans les fonctions dcriture et lecture relatives aux RFID. Ces dernires sont dveloppes indpendamment.Fonction dcriture via le port srie:int writedata(int com,BYTE c)

{

DWORD dwWritten, dwHandleSignaled, dwLastError;

HANDLE WaitHandles[2];

int success;

ComWriteError=0;

dwWritten=0;

WaitHandles[0]=comWriteOverlapped[com-1].hEvent;

success=FALSE;

ecriture[com-1]=WriteFile(hCom[com-1],&c,1,&dwWritten,&comWriteOverlapped[com-1]);

}

Fonction de lecture via le port srie:DWORD ReadComData(DWORD com)

{ DWORD dwRead;

BYTE c;

HANDLE WaitHandles[2];

DWORD dwLastError,dwHandleSignaled;

WaitHandles[0]=comReadOverlapped[com-1].hEvent; For (;;)

{

if (ReadFile (hCom [com-1], &c, 1, &dwRead, &comReadOverlapped[com-1]) = = TRUE )

{ comin_buf[com-1][comin_z2[com-1]]=c;

comin_z2[com-1]++;

if (comin_z2[com-1]>=MAXCOMINBUF)

comin_z2[com-1]=0;

comin_error[com-1]=0;

if (comin_z2[com-1]==comin_z1[com-1])

{

comin_error[com-1]=1;

ComReadError=CRERROR_OVERFLOW;

}} .

return dwRead;}Fonction de lecture depuis les units RFID:short int _stdcall Byte_read(BOOL Mode, char* head, char* status, char* adresse, char* number, char* data)

{short int bAllesOk = 0;

ins_data.iBytes = 6;

if (Mode) {ins_data.iCode[0] = 'W';

} else {ins_data.iCode[0] = 'w';

}

ins_data.iCode[1] = head[0];

ins_data.iCode[2] = adresse[0];

ins_data.iCode[3] = adresse[1];

ins_data.iCode[4] = number[0];

ins_data.iCode[5] = number[1];

if (Send()) { ans_data.iBytes = 5 + HexToInt(number);

if (Receive()) {

ShiftLeft(ans_data.idata, 1);

status[0] = ans_data.idata[0];

status[1] = ans_data.idata[1];

status[2] = '\0';

ShiftLeft(ans_data.idata, 2);

ArrayCopy(data, ans_data.idata, HexToInt(number));

bAllesOk = 1;}

}return bAllesOk;

}Fonction dcriture dans les units RFID:

short int _stdcall Bytes_write(BOOL Mode, char* head, char* status, char* adresse, char* number, char* data)

{

short int bAllesOk = 0;

ins_data.iBytes = 6 + HexToInt(number);

if (Mode)

{// Auto-Modus

ins_data.iCode[0] = 'K';

} else {// Single-Modus

ins_data.iCode[0] = 'k';

}

ins_data.iCode[1] = head[0];

ins_data.iCode[2] = adresse[0];

ins_data.iCode[3] = adresse[1];

ins_data.iCode[4] = number[0];

ins_data.iCode[5] = number[1];

for (int i=0; i < HexToInt(number); i++) {

ins_data.iCode[6 + i] = data[i];}

if (Send ( ) )

{

ans_data.iBytes = 5;

if (Receive())

{

ShiftLeft(ans_data.idata, 1);

status[0] = ans_data.idata[0];

status[1] = ans_data.idata[1];

status[2] = '\0';

bAllesOk = 1;

}

}

return bAllesOk;

}

Les fonctions Send () et Receive() sont expliques dans le dossier technique.III.6.5 Modification des structures de donnesLa classe CString utilise dans lancienne DLL nous a pos des complications, nous avons d changer cette classe et nous avons eu recours la structure de donnes struct qui contient des tableaux de caractres :

Une structure qui contient les informations qui vont tre crites dans les RFID;

Une structure qui contient les informations qui vont tre lues dans les RFID.

Structure de lecture:

struct ANSWER {int iStatus;

unsigned char idata[DATA_ARRAY ];

int iBytes; };

Structure dcriture:

struct INSTRUCTION {Unsigned char iCode[DATA_ARRAY ];

int iBytes;};

III.6.6 Changement de linstruction dexportation des fonctions de la DLL vers WinCC

Dans les applications telle que WIN CC, qui font appel une DLL, les fonctions doivent tre exportes laide de la convention dappel correcte sans la dcoration de noms effectue par le compilateur.

Linstruction _stdcall cre la convention dappel correcte pour la fonction (la fonction appele nettoie le pile et les paramtres sont passs de droite gauche) mais dcore le nom de la fonction diffremment.

En effet, La dcoration de nom _stdcall fait prcder le nom du symbole dun trait de soulignement (_) et annexe au symbole un arobase (@) suivi du nombre doctets dans la liste darguments (lespace de pile requis).

Lutilisation du mot cl _declspec(dllexport) produit leffet suivant:

Si la fonction est exporte laide de la convention dappel C (_cdecl), elle supprime le trait de soulignement de dbut (_) quand le nom est export.

Si la fonction exporte nutilise pas la convention dappel C (par exemple, _stdcall), elle exporte le nom dcor.

Comme il nexiste aucun moyen de redfinir les cas o le nettoyage de pile se produit, nous devons utiliser _stdcall. Pour supprimer la dcoration des noms au moyen de _stdcall, nous devons spcifier les noms laide dalias dans la section EXPORTS du fichier Rfid.def. Au fait les fonctions dveloppes dans RFID.dll seront imbriques dans dautres fonctions qui seront incluses dans le fichier principal de la DLL Rfid.cpp et qui elles, seront exportes.Nous prsenterons dans le prochain chapitre une liste et une description des fonctions exportables par la DLL.

III.6.7 Fonctions de la DLLLes fonctions de la DLL sont les suivantes: short int _stdcall Evaluation_unit_reset (BOOL Mode); short int _stdcall System_memory_examine(BOOL Mode, char* status); short int _stdcall Data_medium_type_adjust (BOOL Mode, char* data_medium); short int _stdcall Double_sided_read_letter_active (BOOL Mode); short int _stdcall Autoread_letter_terminate (BOOL Mode); short int _stdcall Version_message (BOOL Mode, char* version); int _stdcall Comset (int iPort, int iBaud, int iBits, int iStop, int iParity, int iTimeout); int _stdcall ComReset(int iPort); short int _stdcall Data_medium_read (BOOL Mode, char* head, char* status, char* data); short int _stdcall Bytes_write (BOOL Mode, char* head, char* status, char* adresse, char* number, char* data); short int _stdcall Byte_read (BOOL Mode, char* head, char* status, char* adresse, char* number, char* data); short int _stdcall Reset (BOOL Mode, char* head, char* status);

Description de quelques fonctions:

Evaluation_unit_reset (BOOL Mode): cette fonction permet denvoyer une trame permettant de rinitialiser linterface de lunit dvaluation tout en tenant compte de la configuration des interrupteurs. System_memory_examine (BOOL Mode, char* status) : cette fonction permet de vrifier ltat des mmoires EEPROM et RAM de la puce prsente dans la palette. Double_sided_read_letter_active (BOOL Mode) : cette fonction est utilise pour la lecture des donnes dans les deux sens ( du plus faible bit au plus fort et vice versa) Autoread_letter_terminate (BOOL Mode) : cette fonction interrompt la lecture automatique des donnes. Comset (int iPort, int iBaud, int iBits, int iStop, int iParity, int iTimeout) : Cette fonction permet de configurer les deux ports srie (Com1 et Com1) qui sont utiliss pour la communication avec les deux units dvaluations.

int _stdcall ComReset (int iPort) : Cette fonction permet de librer le port srie (Com1 ou Com2). short int _stdcall Bytes_write (BOOL Mode, char* head, char* status, char* adresse, char* number, char* data) : Cette fonction permet dcrire un Byte dans la puce. Elle donne la possibilit de choisir la tte dcriture, le mode dcriture et la destination des donnes crites.

short int _stdcall Byte_read (BOOL Mode, char* head, char* status, char* adresse, char* number, char* data) : Cette fonction permet de lire toutes les donnes de la puce. Elle donne la possibilit de choisir la tte de lecture, le mode de lecture et la destination des donnes lues.

short int _stdcall Reset (BOOL Mode, char* head, char* status): cette fonction efface tout le contenu de la puce.

Ainsi, nous avons introduit toutes les fonctions lmentaires pour raliser la nouvelle DLL.

III.6.8 Chargement de la DLL dans WinCCChaque application de WinCC (Graphics Designer, Tag Logging, Alarm Logging), contient son propre API dans une ou plusieurs DLL. On entend ici par DLL (Dynamic Link Library) une bibliothque de fonctions qui se charge dynamiquement. Les dclarations des fonctions places dans une DLL se trouvent dans un fichier d'en-tte associ.

Le code ci-dessous montre titre d'exemple la liaison de RFID.dll une action C.La premire ligne contient le nom de la DLL charger.Les lignes qui suivent permettent de charger les fonctions de la DLL.

La dclaration se termine par la ligne #pragma code ( ).Chargement de la DLL sous WinCC:#include "apdefap.h"

void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)

{#pragma code ("Rfid.dll")

short int Evaluation_unit_reset(BOOL Mode);

short int System_memory_examine(BOOL Mode, char* status);

short int Data_medium_type_adjust(BOOL Mode, char* data_medium);

short int Double_sided_read_letter_active(BOOL Mode);

short int Autoread_letter_terminate(BOOL Mode);

short int Version_message(BOOL Mode, char* version);

int Comset (int iPort, int iBaud, int iBits, int iStop, int iParity, int iTimeout);

int ComReset(int iPort);

short int Data_medium_read(BOOL Mode, char* head, char* status, char* data);

short int Bytes_write(BOOL Mode, char* head, char* status, char* adresse, char* number, char* data);

short int Byte_read(BOOL Mode, char* head, char* status, char* adresse, char* number, char* data);

short int Reset(BOOL Mode, char* head, char* status);

#pragma code ()}Aprs avoir russi le chargement de la DLL, nous avons ralis une interface graphique avec WinCC qui nous permet de lire les donnes prsentes dans les palettes via les units RFID et crire via les units RFID dans les palettes.Interface dcriture et lecture WinCC RFID

Figure III. 8 : Interface dexploitation des units RFIDNoua allons dans ce qui suit dcrire les fonctions criture dans RFID et lecture des RFID

Code de la fonction criture dans RFID partir de WinCC:

#include "apdefap.h"

Void OnClick(char* lpszPictureName,char* lpszObjectName, char* lpszPropertyName)

{// Dfinition de la taille de la donne

#define DATA_ARRAY 129// Chargement de la DLL

#pragma code ("Rfid.dll")

Short int Evaluation_unit_reset(BOOL Mode);

Short int System_memory_examine(BOOL Mode,char* status);

int Comset(int iPort, int iBaud, int iBits, int iStop,int iParity,int iTimeout);

int ComReset(int iPort);

Short int Bytes_write (BOOL Mode, char* head, char* status, char* adresse, char* number, char* data);

#pragma code ()

// Fin du chargement de la DLL// Dclaration des variables locales

int i;

Char buffer[3];

Char data[DATA_ARRAY ];

Char input[DATA_ARRAY ];printf("\Programme d'exploitation des RFID\n\n");

printf("\n ECRITURE\n");// Ouverture et initialisation du port

Comset(1,9600,8,1,0,20);// Initialisation de lunit RFID

Evaluation_unit_reset(TRUE);// Ajustement des donnes

Data_medium_type_adjust(TRUE, "4");// Copie de la chane de caractre crire dans lunit RFID dans input

Strcpy (input, "pallette 1 ");

Strcpy (buffer, "xx");// Ecriture de la chane de caractre dans lunit RFID

Bytes_write (TRUE, "1", buffer, "10", "34", input);// Fermeture du port

ComReset (1);

}

Code de la fonction lecture des RFID partir de WinCC:

#include "apdefap.h"

void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)

{//Dfinition de la taille de la donne

#define DATA_ARRAY 129// Chargement de la DLL

#pragma code ("Rfid.dll")

Short int Evaluation_unit_reset(BOOL Mode);

Short int System_memory_examine(BOOL Mode, char* status);

int Comset(int iPort, int iBaud, int iBits, int iStop, int iParity, int iTimeout);

int ComReset(int iPort);

short int Byte_read(BOOL Mode, char* head, char* status, char* adresse, char* number, char* data);

#pragma code()// Fin du chargement de la DLL

int i;

// Dclaration des variables locales

char buffer[3];

char data[DATA_ARRAY ];

char input[DATA_ARRAY ];

printf("\nLECTURE PALETTE_1");// Ouverture et initialisation du port

Comset(1,9600,8,1,0,20);// Lecture de la chane de caractre de lunit RFID

Byte_read(TRUE, "1", buffer, "10", "34", data);

printf("\nStatus: %s\t", buffer);

printf("\nles donnes sont :\t");// Affichage de la chane lue

for ( i = 0; i < 10; i++)

{

char c = data[i];

printf("%c ", c);

}

printf("\n");

// Fermeture du port

ComReset(1);

}III.7 ConclusionNous avons prsent au cours de ce chapitre la DLL ralise par le Sous lieutenant Chevance Julien, ainsi que les diffrents problmes rencontrs lors du chargement de la DLL dans WinCC.

Nous avons ensuite dcrit les modifications apportes la DLL afin quelle puisse tre fonctionnelle avec WinCC.

En effet, le passage des variables en tant quarguments des fonctions nous a limin dnormes obstacles.Enfin nous avons prsent les nouvelles fonctions de la DLL RFID.dll.Le chargement de la DLL sera ncessaire afin quon puisse aiguiller les palettes vers les stations dsires. Cette partie sera dtaille dans le chapitre IV.Si la cration de Threads a russi, on affecte la priorit la plus haute au Thread.

Cration de Threads pour la gestion de la lecture du port srie.

Chaque port a son propre Thread

Si la cration dvnements a russi, on commence remplir la structure DCB (responsable de la communication) avec les paramtres de configuration de la communication srie

Sil ny a aucune erreur dans lexcution de la fonction Writefile, on initialise les buffers et les variables puis on cre des vnements pour lcriture et la lecture des donnes.

Nom de la fonction

Affectation de COM1 ou COM 2 la variable comstr

Paramtrage du bit de parit

Dclaration des variables locales

Dclaration des variables locales

Choix du port COM2 grce au choix de lidentificateur 3

Aprs Build

Rfid.dll

Rfid.cpp

Rfid.dsw

Rfid.def

Comtools.cpp

Comtools.h

Sil y a eu une erreur dans lexcution de la fonction WriteFile, on affecte la variable ComSetError les diffrentes erreurs qui peuvent apparatre.

Exemple: port occup ou port non disponible

Dclaration des variables locales

Nom de la fonction

Arrt du Thread

Effacement des buffers

Fermeture du port

Arrt des vnements de lecture et criture

Ecriture COM1.

Cration de lvnement dcriture

Dclaration des variables locales

Dclaration des variables locales

Cration de lvnement

de lecture

Lecture du port.

Choix du mode dcriture

K: mode automatique

k : mode manuel

Remplissage de la structure de donnes dinstruction avec les paramtres: head, adresse et number.

Envoi des instructions vers les units RFID et rception des rponses depuis les units RFID

Envoi des instructions vers les units RFID et rception des rponses depuis les units RFID

Remplissage de la structure de donnes dinstruction avec les paramtres: head, adresse et number.

Choix du mode de lecture

W: mode automatique

w : mode manuel

Dclaration des variables locales

Unit RFID

3

Port srie du PC de supervision

Superviseur

Lecture - Ecriture dans RFID

Lecture - Ecriture

RS232C

COM1

COM2

2

1

Units dvaluation

PAGE 61Iyad MANSOUR

ENIT 2006/2007