Anwendung der COM-Komponententechnologie in der Konfigurationssoftware von Feldbus-Steuerungssystemen
2026-02-21 11:01:01··#1
Die COM-Technologie (Component Object Model) ist eine Spezifikation zur Erstellung binärkompatibler Software. Sie ermöglicht die Entwicklung von Komponenten zum Datenaustausch und eignet sich aufgrund ihrer Client-Server-Architektur hervorragend für die Entwicklung von industriellen Steuerungssoftwareanwendungen. Da industrielle Steuerungssoftware neben der HMI-Software (Human-Machine Interface) auf dem PC auch Programme zum Datenaustausch mit verschiedenen ISA- oder PCI-Bus-basierten Datenerfassungskarten umfasst, erfordert letztere ein höheres Maß an Hardware-Know-how von den Entwicklern und ist komplexer zu entwickeln. Aufgrund ihrer Unabhängigkeit von der HMI-Software lässt sich die industrielle Steuerungssoftware in zwei Teile unterteilen: die HMI-Software als Client-Seite und die Software für den Datenaustausch mit der Hardware als Server-Seite. Ausgehend von diesem Ansatz wendet dieser Artikel die Client-Server-Architektur auf die Konfigurationssoftware eines Feldbus-Steuerungssystems an und konzentriert sich dabei auf die Funktionen und die Implementierung von Client und Server. Zunächst wird der Aufbau des Feldbus-Steuerungssystems erläutert. 1 Systemzusammensetzung Das Feldbus-Steuerungssystem besteht im Wesentlichen aus einem PC, intelligenten ISA- oder PCI-Bus-Adaptern, intelligenten Mess- und Steuermodulen, Konfigurationssoftware, HMI-Software, einem COM-Server und Anwendersoftware. Die gesamte Datenübertragung im Feldbussystem ist bidirektional. Der COM-Server fungiert als Vermittler zwischen dem intelligenten Adapter und der Host-Computer-Software und ist für die Datenübertragung verantwortlich. Die Host-Computer-Software entspricht der Client-Anwendungssoftware. Sie nutzt die vom COM-Server bereitgestellte Schnittstelle, um den Adapter zu steuern, zu initialisieren und Daten von und an bestimmte Einheiten zu senden und zu empfangen. Da im Windows-geschützten Modus nicht direkt auf den Speicher zugegriffen werden kann, muss ein VxD-Treiber geschrieben werden, um physische Adressen in lineare Adressen zu übersetzen. Anschließend kann COM VxD-Funktionen wie eine DLL aufrufen, um den intelligenten ISA- oder PCI-Bus-Adapter zu steuern. Die Bottom-Up-Datenübertragung vom Mess- und Steuermodul zur Host-Computer-Software ermöglicht dem Benutzer die Überwachung des Mess- und Steuermoduls. Während die übergeordnete Software Daten über COM an den Adapter und von diesem an das Mess- und Steuermodul sendet, können Benutzer die Betriebsparameter einstellen und den Betriebszustand des Moduls verwalten. Abbildung 1 zeigt das Systemsoftware-Strukturdiagramm. 2. Funktionen der Konfigurationssoftware Die Konfigurationssoftware des Feldbus-Steuerungssystems besteht aus Softwarekomponenten, die auf Windows 98- und Windows 2000-Plattformen (oder höher) basieren und zum schnellen Aufbau und zur Generierung von Host-Computer-Überwachungssystemen dienen. Sie bietet eine Komplettlösung für praktische technische Probleme – von der Datenerfassung über die Datenverarbeitung und Fernsteuerung bis hin zur Alarmbehandlung und Berichtsausgabe. Sie nutzt die vom COM-Server bereitgestellte Schnittstelle zum Datenaustausch mit dem Adapter und fungiert als COM-Client-Programm. 3. COM-Komponententechnologie Eine Komponente ist ein Softwarebaustein, der eine spezifische Funktion ausführt, von anderen Programmen verwendet und leicht ausgetauscht werden kann. Um die Portabilität der von jedem Benutzer entwickelten Komponenten zu gewährleisten, muss ein Standard etabliert werden, der Kompatibilität und Austauschbarkeit sicherstellt. COM ist ein solcher Standard; durch die Einhaltung der COM-Regeln können Komponenten erstellt werden, die Daten austauschen können. In einem Feldbus-Steuerungssystem ist der COM-Komponentenserver für die Datenübertragung zwischen der Host-Software (z. B. Konfigurationssoftware) und dem intelligenten Adapter zuständig. Da der Adapter über den CAN-Feldbus mit dem Mess- und Steuermodul verbunden ist, entsprechen Operationen am Adapter der Überwachung und Steuerung des Moduls. Der COM-Server stellt Schnittstellen für die Adapterinitialisierung, die Modulprüfung, das Senden und Empfangen von Daten bereit. Im Folgenden werden die Datenübertragungs- und -empfangsmodi sowie die Implementierung dieser vier repräsentativen Funktionen erläutert. 3.1 Adapterinitialisierung: Weitere Operationen können erst nach erfolgreicher Initialisierung des Adapters durchgeführt werden. Da im geschützten Modus von Windows nicht direkt auf den Adapter zugegriffen werden kann, muss das COM-Programm das VxD-Programm aufrufen, um die entsprechende physikalische Adresse in einen linearen Adresszeiger lpBaseAddress umzuwandeln. Operationen am Adapter werden somit zu Operationen auf dem Array ab diesem Zeiger. Schreiben Sie die Knotennummer des Host-Computers, die Baudrate der Kommunikation zwischen Adapter und Modul sowie das vom Adapterprogramm festgelegte Befehlswort 0xC6 (zur Initialisierung des Adapters) in die Array-Zellen 0x3F0, 0x3F1 und 0x3F8. Nach einer Wartezeit von einigen zehn Millisekunden löscht der Adapter die Zelle 0x3F8, wenn er die Daten empfängt und entsprechend reagiert. Dies signalisiert eine erfolgreiche Initialisierung. Ist der Wert in der Zelle ungleich null, schlägt die Initialisierung fehl. 3.2 Datenübertragungsformat Nach erfolgreicher Initialisierung des Adapters können Daten ausgetauscht werden. Im Folgenden wird das Format für das Senden und Empfangen von Daten kurz erläutert. Die Zellen 1 bis 5 des während der Adapterinitialisierung erhaltenen linearen Adresszeigers lpBaseAddress speichern die Knotennummer des Host-Computers, die Knotennummer des Moduls, reservierte Wörter, die Länge der zu sendenden oder zu empfangenden Bytes sowie das Befehlswort für den Modulbetrieb. lpBaseAddress[6] bis lpBaseAddress[256] speichern die zu sendenden Daten. Ab lpBaseAddress[0x106] werden die empfangenen Daten gespeichert, und lpBaseAddress[0x3F8] speichert das Befehlswort für den Betrieb des Adapters. Der Adapter verarbeitet die Daten entsprechend dem Inhalt dieser Einheit. Bei einem Wert von 0xC6 werden der Adapter und der CAN-Controller des Moduls initialisiert; bei 0xC7 werden die Zahlen im Array an den E2PROM des Moduls gesendet. Nach dem Empfang der Daten verarbeitet das Modul diese gemäß dem Befehlswort von lpBaseAddress[5]. Bei 0xB0 wird der Betriebszustand des Moduls anhand der empfangenen Daten konfiguriert; bei 0xA5 wird der Messwert an den Adapter gesendet und vom COM-Programm ausgelesen. 3.3 Modulprüfungsfunktion Nach erfolgreicher Initialisierung des Adapters muss geprüft werden, ob der Adapter mit dem darunterliegenden Mess- und Steuermodul verbunden ist oder ob ein Modul von der Konfigurationssoftware konfiguriert werden muss. Hierfür ist eine Modulprüfung erforderlich. Das Befehlswort für die Modulprüfung ist 0xAD. Schreiben Sie die Host-Computer-Knotennummer, die Modul-Knotennummer, das reservierte Wort, die zu sendende Datenlänge und das Modulprüfbefehlswort 0xAD in die Array-Einheiten 1 bis 5. Schreiben Sie 0xC7 in Einheit 0x3F8 (um anzuzeigen, dass Daten an den Adapter geschrieben wurden). Wenn nach einigen zehn Millisekunden Einheit 0x3F8 gelöscht und Einheit 0x100 auf 0xAA gesetzt wird, bedeutet dies, dass das Modul existiert und kommunizieren kann; andernfalls bedeutet dies, dass das Modul nicht existiert oder ein Hardwareproblem vorliegt. 3.4 Funktion zum Schreiben von Adapterdaten Nachdem die kommunikativen Module im Netzwerk ermittelt wurden, können Daten an diese gesendet und konfiguriert werden. Um das Senden von Daten an den Adapter zu realisieren, wurden insgesamt vier Funktionen geschrieben: SendData([in]BYTE SendBuf[256]), SendFinish([in]BOOL bFinish), FinishQuery([out]BOOL*bFinish) und ReceiveResult([out]BOOL*bSendFinish). SendData ist dafür zuständig, die von einem Modul zu sendenden Daten in einem zweidimensionalen Array (Room[64][256]) auf dem Server zu speichern, wobei die Daten jedes Moduls eine Zeile bilden. Da nach dem Senden der Daten an den Adapter eine gewisse Wartezeit erforderlich ist, um festzustellen, ob das Modul die Daten erfolgreich empfangen hat, wird in SendFinish ein Hilfsthread gestartet, der die Daten sendet und auf das Ergebnis wartet. Dadurch wird die Laufzeit des COM-Hauptprogramms nicht blockiert, sodass der Client nach dem Aufruf der Schnittstellenfunktion sofort zurückkehren und andere Operationen ausführen kann. FinishQuery prüft, ob die Datenübertragung abgeschlossen ist. ReceiveResult öffnet ein nicht-modales Dialogfeld, das anzeigt, welche Module die Daten empfangen haben und welche nicht. 3.5 Funktion zum Lesen von Adapterdaten: Zusätzlich zum Senden von Daten an den Adapter kann diese Funktion auch die vom Modul an den Adapter gesendeten Daten lesen. Das Befehlswort zum Lesen von Daten ist 0xA5. Die Funktion zur Implementierung dieser Aufgabe ist GetPV([in]BYTE bDesNode, [out]float value[8]). Der erste Parameter ist die Modulknotennummer, der zweite das Array der zurückgegebenen Messwerte. Hierbei handelt es sich bei COM um einen in ATL geschriebenen lokalen Server, und der Thread des COM-Objekts ist der Socket-Thread. Die Schnittstelle definiert sechs Funktionen. Das Ablaufdiagramm des COM-Programms ist in Abbildung 2 dargestellt. Die Funktionsdeklarationen der COM-Objektschnittstelle und die Initialisierungsprozedur des Adapters lauten wie folgt: COM-Schnittstellendefinition: interface INCardWork :IDispatch { [id(1), helpstring("Adapter-Initialisierungsfunktion, Rückgabewert gibt an, ob sie erfolgreich war")] HRESULT NcardInit([in]BYTE bSrcNode,[in]BYTE bIntrAdd,[in]BYTE bRate,[in]long bSegmantAdd,[out]BOOL *flag); [id(2), helpstring("Weist das vom Client gesendete Array Room[][] zu")] HRESULT SendData[in]BYTE SendBuf[256]); [id(3), helpstring("Startet Multithreading")] HRESULT SendFinish([in]BOOL bFinish); [id(4), helpstring("Diese Funktion gibt zurück, ob die Daten an den zugrunde liegenden Rechner gesendet wurden und zeigt an, welche Module noch nicht konfiguriert sind. Normalerweise wird FinishQuery([out]BOOL *bFinish) verwendet, um vor dieser Funktion abzufragen, ob das Senden abgeschlossen ist.")] HRESULT ReceiveResult([out]BOOL *bSendFinish); [id(5)], helpstring("Diese Funktion gibt zurück, ob die Daten an den zugrunde liegenden Rechner gesendet wurden. "True" bedeutet, dass das Senden abgeschlossen ist.")] HRESULT FinishQuery([out]BOOL *bFinish); [id(6), helpstring("Netzwerkprüfung, wird verwendet, um zu prüfen, ob der Knoten vor dem Senden von Daten existiert")] HRESULT NetCheck[in]BYTE sour,[in]BYTE des,[in]BYTE type,[out]BOOL *flag); [id(7), helpstring("Lesen des Messwerts des Moduls")] HRESULT GetPV([iv]BYTE bDesNode,[out]float value[256]); } Adapter-Initialisierungsfunktion: #include #include "winioctl.h" // Weitere Header-Dateien einbinden... STDMETHODIMP CNCardWork::NcardInit(BYTE bSrcNode, BYTE bIntrAdd, BYTE bRate, long bSegmentAdd, BOOL *flag) { NcardCtrl cardctrl; // Funktionsaufruf der Klasse NcardCtrl VxD function exbSrcNode=bSrcNode; // Wert dem Host-Knoten zuweisen exbRate=bRate; // Baudrate für die Kommunikation zwischen Slave und Adapter BOOL transfersign; // Flag für erfolgreiche Initialisierung DWORD dwSegmentaddress=bSegmentAdd;//Segmentadresse des Adapters HANDLE hDevice=NULL; // Handle zum linearen Zeigerpaar LpBaseAddress=(PBYTE)cardctrl.MapLinearAddress(dwSegmentaddress,0x400,hDevice); // Die VxD-Funktion aufrufen, um einen linearen Adresszeiger auf die physische Adresse des ISA-Busses zu erhalten. cardctrl, UnMapLinearAddress(lpBaseAddress, hDevice); // VxD schließen // Die Adapterinitialisierungsfunktion aufrufen _outp(0x310, 0x01); // Mailbox-Sperre öffnen lpBaseAddress[0x3F0] = bSrcNodeNumber; // Knotennummer des Host-Computers lpBaseAddress[0x3F1] = bRate; // Baudrate lpBaseAddress[0x3F8] = 0xC6; // Befehlswort für die Adapterinitialisierung DrvDelay(20, false); // 20 ms Verzögerung ………… // Weitere Operationen nach der Initialisierung _outp(0x310, 00); // Mailbox-Sperre schließen return S_OK; } 4 Virtueller Gerätetreiber VxD ist die Abkürzung für Virtual Device Driver, wobei das x in der Mitte ein Gerät darstellt. Es hat uneingeschränkten Zugriff auf alle Hardwaregeräte, freien Zugriff auf Betriebssystem-Datenstrukturen (wie Deskriptoren und Seitentabellen) und Zugriff auf jeden Speicherort. In diesem Artikel übersetzt VxD die dem ISA-Bus entsprechende physische Adresse in eine segmentlineare Adresse zur Verwendung durch die Anwendung. Das Entwicklungswerkzeug für VxD ist VtoolsD, und die für die Übersetzung verwendete Funktion ist MapPhysToLinear. Nachfolgend ein Codeausschnitt: // Struktur definieren typedef struct _MapDevRequest { PVOID mdr_PhysicalAddress; DWORD mdr_SizeInBytes; PVOID mdr_LinearAddress; WORD mdr_Status; } MAPDEVREQUEST, *PMAPDEVREQUEST; #include //Weitere Headerdateien einbinden………… PARAMS pDIOCParams { PMAPDEVREQUEST pRea; //Benutzerdefinierte Struktur switch(pDIOCParams->dioc_IOCtlCode) { case DIOC_OPEN: case DIOC_CLOSEHANDLE:break; case MDR_SERVICE_MAP: pReq=*(PMAPDEVREQUEST*)pDIOCParams->dioc_InBuf; pReq->mdr_LinearAddress=MapPhysToLinear (pReq->mdr_PhysicalAddress,pReq->mdr_SizeInBytes,0); if (pReq->mdr_LinearAddress==NULL) pReq->mdr_Status=MDR_STATUS_ERROR; else pReq->mdr_Status=MDR_STATUS_SUCCESS; break; case MDR_SERVICE_UNMAP:break; default: return ERROR_INVALID_FUNCTION; } return DEVIOCTL_NOERROR; } Der Einsatz von COM-Komponententechnologie in Feldbus-Steuerungssystemen macht die Datenübertragung nicht nur vom Clientprogramm unabhängig und reduziert so den Entwicklungsaufwand, sondern ermöglicht auch den direkten Aufruf durch jedes Programm, das Binärcode unterstützt, wie beispielsweise Excel-Tabellen. Bei einem Server-Client-Ansatz ist der Code leichter zu warten. Selbst wenn das serverseitige Programm aktualisiert werden muss, bleibt das Clientprogramm unverändert, solange die Schnittstelle gleich bleibt. Dies reduziert den nachfolgenden Aufwand erheblich. Wie der Server muss sich auch der Client nur mit der Serverschnittstelle befassen und nicht mit der Implementierung des Datenaustauschs. Das heißt, wenn sich die Funktion eines Endes des COM-Servers oder -Clients ändert, muss das andere Ende nicht angepasst werden, solange die Schnittstelle unverändert bleibt. Die in diesem Artikel vorgestellte Technologie wurde bereits erfolgreich in realen Projekten wie einer Wasserinjektionsstation im Shengli-Ölfeld eingesetzt.