Hallo,
ich neötige Hilfe bei der Inbetriebnahme des freeModbus
(https://github.com/cwalter-at/freemodbus)
Das Zielsystem ist ein Stm32F469, FreeRTOS wird nich verwendet.
LWIP mit dem tcp_server sowie auch tcp_client Beispielen funktionieren
super.
(tcp-echoserver und tcp-echoclient).
Nun zu dem Modbus Stack (freeModbus s.o.).
Das Modbusinterface machr praktisch auch was es soll (Poll).
ICh schicke eine Nachricht hin und es kommt eine entsprechende Antwort.
Was ich aber gern machen würde ist, dass ich von meinem STM-Controller
eine Nachricht über den Modbus senden und dann die Rückantwort
auswerten.
Hta jemand von euch schon einmal dieses TCP Stack implementiert?
Ich habe das Gefühl das da alls da ist, ich verstehe aber nicht wirklich
was da zu machen ist...
Gibt es eine Funktion mit der ich einen Client Ansprechen (z.B. lese
Messdaten aus Client) kann?
In der Funktion eMBPoll() gibt es die Funktion
peMBFrameSendCur(ucMBAddress, ucMBFrame, usLength).
Die ist prakisch für das Senden verantwortlich. Jedoch geht das nicht
die Funktion einzeln ausführen zu lassen. Da zu muss man offensichtlich
den Zustandsautomat der eMBPoll() verwenden...
Der ist aber nur dafür gemacht das es eine Nachricht empfängt, prüft und
eine Antwort sendet.
Hat jemand von euch vielleicht eine Idee dazu bzw. das selbst schon
einmal gemacht?
Muss ich mir eine äquvivalente Funktion schreiben welche auch so einen
Zustandsautomaten hat...?
Grüße von Günther
Hier nochmal die eMBPoll Funktion:
1 | eMBErrorCode eMBPoll( void )
|
2 | {
|
3 | static UCHAR *ucMBFrame;
|
4 | static UCHAR ucRcvAddress;
|
5 | static UCHAR ucFunctionCode;
|
6 | static USHORT usLength;
|
7 | static eMBException eException;
|
8 |
|
9 | int i;
|
10 | eMBErrorCode eStatus = MB_ENOERR;
|
11 | eMBEventType eEvent;
|
12 |
|
13 | /* Check if the protocol stack is ready. */
|
14 |
|
15 | if( eMBState != STATE_ENABLED )
|
16 | {
|
17 | return MB_EILLSTATE;
|
18 | }
|
19 |
|
20 | /* Check if there is a event available. If not return control to caller.
|
21 | * Otherwise we will handle the event. */
|
22 | if( xMBPortEventGet( &eEvent ) == TRUE )
|
23 | {
|
24 |
|
25 | switch ( eEvent )
|
26 | {
|
27 | case EV_READY:
|
28 | break;
|
29 |
|
30 | case EV_FRAME_RECEIVED:
|
31 | eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
|
32 |
|
33 | if( eStatus == MB_ENOERR )
|
34 | {
|
35 | /* Check if the frame is for us. If not ignore the frame. */
|
36 | if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
|
37 | {
|
38 | ( void )xMBPortEventPost( EV_EXECUTE );
|
39 | }
|
40 | }
|
41 | break;
|
42 |
|
43 | case EV_EXECUTE:
|
44 | ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
|
45 | eException = MB_EX_ILLEGAL_FUNCTION;
|
46 | for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
|
47 | {
|
48 | /* No more function handlers registered. Abort. */
|
49 | if( xFuncHandlers[i].ucFunctionCode == 0 )
|
50 | {
|
51 | break;
|
52 | }
|
53 | else if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
|
54 | {
|
55 | eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
|
56 | break;
|
57 | }
|
58 | }
|
59 |
|
60 | /* If the request was not sent to the broadcast address we
|
61 | * return a reply. */
|
62 | if( ucRcvAddress != MB_ADDRESS_BROADCAST )
|
63 | {
|
64 | if( eException != MB_EX_NONE )
|
65 | {
|
66 | /* An exception occured. Build an error frame. */
|
67 | usLength = 0;
|
68 | ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
|
69 | ucMBFrame[usLength++] = eException;
|
70 | }
|
71 | if( ( eMBCurrentMode == MB_ASCII ) && MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS )
|
72 | {
|
73 | vMBPortTimersDelay( MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS );
|
74 | }
|
75 |
|
76 | eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
|
77 |
|
78 |
|
79 | }
|
80 | break;
|
81 |
|
82 | case EV_FRAME_SENT:
|
83 | break;
|
84 | }
|
85 | }
|
86 | return MB_ENOERR;
|
87 | }
|