Modbus RTU Problem

  • 1
  • 2
  • 3
  • Page 1 of 3
Hans K.
 
Avatar
 
Subject:

Modbus RTU Problem

 · 
Posted: 10.11.2011 - 10:48  ·  #1
Hallo

Ich baue eine Applikation, die u.a. einen ModbusRTU Slave implementiert. Dafür verwende ich die entsprechenden Library-Funktionen, wie in der Demo-App vorgegeben. Das Gerüst sieht etwa so aus:
Code

Device = mega644p, VCC=3.3;
Import SysTick, SerPort;
Import I2Cport;
Import ModBus;
From System Import Processes;
Define
   ProcClock      = 8000000;       // Hertz
   SysTick        = 10, Timer0;    // 10 msec, use Timer0 (Timer2 used for RTU)
   StackSize      = $0150, iData;
   FrameSize      = $0150, iData;

   // RS-485 / ModBus
   SerPort        = 19200, Databit8, parEven, Stop1;    {Baud, StopBits|Parity}
   RxBuffer       = 255, iData;
   TxBuffer       = 100, iData;
   SerCtrl        = PortD, 4, positive; {control line for RS485 driver}

   I2Cport     = PortC;
   I2Cdat      = 1;
   I2Cclk      = 0;

   // Modbus RTU Slave
   Scheduler      = iData;
   ModBus         = SerPort, 20, iData, 40;   
   ModBusMode     = RTU, Timer2;

Uses ModBusServRTU;

Implementation

var
{$MODBUS MBnetaudioRTU}
   ModBuff[@ModDPR]: record
      // Tag       Type            // Register (Word)
      Meter1:      mb_InpW;        // [00]
      PagingStn:   mb_InpW;        // [01]
      SlaveId:     mb_RdWrW;       // [02]
      Argument:    mb_RdWrW;       // [03]
      NetAudioCmd: mb_RdWrW;       // [04]
      RxBundle1:   mb_RdWrW;       // [05]
      TxBundle1:   mb_RdWrW;       // [06]
      Rx1Submap1:  mb_RdWrW;       // [07]
      Tx1Submap1:  mb_RdWrW;       // [08]
   end;

begin
   Start_Processes;
   mb_SetModBusDevID (1);  // (LastSlaveId);
   // initialize user's event handlers and enable them
   mb_SetBeforeRegisterRead (@mb_BeforeRegisterRead);
   mb_SetAfterRegisterWrite (@mb_AfterRegisterWrite);

loop
   // Do something useful
endloop;

Wenn ich nun ein oder mehrere Register schreibe (Function code 06 oder 16), so funktioniert das meistens. Aber je nachdem was die Prozedur mb_AfterRegisterWrite tut, startet die Applikation neu oder hängt. Ein Lesezugriff auf die Register funktioniert immer. In gewissen Fällen kommt der Neustart auch nach mehrmaligem Schreiben des gleichen Registers und anschliessendem Lesezugriff auf dasselbe Register.
Sieht irgendwie nach überlaufendem Stack aus. Ist das Phänomen bekannt? Hat jemand einen Tip, was ich noch versuchen könnte? Der gleiche Fall tritt übrigens auch mit ModbusASCII auf.

Gruss
Hans
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Modbus RTU Problem

 · 
Posted: 10.11.2011 - 18:14  ·  #2
AVRA ??
Hans K.
 
Avatar
 
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 12:22  ·  #3
Hallo Rolf

Heisst das, der Modbus-Treiber ist nicht von E-Lab?
Ich habe jetzt die Applikation soweit reduziert, dass nur der ModbusRTU-Code aktiv ist. Die Prozedur mb_AfterRegisterWrite macht nichts anderes, als eine Meldung über die zweite serielle schnitstelle auszugeben. Das Problem tritt genauso auf. Und zwar reproduzierbar nach einem Lesen (FC 3)eines Registers und anschliessendem Schreiben (FC6) desselben Registers. Er erfolgt ein Neustart, danach wird mb_AfterRegisterWrite ausgeführt. Ich bin wirklich dankbar für jede Hilfe.

Gruss
Hans
mc-electronic
Benutzer
Avatar
Gender: n/a
Location: Sauerland NRW
Posts: 372
Registered: 03 / 2008
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 12:54  ·  #4
Hallo Hans,

erhöhen Sie doch einmal den Frame deutlich, wenn ich sehe, was da alles importiert und benutzt wird, würde ich das als erstes vermuten. Nur um das auszuschließen..

Gruß, Michael
Hans K.
 
Avatar
 
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 13:41  ·  #5
Hallo Michael

Stack und Frame um je 500 Bytes erhöht bringt nichts. Daran liegt es wohl nicht.

Gruss

Hans
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 14:06  ·  #6
Hallo Hans,

der ModBus Treiber wurde von AVRA geschrieben. Ich habe dabei nur wesentliche Teile in Assembler umgesetzt um Speed zu erhöhen und Code size zu erniedrigen sowie den Einbau in das System. Alle Tests hat AVRA erledigt, da das ohne einen Modbus Slave nur sehr schwer möglich ist.

rolf
Hans K.
 
Avatar
 
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 14:35  ·  #7
Danke Rolf.

@Avra:
Please help with your ModBusRTU driver. I have a minimal application, as shown above, which implements a ModBusRTU slave on an ATmega644p. Now there is the situation that the application restarts when the master first reads from a register (FC 3), then writes to the same register (FC 6). This behaviour is reproducable. The procedure mb_AfterRegisterWrite in this test implementation just writes a short message to the second serial port.

The behaviour tastes like a memory leak, but my application does not use any dynamic memory allocation. Any idea where to look?

Regards,
Hans
Avra
Schreiberling
Avatar
Gender:
Location: Belgrade, Serbia
Age: 53
Homepage: rs.linkedin.com/in…
Posts: 653
Registered: 07 / 2002
Subject:

Re: Modbus RTU Problem

 · 
Posted: 14.11.2011 - 16:06  ·  #8
Hello Hans,

I had a hard drive failure and unfortunately I have no working AvrCo installation at the moment. I am also in the process of moving my WinXP development machine to Win7, so this will also take additional time. Therefore I can not say exactly when I will be able to investigate the problem you are facing, sorry. But I will do my best.

That being said there are things we can try. Provided example is not enough. You should PM me a minimal complete project (PAS, PMBL, PPRO) with everything else stripped off and with exact steps I need to do to replicate the problem. I need to know if you use AvrCo Modbus Tester application or something else? Does the problem show only when you have no pause between read and write or there can be a pause? Do you have a problem even when you don't use callback procedures at all? Strings in callbacks could easily eat stack/frame, especially if you like adding all substrings in a single pascal line. Do you use multitasking? Maybe local stack/frame size need to be increased? Have you used wizard for a skeleton application or you used copy/paste? Do original MODBUS RTU and ASCII demos work or you have the same problem? It would be also good if you have Delphi and you can test MODBUS samples from AvrCo site and report if they work with your board (little adaptation is needed since they are made for MEGA128). Even if you don't have Delphi then I think executables are included in the archive so they could be tested instead. This is the link: http://e-lab.de/downloads/dive…asters.zip. If you have an urgent project and can't wait for my testing, then you can split that problematic tag into two tags. One just for read and one just for write, which will be a pseudo getter and setter of the same variable. That should work as a workaround. Dynamic memory allocation has not been used in MODBUS RTU and ASCII libraries. I also don't see that your var section is in {$IDATA}. How can that be, are you sure that is the case? You can try to put a big dummy array before and after a ModBuff record. If that makes behavior more better but still happens then probably stack gets corrupted and big array just give you more time before corruption.
  • 1
  • 2
  • 3
  • Page 1 of 3
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   132   146 · Page-Gen-Time: 0.019357s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI