Bug fix & documentation...

This commit is contained in:
zonetest 2017-09-01 14:17:18 -04:00
parent 36a735db06
commit 9029432d46
5 changed files with 106 additions and 49 deletions

View File

@ -71,11 +71,11 @@ ENGLOG=3
#STATION=HONORE_BEAUGRAND #STATION=HONORE_BEAUGRAND
#STATION=ANGRIGNON #STATION=ANGRIGNON
#STATION=HENRI_BOURASSA #STATION=HENRI_BOURASSA
STATION=COTE_VERTU #STATION=COTE_VERTU
#STATION=BERRI_UQAM #STATION=BERRI_UQAM
#STATION=LONGUEIL #STATION=LONGUEIL
#STATION=SAINT_MICHEL #STATION=SAINT_MICHEL
#STATION=SNOWDON_L5 STATION=SNOWDON_L5
#STATION=MONTMORENCY #STATION=MONTMORENCY
#STATION=MONTMORENCY_10_12 #STATION=MONTMORENCY_10_12
#STATION=MONTMORENCY_10_22 #STATION=MONTMORENCY_10_22

Binary file not shown.

View File

@ -43,7 +43,7 @@
#define ZT_EXTERNAL_WATCHDOG_TIMEOUT 10000 //10 seconds #define ZT_EXTERNAL_WATCHDOG_TIMEOUT 10000 //10 seconds
#define ZT_EXTERNAL_WATCHDOG_PULSE_TIME 1000 //1 second #define ZT_EXTERNAL_WATCHDOG_PULSE_TIME 1000 //1 second
#define ZT_SM_MAX_NB_PG_CALIB_PASSAGES 50 //Nb maximal de passages pour calibration du pneu guidage #define ZT_SM_MAX_NB_PG_CALIB_PASSAGES 50 //Nb maximal de passages pour calibration du pneu guidage
#define ZT_DEFAULT_DETECTION_RANK 1 //The rank of a detection when there is a count error #define ZT_DEFAULT_DETECTION_RANK 99 //The rank of a detection when there is a count error
//To be able to run the application with no PCI card installed. //To be able to run the application with no PCI card installed.

View File

@ -1,3 +1,31 @@
/*******************************************************************************
* *
* Société de Transports de Montréal. *
* 2012 - 2013 *
* *
* Projet Zones Tests *
* *
* *
* *
*******************************************************************************/
/*
Description:
Classe qui implémente le protocole Modbus.
*/
/* ************************************************************************** */
/* Revision:
### YYYMMDD JFM
Verision d'origine.
### YYYYMMDD Description du besoin ou du bug
Description du changement.
*/
/* ************************************************************************** */
#include "ModbusBackend.h" #include "ModbusBackend.h"
#include "QBuffer" #include "QBuffer"
#include "EngLog.h" #include "EngLog.h"
@ -47,15 +75,15 @@ void CModbusBackend::ModbusDataReady()
if(mModbusMode == MODBUS_MASTER_MODE) if(mModbusMode == MODBUS_MASTER_MODE)
{ {
AnalyzeModbusResponse(Transaction); AnalyzeModbusResponse(Transaction); //Le maître recoit des réponses
} }
else if( mModbusMode == MODBUS_SLAVE_MODE) else if( mModbusMode == MODBUS_SLAVE_MODE)
{ {
AnalyzeModbusRequest(Transaction); AnalyzeModbusRequest(Transaction); //L'esclave recoit des requêtes
} }
else else
{ {
CEngLog::instance()->AddLogString("Erreur Modbus: <Illegal modbus backend mode...>"); CEngLog::instance()->AddLogString("Erreur Modbus: <Illegal modbus backend mode...>"); //Erreur de logique interne. Ne doit pas survenir normalement
} }
} }
@ -63,6 +91,7 @@ void CModbusBackend::ModbusLinkDisconnected()
{ {
// qDebug("Modbus link disconnected"); // qDebug("Modbus link disconnected");
mDataLinkValid = false; mDataLinkValid = false;
mModbusTCPSocketHandle->flush();
} }
@ -93,7 +122,7 @@ int CModbusBackend::AnalyzeModbusRequest(CModbusTransaction Transaction)
if(NbRegisters < 1 || NbRegisters > MODBUS_MAX_NB_REGISTERS) if(NbRegisters < 1 || NbRegisters > MODBUS_MAX_NB_REGISTERS)
{ {
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE); SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE);
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS); ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS); //Fonction à être implémentée par le parent
return 0; return 0;
} }

View File

@ -1,3 +1,25 @@
/*******************************************************************************/
/*
Description:
Classe qui implémente le protocole Modbus.
Cette classe est héritée par la classe serveur (CModbusCCMgr) ou client (CModbusMaster).
Elle sert à interpréter ou formatter des paquets Modbus provenant ou destinés au partenaire.
Elle peut être héritée soit un parent qui implémente une instance maître ou client mais pas les deux à la fois.
sur le réseau.
*/
/* ************************************************************************** */
/* Revision:
### YYYMMDD JFM
Verision d'origine.
### YYYYMMDD Description du besoin ou du bug
Description du changement.
*/
/* ************************************************************************** */
#ifndef CMODBUSBACKEND_H #ifndef CMODBUSBACKEND_H
#define CMODBUSBACKEND_H #define CMODBUSBACKEND_H
#include <QObject> #include <QObject>
@ -31,6 +53,7 @@ enum eModbusExceptionCodes
MODBUS_EXCEPTION_GATEWAY_TARGET_DEV_NOT_RESPONDING = 11 MODBUS_EXCEPTION_GATEWAY_TARGET_DEV_NOT_RESPONDING = 11
}; };
//Énumération des différents modes possibles
enum eModbusModes enum eModbusModes
{ {
MODBUS_MASTER_MODE, MODBUS_MASTER_MODE,
@ -47,11 +70,11 @@ public:
class CModbusPDU class CModbusPDU
{ {
public: public:
qint8 mFunctionCode; qint8 mFunctionCode; //Type de transaction (voir structure eModbusFunctions) pour les fonctions implémentées par le présent module
QByteArray mData; QByteArray mData; //Les données de la transaction
}; };
class CModbusHeader class CModbusHeader //Objet contenant les données d'un header Modbus (selon la spécification)
{ {
public: public:
qint16 mTransactionID; qint16 mTransactionID;
@ -60,20 +83,20 @@ public:
qint8 mUnitID; qint8 mUnitID;
}; };
class CModbusTransaction class CModbusTransaction //Objet contenant les données d'une transaction Modbus
{ {
public: public:
CModbusHeader mHeader; CModbusHeader mHeader; //Le header de la transaction
CModbusPDU mPDU; CModbusPDU mPDU; //Le PDU (fonction & données) de la transaction (voir classe CModbusPDU)
}; };
class CModbusRequest : public CModbusTransaction class CModbusRequest : public CModbusTransaction //Objet représentant une transaction (mode maître)
{ {
public: public:
CModbusRequest(); CModbusRequest();
~CModbusRequest(); ~CModbusRequest();
int mRetries; int mRetries; //nombre de fois que la transaction a été retransmise
QTimer *mRequestTimer; QTimer *mRequestTimer; //Timer servant à retransmettre la requête si aucune réponse ne survient
quint16 mStartAddress, mNbRegisters; //For convinience... quint16 mStartAddress, mNbRegisters; //For convinience...
}; };
@ -84,64 +107,69 @@ class CModbusBackend : public QObject
private: private:
enum eModbusMasterSMStates //enum eModbusMasterSMStates
{ //{
MODBUS_SM_WAIT_FOR__STATE // MODBUS_SM_WAIT_FOR__STATE
}; //};
enum eModbusSlaveSMStates //enum eModbusSlaveSMStates
{ //{
}; //};
public: public:
CModbusBackend(CModbusRepository *Repo); CModbusBackend(CModbusRepository *Repo); //Le pointeur vers le registre des données est obligatoire.
virtual ~CModbusBackend(); virtual ~CModbusBackend();
QTcpSocket *mModbusTCPSocketHandle; QTcpSocket *mModbusTCPSocketHandle; //Pointeur vers le Socket TCP du réseau Modbus.
CModbusRepository *mModbusRepo; CModbusRepository *mModbusRepo; //Pointeur vers le registre de données Modbus
bool mDataLinkValid; bool mDataLinkValid; //Flag indiquant si le lien de communication est en santé
int mModbusMode; int mModbusMode; //Indique si le lien modbus de cette instance est exploitée en "slave" (serveur) ou un "master" (client) (voir struct eModbusModes ci-haut).
qint8 mDeviceID; qint8 mDeviceID; //Le device ID Modbus de cette instance.
void ModbusLinkDisconnected(); void ModbusLinkDisconnected(); //Fonction appelée par le parent lors d'une perte de la connection.
void SetDeviceID(qint8 ID){mDeviceID = ID;} void SetDeviceID(qint8 ID){mDeviceID = ID;}
//Master (client) //Master (client)
int SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); int SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); //Fonction servant à transmettre la fonction modbus "Read HR" au partenaire
int SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); int SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); //Fonction servant à transmettre la fonction modbus "Write HR" au partenaire
int SendWriteSingleRegisterRequest(quint16 Address); int SendWriteSingleRegisterRequest(quint16 Address); //Fonction servant à transmettre la fonction modbus "Write Single Register" au partenaire
virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; //Fonction virtuelle à être implémentée par le parent
//Appelée lorsque de nouvelles données ont été reçues du réseau Modbus et écrites dans le registre
//Master Exception //Master Exception
virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par le parent
//Sert à informer le parent lorsqu'une exception se produit dans la communication Modbus (réponse)
//Slave Exception //Slave Exception
virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par le parent
//Sert à informer le parent lorsqu'une exception se produit dans la communication Modbus (requête)
private: private:
//Sur un réseau Modbus, l'eslcave (slave) est un serveur et le maître (master) est un client.
//Slave (server) //Slave (server)
int AnalyzeModbusRequest(CModbusTransaction Transaction); int AnalyzeModbusRequest(CModbusTransaction Transaction); //Exécute l'analyse des données reçues d'une requête Modbus
int ModbusStateMachine(int Event, QByteArray Data); int SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data); //Fonction servant à composer et transmettre une réponse à une requête.
int SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data); int SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode); //Fonction servant à composer et transmettre une réponse d'erreur à une requête.
int SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode);
//Master (client) //Master (client)
QList<CModbusRequest*> mRequestsList; QList<CModbusRequest*> mRequestsList; //Liste des requêtes courantes en attente d'une réponse du serveur
int SendModbusRequest(CModbusRequest *Request); int SendModbusRequest(CModbusRequest *Request); //Construit et transmet une nouvelle requête Modbus au partenaire.
quint16 GetNewTransactionID(); quint16 GetNewTransactionID(); //Fonction (helper) servant à générer un nouvel ID de transaction nécessaire pour transmettre une nouvelle requête.
int AnalyzeModbusResponse(CModbusTransaction Transaction); int AnalyzeModbusResponse(CModbusTransaction Transaction); //Exécute l'analyse des données reçues d'une réponse Modbus
quint16 mTransactionIDCounter; quint16 mTransactionIDCounter; //Compteur interne des ID de transactions Modbus
int mModbusRequestTimeout; int mModbusRequestTimeout; //Valeur du délai d'attente maximal avant de recevoir une réponse à une requête. À l'expiration du timer, la requête est renvoyée.
int mModbusMaxRetry; int mModbusMaxRetry; //Valeur du nombre maximal de renvoi d'une requête avant d'invalider la requête.
signals: signals:
@ -156,9 +184,9 @@ signals:
public slots: public slots:
void ModbusDataReady(); void ModbusDataReady(); //Slot indiquant au module que des données sont arrivées et sont attente dans le Socket.
void RequestTimerExpired(); void RequestTimerExpired(); //Slot indiquant qu'un timer de requête a expiré.
}; };