-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers: modbus_rtu: add initial support (v2) #20386
base: master
Are you sure you want to change the base?
Conversation
d6f6c6f
to
3541174
Compare
This adds initial support for Modbus RTU in master and slave mode. It supports the following functions: * MODBUS_FC_READ_COILS * MODBUS_FC_READ_DISCRETE_INPUTS * MODBUS_FC_READ_HOLDING_REGISTERS * MODBUS_FC_READ_INPUT_REGISTERS * MODBUS_FC_WRITE_SINGLE_COIL * MODBUS_FC_WRITE_SINGLE_HOLDING_REGISTER * MODBUS_FC_WRITE_MULTIPLE_COILS * MODBUS_FC_WRITE_MULTIPLE_HOLDING_REGISTERS Code has been structured to make it extensible in the future, but preparing it for other uses than Modbus RTU is not part of this commit.
This application will test the Modbus RTU implementation.
This example will demonstrate how to implement a Modbus slave, that interacts with SAUL.
3541174
to
b8a4dfc
Compare
drivers/include/modbus_rtu.h
Outdated
/** | ||
* @brief RTS pin. @p GPIO_UNDEF if not used. | ||
*/ | ||
gpio_t pin_rts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why dont you use ?
/** | |
* @brief RTS pin. @p GPIO_UNDEF if not used. | |
*/ | |
gpio_t pin_rts; | |
gpio_t pin_rts; /**<< RTS pin. @p GPIO_UNDEF if not used.*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update this. I just re-used what was already provided in the first PR :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have addressed this for modbus_rtu_params_t
and modbus_rtu_t
. I did drop the @internal
annotations, which I could not combine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice... I would like to see this in and would provide testing in the near future.
drivers/modbus/Kconfig
Outdated
@@ -0,0 +1,34 @@ | |||
# Copyright (c) 2023-2024 Bas Stottelaar <[email protected]> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are no longer doing dependency modelling with kconfig... This can be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, so I can just remove the Kconfig file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the Kconfig file.
4e6bfe2
to
b6d822f
Compare
drivers/include/modbus_rtu.h
Outdated
const modbus_rtu_params_t* params; /**< device parameters */ | ||
uint32_t timeout; /**< amount of time (usec) to wait for a slave to | ||
begin sending a */ | ||
uint32_t rx_timeout; /**< time between two bytes before timeing out */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint32_t rx_timeout; /**< time between two bytes before timeing out */ | |
uint32_t rx_timeout; /**< timeout between bytes*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved.
drivers/include/modbus_rtu.h
Outdated
modbus_t dev; /**< @ref modbus_t base class */ | ||
const modbus_rtu_params_t* params; /**< device parameters */ | ||
uint32_t timeout; /**< amount of time (usec) to wait for a slave to | ||
begin sending a */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
begin sending a */ | |
begin sending*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved.
88d0828
to
59e2a59
Compare
59e2a59
to
d553305
Compare
I made some additional changes to the implementation.
|
drivers/include/modbus_rtu.h
Outdated
uint32_t timeout; /**< amount of time (usec) to wait for a slave to | ||
begin sending */ | ||
uint32_t rx_timeout; /**< timeout between two bytes */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can u make them a little more descriptive
like "inter_fame_usec_min" and "byte_usec_max"
is that correct?
maybe its is more like frame_space_rx (1,5 chars ) , frame_space_ tx (3,5 chars)
please check me on this
there also isn't a difference in master vs slave am i wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved timeout
to the modbus_rtu_params_t
, and renamed rx_timeout
to byte_timeout
.
rx_timeout
is calculated during initialization, to save some computation in hot path (debatable). I could remove it: it is based on baud rate, which was not stored before (it is via params).
Fields inside modbus_rtu_t
are now marked as internal (with a comment). Also improved comments.
I think it is OK now.
@derMihai since you worked with modbus would you please take a short look |
Contribution description
This PR is a reboot of #13913 that got stale. I cloned it, rebased it onto master, adapted it to latest standards (hopefully) and proposed #19819. But after some actual testing, I decided that both PRs were not really useful, and made a lot of assumptions. For more flexibility, I rewrote most of the code. Some notable improvements:
Contrary to the original PR, I removed a lot of
#ifdefs
that limited which Modbus functions would be supported. It was hard to manage IMHO.I also extended the test application to test using a single or multiple devices. An example application that provides a Modbus slave implementation is also provided.
Testing procedure
A test application is provided in
tests/drivers/modbus
.There are multiple ways to test this. The easiest is to connect RX/TX of one UART to TX/RX of another UART. That way, Modbus runs over RS-232, which should be sufficient to test majority of the implementation. If you take a board with two additional UARTs, then you can use the loopback mode, which will perform additional assertions by comparing data directly.
Alternatively, connect two or more boards via a RS-485 network. Let one run as master and the other as slaves.
See here for more information.
Issues/PRs references
Fixes #13869.