Forum: Compiler & IDEs Methoden in FreeModbus


von Owen S. (senmeis)


Lesenswert?

Hallo,

ich beschäftige mich zur Zeit mit dem FreeModbus-Projekt für den 
Atmega128. Hier Fragen dazu:

1.  Es gibt 4 Methoden
1
eMBErrorCode  eMBRegInputCB (UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs) 
2
eMBErrorCode  eMBRegHoldingCB (UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode) 
3
eMBErrorCode  eMBRegCoilsCB (UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode) 
4
eMBErrorCode  eMBRegDiscreteCB (UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete)

und 10 Makro für Modbus Funktionen
1
#define  MB_FUNC_OTHER_REP_SLAVEID_ENABLED   ( 1 ) 
2
#define  MB_FUNC_READ_INPUT_ENABLED   ( 1 ) 
3
#define  MB_FUNC_READ_HOLDING_ENABLED   ( 1 ) 
4
#define  MB_FUNC_WRITE_HOLDING_ENABLED   ( 1 ) 
5
#define  MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED   ( 1 ) 
6
#define  MB_FUNC_READ_COILS_ENABLED   ( 1 ) 
7
#define  MB_FUNC_WRITE_COIL_ENABLED   ( 1 ) 
8
#define  MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED   ( 1 ) 
9
#define  MB_FUNC_READ_DISCRETE_INPUTS_ENABLED   ( 1 ) 
10
#define  MB_FUNC_READWRITE_HOLDING_ENABLED   ( 1 )
Welche Beziehungen gibt es dazwischen? Ist es so, dass eine Methode von 
meheren Modbus-Funktionen verwendet wird?

2.  Im File AVR/demo.c befinden sich drei Methoden
1
eMBErrorCode
2
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
3
                 eMBRegisterMode eMode )
4
{
5
    return MB_ENOREG;
6
}
7
8
9
eMBErrorCode
10
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
11
               eMBRegisterMode eMode )
12
{
13
    return MB_ENOREG;
14
}
15
16
eMBErrorCode
17
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
18
{
19
    return MB_ENOREG;
20
}

Warum sind diese drei inhaltlich leer?

MfG
Senmeis

von Stephan (Gast)


Lesenswert?

Hi
mit den Macros bestimmst du deinen Befehlsumfang von Modbus und 
"aktivierst" auch deren Aufruf-Funktionen.

was dies macht:
1
#define  MB_FUNC_OTHER_REP_SLAVEID_ENABLED   ( 1 )

weiß ich leider nicht, steht aber bestimmt in der Doku.
Könnte FC 0x08 sein, bin aber nicht sicher.

Die Aufruf-Funktionen sind deine "Register-Händler" und müssen von dir 
mit Code gefüllt werden!
Hier wird der Modbus halt mit leben gefüllt, wenn man das so sagen kann.

z.B.: Nehme den Wert des zu beschreibende Register und setze die 
Ausgänge oder so....

mfg
Stephan

von Owen S. (senmeis)


Lesenswert?

Mit
1
#define  MB_FUNC_OTHER_REP_SLAVEID_ENABLED   ( 1 )

wird FC 0x11 gemeint.

Soweit ich verstehe sind alle Modbus-Funktionen bereits standardiert. 
Warum wieder mit Code erfüllen? Diese 10 Methoden für Modbus-Funktionen 
werden auch implementiert. Soweit ich sehe werden diese 4 Methoden 
jeweils von den 10 Methoden aufgerufen, da diese 4 Methoden sich auf der 
niedrigeren Ebene befinden.

MfG
Senmeis

von Stephan (Gast)


Lesenswert?

Hi

>Diese 10 Methoden für Modbus-Funktionen
>werden auch implementiert. Soweit ich sehe werden diese 4 Methoden
>jeweils von den 10 Methoden aufgerufen, da diese 4 Methoden sich auf der
>niedrigeren Ebene befinden.

ja, genau! :-)
Das ist deine Schnittstelle, von deinem Programm zu Modbus.

In der Demo zum AVR ist ja nur eine Funktion mit Code gefüllt, der nur 
das lesen von InputReg erlaubt. (siehe oben 1. Funktion)
Des weiteren bezieht sich die Demo auf ein Array 
"usRegInputBuf[REG_INPUT_NREGS]" mit der Anzahl von "REG_INPUT_NREGS" 
Registern. Das alles ist ja nur eine Demo und in deinem Programm kann 
das alles sich ändern.

Wenn du Register auch beschreiben willst musst du auch die entsprechende 
Funktion mit Code befüllen.

Dafür brauchst du wieder ein Array und die Funktion:
1
eMBErrorCode  eMBRegHoldingCB (UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)

als unvollständiges Beispiel:
1
{
2
  eMBErrorCode    eStatus = MB_ENOERR;
3
4
  switch(eMode){
5
  // Register lesen
6
  case MB_REG_READ:
7
       // lese von "pucRegBuffer" mit der Anzahl von "usNRegs" Registern
8
       // und schreibe diese ab Registeradresse "usAddress" in mein
9
       // "RegHoldingArray"
10
       // fertig!
11
       break;
12
  // Register schreiben     
13
  case MB_REG_WRITE:
14
       // lese von meinem "RegHoldingArray" mit der Anzahl von "usNRegs" 
15
       // Registern und schreibe diese in den Buffer "pucRegBuffer"
16
       // fertig!
17
       break;
18
  }
19
20
return eStatus;
21
}

ja, so könnte das aussehen. Wenn man es geschickt anstellt kann man das 
mit dem neuen Arrays auch umgehen. (Stichwort: 
Registereigenschaften(R/W))

mfg
Stephan

von Owen S. (senmeis)


Lesenswert?

Vielen Dank. D.h. diese 4 Methoden sind applikationspezifisch!

Noch eine Frage zur main() Methode:
1
int main( void )
2
{
3
    const UCHAR     ucSlaveID[] = { 0xAA, 0xBB, 0xCC };
4
    eMBErrorCode    eStatus;
5
6
    eStatus = eMBInit( MB_RTU, 0x0A, 0, 38400, MB_PAR_EVEN );
7
8
    eStatus = eMBSetSlaveID( 0x34, TRUE, ucSlaveID, 3 );
9
    sei(  );
10
11
    /* Enable the Modbus Protocol Stack. */
12
    eStatus = eMBEnable(  );
13
14
    for( ;; )
15
    {
16
        ( void )eMBPoll(  );
17
18
        /* Here we simply count the number of poll cycles. */
19
        usRegInputBuf[0]++;
20
    }
21
}
Was macht „eMBSetSlaveID( 0x34, TRUE, ucSlaveID, 3 )”?

Nach der Anleitung: "Configure the slave ID of the device"

Ich glaube, es macht keinen Sinn, den Slave ID zu ändern, da der Master 
nicht fähig ist, den Slave ID zu konfigurieren.

Wo habe ich falsch verstanden?

MfG
Senmeis

von Stephan (Gast)


Lesenswert?

Hi
die Funktion:
1
eMBSetSlaveID( 0x34, TRUE, ucSlaveID, 3 )

setzt die Infos für das MB Command (0x11):
1
#define  MB_FUNC_OTHER_REP_SLAVEID_ENABLED   ( 1 )

Die Daten sind fest und werden nur einmal eingestellt.
Wenn du diese Sachen nicht brauchst, dann schmeiß sie raus, ich hab 
diese Funktion noch nicht in der freien Wildbahn genutzt. Es reicht 
normalerweise die Slave-Adresse und die Seriennummer im Gerät.
Was du machen könntest ist, dass du dort den Namen des Gerätes 
hinterlegst oder so.

mfg
Stephan

von Owen S. (senmeis)


Lesenswert?

Vielen Dank.

Der Modbus-Slave soll den ID von 0x0A haben. Warum wieder mit 0x34 
konfiguriert? Hat das Array "ucSlaveID[]" mit dem Slave-ID zu tun? Das 
ist bisschen irreführend.

MfG
Senmeis

von Stephan (Gast)


Lesenswert?

Hi

hat was länger gedauert, aber bin wieder da. ;-)

>Der Modbus-Slave soll den ID von 0x0A haben.
Ok, warum nicht. Ist dir überlassen.

>Warum wieder mit 0x34 konfiguriert?
Das war aus dem Beispiel. Was da drin steht ist egal.

>Hat das Array "ucSlaveID[]" mit dem Slave-ID zu tun? Das
>ist bisschen irreführend.
Du hast noch die Möglichkeit weiter Infos dran zuhängen und das 
geschieht wenn du den 2. Parameter auf True setzt und das Array mit der 
entsprechenden Länge übergibst.

hier mal ein Beispiel: (ungetested!)
1
u08* ucSlaveID="ich bin der Master!";
2
eMBSetSlaveID( 0x07, TRUE, ucSlaveID, 19 )

Als Antwort erhälst du dann:
ID: 0x07
Zusatz Info: ich bin der Master!

mfg
Stephan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.