Giter Club home page Giter Club logo

freemodbus's People

Contributors

cwalter-at avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

freemodbus's Issues

Wrong bit name in AVR Example

There is wrong bit name in file portserial.c in function void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) :

if( xTxEnable )
    {
        UCSRB |= _BV( TXEN ) | _BV( UDRE );
#ifdef RTS_ENABLE
        RTS_HIGH;
#endif
    }
    else
    {
        UCSRB &= ~( _BV( UDRE ) );
    }

Must be:

if( xTxEnable )
    {
        UCSRB |= _BV( TXEN ) | _BV( UDRIE );
#ifdef RTS_ENABLE
        RTS_HIGH;
#endif
    }
    else
    {
        UCSRB &= ~( _BV( UDRIE ) );
    }

May be UDRIE must be defined like #define UDRIE UDRIE0 //or UDRIE1 in file port.h

LWIP rx pool allocation fails with modbus

Hello! I'm trying to run modbus tcp on lwip stack (NUCLEO-H755ZI-Q), so the problem:

  • adding modbus ruine something - the board is not pinged, I can't figure what is the reason. Further investigations revealed that the problem is maybe connected with lwip rx pool allocation, in debug I've counted how many times LWIP_MEMPOOL_ALLOC and LWIP_MEMPOOL_FREE were called, so the sequence of allocations and frees is: (A - allocation, F - free)
    A-A-A-A-A-A-A-A-A (9 pools) - F (8 pools) - A (9) - F (8) - A-A-A-A (12) - F (11) - A (12) - F (11) - A (12) - A (Fail)
    This behavior pattern repeats, always maximum 12 pools are allocated, an attempt to allocate 13th fails.
    Without modbus the sequence looks like:
    A-A-A-A-A (5) - F (4) - A (5) - F (4) - A (5) - F(4)
    and continue to maintain 4 allocate pools.
    Somehow inserting modbus creates conditions for races of memory allocation and free functions.

Modbus init sequence:

 if(eMBTCPInit(0) != MB_ENOERR)
    return;
    
  if(eMBSetSlaveID( 1, TRUE, Vendor, sizeof(Vendor)) != MB_ENOERR)
    return;
  
  if(eMBEnable() != MB_ENOERR)
    return;
  
  while(1) 
  {   
    eMBPoll();
    MX_LWIP_Process();    
  }  

License of demo/BARE

Please change license of demo/BARE/ to same as the main code. Currently one can not use freemodbus under the bsd license due to documentation on how to integrate the project in your own code being a bit incomplete without this code. To make a working integration one pretty much must start from demo/BARE, pushing the gpl license requirements onto the custom application.
Alternatively extend the documentation so that it includes the needed pieces without having to refer to demo/BARE. Today the documentation assumes one starts from demo/BARE and do not cover all of the required interactions with the library when porting it to a new target.

RTU and TCP outputs only show the least significant byte of the registers

Hi, I am running this software on an STM32F407 running as a modbus slave device. Everything works fine except when i poll data from the device and read the holding registers via either RTU or TCP I only receive the least significant byte of the register even though the modbus master specifies to read INT16 data. Any idea why it is not transmitting the upper byte of the register? I inherited this project from a previous developer so I do not want to start modifying it until I know if there is a simple solution or not.

In mbfuncholding.c, line 185 is there a bug?

freemodbus/modbus/functions/mbfuncholding.c;
line 185, usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
like should be: usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );

bug in file bfuncinput.c ??

in file mbfuncinput.c

    usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
    usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );

    usRegAddress++;   ---> Why incremente the addr ???

eMBPoll always returns success

It seems more appropriate that it return eStatus, rather than always returning success. This would have a chance for the caller to track that things have gone wrong.

Choose between RTU and TCP at runtime

Is it possible with this library to choose between RTU and TCP at runtime ?

Can we choose from a variable if Modbus RTU or Modbus TCP needed to be activated ?

how can we have dummy values for Input registers in modbus slave ?

Hi,
In the modbus slave service, when I read INPUT registers, it always return "0" value for any register. But I want to have some dummy values for these registers by default when slave service come-up.

How can we do this using this library ? Really appreciate for all your help.

usRcvBufferPos reset only in STATE_RX_IDLE in mbrtu.c

Firstly, thanks to the authors for this nice concise modbus slave ported to multiple devices. I tested it on a MSP430F5529 so made a few changes to the provided MSP430F169 port. I got it working but only after addressing a couple of issues which I think should impact all devices.
The issue I had to fix had to do with the current position of the buffer use to store received bytes (usRcvBufferPos) which only gets reset in STATE_RX_IDLE. If for whatever reason a slave doesn't respond to a request then the start position of the buffer doesn't get reset and is in an unknown state when the next request comes in. Setting it back to zero at the end of receiving the current frame seems to fix the problem though I'm not sure whether it introduces other problems.

eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength ) { ... usRcvBufferPos = 0; return eStatus; }

There's probably a better solution to this. Anybody else encounter this issue?

A global-buffer-overflow bug that can lead demo/LINUXTCP to crash

Hi,
I am running some experiments for AFLNET and it has found a global-buffer-overflow bug in recv when sent this pdus to tcpmodbus

poc:
poc.zip

To reproduce:
Complie the demo/LINUXTCP with ASAN

then use aflnet-replay to send the binary_poc to the port, detail in aflnet

I also captured the pcap file when send those pdus to the tcpmodbus, both pcap and binary in poc.zip

ASAN show this information:

=================================================================
==62032==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000daefa7 at pc 0x00000046d94c bp 0x7f77940fec50 sp 0x7f77940fe418
WRITE of size 36 at 0x000000daefa7 thread T1
    #0 0x46d94b in recv (/home/ubuntu/Documents/freemodbus/demo/LINUXTCP/tcpmodbus+0x46d94b)
    #1 0x4c9d48 in xMBPortTCPPool /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/port/porttcp.c:224:25
    #2 0x4c8ca4 in xMBPortEventGet /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/port/portevent.c:69:17
    #3 0x4cb3df in eMBPoll /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/../../modbus/mb.c:351:9
    #4 0x4c7dd4 in pvPollingThread /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/demo.c:195:17
    #5 0x7f7797a97608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477:8
    #6 0x7f7797842132 in clone /build/glibc-SzIz7B/glibc-2.31/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:95

0x000000daefa7 is located 0 bytes to the right of global variable 'aucTCPBuf' defined in 'port/porttcp.c:80:17' (0xdaeea0) of size 263
SUMMARY: AddressSanitizer: global-buffer-overflow (/home/ubuntu/Documents/freemodbus/demo/LINUXTCP/tcpmodbus+0x46d94b) in recv
Shadow bytes around the buggy address:
  0x0000801adda0: 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
  0x0000801addb0: f9 f9 f9 f9 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9
  0x0000801addc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000801addd0: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000801adde0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000801addf0: 00 00 00 00[07]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x0000801ade00: 02 f9 f9 f9 f9 f9 f9 f9 02 f9 f9 f9 f9 f9 f9 f9
  0x0000801ade10: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
  0x0000801ade20: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
  0x0000801ade30: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 01 f9 f9 f9
  0x0000801ade40: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
Thread T1 created by T0 here:
    #0 0x480dfa in pthread_create (/home/ubuntu/Documents/freemodbus/demo/LINUXTCP/tcpmodbus+0x480dfa)
    #1 0x4c6264 in bCreatePollingThread /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/demo.c:169:13
    #2 0x4c6264 in main /home/ubuntu/Documents/freemodbus/demo/LINUXTCP/demo.c:92:21
    #3 0x7f7797747082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

==62032==ABORTING

assertion error

I have ported freemodbus on STM32F103, but encountered an assertion error during debugging. I don't know how to solve it
image

The freemodbus stack does not support bulk payload of write request with function code(16) 0x10

I have a slave device which supports writing 150 registers at once which is around 300 bytes. I have framed a modbus request which is greater than 300 bytes including slave ID, function code, register start address, number of registers, number of bytes, data and CRC and sent it to the modbus slave device using standard modbus master template code. In standard documentations it is mentioned that the modbus can support writing multiple registers of 123 registers at once. Is there any way to that can support the bulk and huge payload of writing multiple registers?

RTU only responds to 35 messages

I've ported the code to be used on a atXMega32D4 and got it working with several Master applications.

The common thing that is not working is that after 35 messages, the USART completely stops receiving any data into the DATA register.

Did anyone ever encounter anything like this? Do I need to clear the DATA register somewhere again?

MODBUS broadcast request (slave ID: 0) leaves system in illegal state with the error "receive buffer initialization fail."

I tried to send the modbus broadcast request i.e; slave id = 00, using the sample code of esp-idf modbus. the master sends the request and enters into an illegal state as shown in the figure and does not allow any further requests until reboot. As per the MODBUS protocol standard, the slave only receives request and processes it but doesn't respond since it is the broadcast request. But the freemodbus is making the master enter into illegal state. What is the exact problem for this error of modbus master entering into an unknown state? I suspect that the master is checking the port for any packet received from slave end. Since there is no packet on the port, it gives this error "receive buffer initialization fail." But the master goes into unknown state even without connecting to any slave. The log images of both modbus master and slave are attached for reference. Let me know the issue and ways to fix it.

MODBUS Master logs with broadcast request:

image

MODBUS Slave logs:

image

Thanks in advance!

Modbus ADU msg is 256 bytes

The eMBRTUReceive asserts on 256 bytes received. A bit sensetiv to selfdestruct on a bit to musch on the line? The usRcvBufferPos is both a "indexer" and a "length checker".

eMBSetSlaveID without "Byte Count"

PI–MBUS–300 Data and Control Functions 49

I checked the utility mbpoll: mbpoll -m rtu -a 0x0A -u -b 38400 -d 8 -s 2 -P none /dev/ttyUSB0 -v
and get this result:

[0A][11][C7][1C]
Waiting for a confirmation...
ERROR Connection timed out: select
Report slave ID failed(-1): Connection timed out
<0A><11><34><FF><AA><BB><CC><61><14>

I think this code will be more correct or not (why)?:

eMBErrorCode
eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
               UCHAR const *pucAdditional, USHORT usAdditionalLen )
{
    eMBErrorCode    eStatus = MB_ENOERR;

    /* the first byte in the buffer is reserved for the Byte Count
     * the second byte in the buffer is reserved for the parameter ucSlaveID
     * the third byte in the buffer is reserver for running flag.
     * The rest of the buffer is available for additional data. */
    if( usAdditionalLen + 3 <= MB_FUNC_OTHER_REP_SLAVEID_BUF )
    {
        usMBSlaveIDLen = 0;
        ucMBSlaveID[usMBSlaveIDLen++] = 2 + usAdditionalLen;
        ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;
        ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 );
        if( usAdditionalLen > 0 )
        {
            memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional,
                    ( size_t )usAdditionalLen );
            usMBSlaveIDLen += usAdditionalLen;
        }
    }
    else
    {
        eStatus = MB_ENORES;
    }
    return eStatus;
}

with this code, I get the correct response

[0A][11][C7][1C]
Waiting for a confirmation...
<0A><11><05><34><FF><AA><BB><CC><12><75>
Length: 5
Id    : 0x34
Status: On
Data  : \AA\BB\CC

When Write MULTIPLE_COILS

if i send : 01 0F 00 00 00 03 01 0f CF 53
i means wirte three coils to bit 1,but it returns four bits to bit 1,
if we should just get three bits in 0x0f ?

freemodbus design question

I'm wondering if someone can tell me what the rationale is behind the EV_EXECUTE event in eMBPoll?

It is only invoked if the handler for EV_FRAME_RECEIVED posts EV_EXECUTE, but why isn't the code for EV_EXECUTE just included in the handler for EV_FRAME_RECEIVED? It would make the setup simpler and use less resources in a scheduled environment (e.g. FreeRTOS) because 1) there would be less (unnecessary) kernel calls, and 2) in many cases you would have ISR to task events only (i.e. no task to same task event). This is assuming you implement the events using a kernel queue mechanism.

Some of the above goes for the EV_FRAME_SENT event also, which doesn't do anything.

Unable to Read and Write registers for Linux.

I am using this API as a modbus master for Linux platform. Demo.c doesn't include reading and writing of register also it isn't sending any data frame. Can you please help me it.

A bug that can lead freemodbus server to crash

Hi,
I found this bug which leads demo/LINUXTCP to crash while conducting fuzzing experiment.

The log information of message which lead server to crash:
modbusbug2.txt

The ASAN information:

=================================================================
==9863==ERROR: AddressSanitizer: SEGV on unknown address 0x000009026928 (pc 0x0000004c4c97 bp 0x7f2c32efede0 sp 0x7f2c32efed20 T1)
==9863==The signal is caused by a READ memory access.
    #0 0x4c4c97 in xMBPortTCPPool /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/port/porttcp.c:205:13
    #1 0x4c4667 in xMBPortEventGet /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/port/portevent.c:69:17
    #2 0x4c6084 in eMBPoll /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/../../modbus/mb.c:351:9
    #3 0x4c416f in pvPollingThread /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/demo.c:215:17
    #4 0x7f2c36853608 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8608)
    #5 0x7f2c365fe352 in clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f352)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/port/porttcp.c:205:13 in xMBPortTCPPool
Thread T1 created by T0 here:
    #0 0x47e85a in pthread_create (/home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/tcpmodbus+0x47e85a)
    #1 0x4c39db in bCreatePollingThread /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/demo.c:189:13
    #2 0x4c3502 in main /home/linuxbrew/pin-3.28-98749-g6643ecee5-gcc-linux/source/tools/BinPRE/src/freemodbus/demo/LINUXTCP/demo.c:126:21
    #3 0x7f2c36503082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)

==9863==ABORTING

BARE demo portevent.c variables have a lack of volatile qualifier. No event received from a bus with optimization enabled.

Demo portevent.c variables are optimized-out by current compilers. No events received from a bus.
Here, demo/BARE/port/portevent.c:

/* ----------------------- Variables ----------------------------------------*/
static eMBEventType eQueuedEvent;
static BOOL     xEventInQueue;

Both variables MUST be declared with volatile qualifier:

/* ----------------------- Variables ----------------------------------------*/
static volatile eMBEventType eQueuedEvent;
static volatile BOOL     xEventInQueue;

This is because both variables are changing in an interrupts, unexpectedly for the compiler.
When I compiled my RTU port using BARE demo template, I discovered it works without an optimization and doesn't with high level.
The single failure point was portevent.c with variable definition. It is obvious that these variables need to be volatile to be processed correctly in MODBUS poll function.

AvoidTimeout

AvoidTimeout中的last和cur都是函数里面临时变量,该如何起到作用了?

queston about eMBFuncReadInputRegister

at line 71 of mbfuncinput.c there is an increment of usRegAddress variable
before calling at line 96 the function eMBRegInputCB().
i think, the function eMBRegInputCB() will read the next register address of the desired.

George

freemodbus on ATmega3209 not working

Hi, Thank you very much for this great stack. I've used it on old Atmega644 with success. Now I'm trying to run it on new devices from microchip. I'm struggling to get running on ATmega3209. I've changed all port related files (port.h, porttimer.c and portserial.c). Done all test from porting.docx, everything look good, receiver and transmitter working as expected, interrupt on timer toggle LED, but when trying to test it using mbpull and usb-rs485 converter always got Timeout error.

Code after changes attached.
Any ideas why it's not working??
Atmega3209_Modbus.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.