mirror of
https://github.com/espressif/esp-modbus.git
synced 2025-08-02 20:04:27 +02:00
fix slave tcp skips response from multiple masters
This commit is contained in:
@@ -90,15 +90,15 @@ typedef struct _port_driver port_driver_t;
|
||||
|
||||
#define MB_EVENT_BASE(context) (__extension__( \
|
||||
{ \
|
||||
port_driver_t *pdrv_ctx = MB_GET_DRV_PTR(context); \
|
||||
(pdrv_ctx->loop_name) ? (esp_event_base_t)(pdrv_ctx->loop_name) : "UNK_BASE"; \
|
||||
port_driver_t *drv_obj = MB_GET_DRV_PTR(context); \
|
||||
(drv_obj->loop_name) ? (esp_event_base_t)(drv_obj->loop_name) : "UNK_BASE"; \
|
||||
} \
|
||||
))
|
||||
|
||||
#define MB_ADD_FD(fd, max_fd, pfdset) do { \
|
||||
#define MB_ADD_FD(fd, max_fd, fdset) do { \
|
||||
if (fd) { \
|
||||
(max_fd = (fd > max_fd) ? fd : max_fd); \
|
||||
FD_SET(fd, pfdset); \
|
||||
FD_SET(fd, fdset); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
@@ -106,15 +106,15 @@ typedef struct _port_driver port_driver_t;
|
||||
// Macro for atomic operations
|
||||
#define MB_ATOMIC_LOAD(ctx, addr) (__extension__( \
|
||||
{ \
|
||||
port_driver_t *pdrv_ctx = MB_GET_DRV_PTR(ctx); \
|
||||
(CRITICAL_LOAD(pdrv_ctx->lock, addr)); \
|
||||
port_driver_t *drv_obj = MB_GET_DRV_PTR(ctx); \
|
||||
(CRITICAL_LOAD(drv_obj->lock, addr)); \
|
||||
} \
|
||||
))
|
||||
|
||||
#define MB_ATOMIC_STORE(ctx, addr, val) (__extension__( \
|
||||
{ \
|
||||
port_driver_t *pdrv_ctx = MB_GET_DRV_PTR(ctx); \
|
||||
CRITICAL_STORE(pdrv_ctx->lock, addr, val); \
|
||||
port_driver_t *drv_obj = MB_GET_DRV_PTR(ctx); \
|
||||
CRITICAL_STORE(drv_obj->lock, addr, val); \
|
||||
} \
|
||||
))
|
||||
|
||||
@@ -122,11 +122,11 @@ typedef struct _port_driver port_driver_t;
|
||||
// So, the eventfd value keeps last event and its fd.
|
||||
#define DRIVER_SEND_EVENT(ctx, event, fd) (__extension__( \
|
||||
{ \
|
||||
port_driver_t *pdrv_ctx = MB_GET_DRV_PTR(ctx); \
|
||||
port_driver_t *drv_obj = MB_GET_DRV_PTR(ctx); \
|
||||
mb_event_info_t (event_info##__FUNCTION__##__LINE__); \
|
||||
(event_info##__FUNCTION__##__LINE__).event_id = (int32_t)event; \
|
||||
(event_info##__FUNCTION__##__LINE__).opt_fd = fd; \
|
||||
((write_event((void *)pdrv_ctx, &(event_info##__FUNCTION__##__LINE__)) > 0) \
|
||||
((write_event((void *)drv_obj, &(event_info##__FUNCTION__##__LINE__)) > 0) \
|
||||
? ((event_info##__FUNCTION__##__LINE__)).event_id : UNDEF_FD); \
|
||||
} \
|
||||
))
|
||||
@@ -203,7 +203,7 @@ typedef enum _mb_sync_event {
|
||||
|
||||
typedef enum _mb_status_flags {
|
||||
MB_FLAG_BLANK = 0x0000,
|
||||
MB_FLAG_TRANSACTION_DONE = 0x0001,
|
||||
MB_FLAG_TRANSACTION_READY = 0x0001,
|
||||
MB_FLAG_DISCONNECTED = 0x0002,
|
||||
MB_FLAG_CONNECTED = 0x0004,
|
||||
MB_FLAG_SUSPEND = 0x0008,
|
||||
@@ -263,7 +263,7 @@ typedef struct _port_driver {
|
||||
* @return esp_err_t
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t mb_drv_register(port_driver_t **config);
|
||||
esp_err_t mb_drv_register(port_driver_t **ctx);
|
||||
|
||||
/**
|
||||
* @brief Unregister modbus driver
|
||||
@@ -317,7 +317,7 @@ ssize_t mb_drv_read(void *ctx, int fd, void *data, size_t size);
|
||||
|
||||
int mb_drv_close(void *ctx, int fd);
|
||||
|
||||
int32_t write_event(void *ctx, mb_event_info_t *pevent);
|
||||
int32_t write_event(void *ctx, mb_event_info_t *event);
|
||||
|
||||
const char *driver_event_to_name_r(mb_driver_event_t event);
|
||||
|
||||
@@ -335,7 +335,7 @@ void mb_drv_lock(void *ctx);
|
||||
|
||||
void mb_drv_unlock(void *ctx);
|
||||
|
||||
mb_node_info_t *mb_drv_get_next_node_from_set(void *ctx, int *pfd, fd_set *pfdset);
|
||||
mb_node_info_t *mb_drv_get_next_node_from_set(void *ctx, int *fd_ptr, fd_set *fdset);
|
||||
|
||||
mb_status_flags_t mb_drv_set_status_flag(void *ctx, mb_status_flags_t mask);
|
||||
|
||||
|
@@ -360,6 +360,7 @@ MB_EVENT_HANDLER(mbs_on_ready)
|
||||
pdrv_ctx->listen_sock_fd = listen_sock;
|
||||
// so, all accepted sockets will inherit the keep-alive feature
|
||||
(void)port_keep_alive(pdrv_ctx->listen_sock_fd);
|
||||
(void)mb_drv_set_status_flag(pdrv_ctx, MB_FLAG_TRANSACTION_READY);
|
||||
mb_drv_unlock(ctx);
|
||||
ESP_LOGI(TAG, "%s %s: fd: %d, bind is done", (char *)base, __func__, (int)pevent_info->opt_fd);
|
||||
}
|
||||
@@ -425,13 +426,21 @@ MB_EVENT_HANDLER(mbs_on_recv_data)
|
||||
mb_drv_unlock(pdrv_ctx);
|
||||
}
|
||||
}
|
||||
mb_drv_lock(pdrv_ctx);
|
||||
item = transaction_get_first(port_obj->transaction);
|
||||
if (item)
|
||||
{
|
||||
mb_status_flags_t flags = mb_drv_wait_status_flag(port_obj->pdriver, MB_FLAG_TRANSACTION_READY, TRANSACTION_TICKS);
|
||||
if (transaction_item_get_state(item) == QUEUED)
|
||||
{
|
||||
if (MB_FLAG_TRANSACTION_READY == flags) {
|
||||
(void)mb_drv_clear_status_flag(pdrv_ctx, MB_FLAG_TRANSACTION_READY);
|
||||
} else {
|
||||
// postpone the packet processing
|
||||
DRIVER_SEND_EVENT(ctx, MB_EVENT_RECV_DATA, pnode->index);
|
||||
return;
|
||||
}
|
||||
// send receive event to modbus object to get the new data
|
||||
mb_drv_lock(pdrv_ctx);
|
||||
uint16_t msg_id = 0;
|
||||
uint64_t tick = 0;
|
||||
(void)transaction_item_get_data(item, NULL, &msg_id, NULL);
|
||||
@@ -443,25 +452,18 @@ MB_EVENT_HANDLER(mbs_on_recv_data)
|
||||
pdrv_ctx, pnode->index, pnode->sock_id,
|
||||
pnode->addr_info.ip_addr_str, (unsigned)msg_id);
|
||||
}
|
||||
mb_drv_unlock(pdrv_ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transaction_item_get_state(item) != TRANSMITTED) {
|
||||
// Todo: for test removing expired item
|
||||
// Transaction procesing is ongoing, just delete expired transactions
|
||||
transaction_delete_expired(port_obj->transaction, port_get_timestamp(), 1000 * 1000);
|
||||
}
|
||||
if (MB_FLAG_TRANSACTION_DONE == mb_drv_wait_status_flag(port_obj->pdriver,
|
||||
MB_FLAG_TRANSACTION_DONE,
|
||||
TRANSACTION_TICKS)) {
|
||||
(void)mb_drv_clear_status_flag(pdrv_ctx, MB_FLAG_TRANSACTION_DONE);
|
||||
}
|
||||
// postpone the packet processing
|
||||
DRIVER_SEND_EVENT(ctx, MB_EVENT_RECV_DATA, pnode->index);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "%p, no queued items found", ctx);
|
||||
}
|
||||
mb_drv_unlock(pdrv_ctx);
|
||||
}
|
||||
mb_drv_check_suspend_shutdown(ctx);
|
||||
}
|
||||
@@ -502,6 +504,7 @@ MB_EVENT_HANDLER(mbs_on_send_data)
|
||||
ESP_LOGE(TAG, "%p, " MB_NODE_FMT(", send incorrect frame TID:0x%04" PRIx16 "!= 0x%04" PRIx16 ", %d (bytes), errno %d"),
|
||||
ctx, (int)pnode->index, (int)pnode->sock_id,
|
||||
pnode->addr_info.ip_addr_str, pnode->tid_counter, tid, (int)ret, (unsigned)errno);
|
||||
pnode->tid_counter = tid; // update the TID to the current one
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -511,7 +514,7 @@ MB_EVENT_HANDLER(mbs_on_send_data)
|
||||
}
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("SENT", frame_entry.pbuf, ret, ESP_LOG_DEBUG);
|
||||
}
|
||||
(void)mb_drv_set_status_flag(pdrv_ctx, MB_FLAG_TRANSACTION_DONE);
|
||||
(void)mb_drv_set_status_flag(pdrv_ctx, MB_FLAG_TRANSACTION_READY);
|
||||
pdrv_ctx->event_cbs.mb_sync_event_cb(pdrv_ctx->event_cbs.port_arg, MB_SYNC_EVENT_SEND_OK);
|
||||
mb_drv_lock(pdrv_ctx);
|
||||
transaction_set_state(port_obj->transaction, tid, TRANSMITTED);
|
||||
|
Reference in New Issue
Block a user