- The libmodbus library provides some locking mechanisms to protect data accessing Modbus slave devices in multi-threaded environments. Specifically, the libmodbus library provides the following two locking mechanisms:
- Mutex: The modbus_t structure in the libmodbus library contains a mutex that can be locked and unlocked using the modbus_mutex-lock() and modbus_mutex_unlock() functions to protect against Modbus slaves in multi-threaded environments
- Recursive lock: The libmodbus library also provides a reentrant lock mechanism, which can be used to set user-defined RTS operation callback functions through the modbus_rtu_det_custom_rts() function, and lock and unlock in the callback functions to protect access to Modbus slave devices in multi-threaded environments.
It should be noted that using lock mechanisms requires caution, as improper use can lead to issues such as deadlocks or thread blocking. Therefore, when using the libmodbus library in a multi-threaded environment, careful design and implementation of thread synchronization mechanisms are necessary.
The following is an example code of mutex using the libmodbus library:
#include <stdio.h>
#include <modbus/modbus.h>
int main() {
modbus_t *ctx;
modbus_mapping_t *mapping;
int ret;
// 创建Modbus从站设备并分配数据存储区
ctx = modbus_new_rtu("/dev/ttyS0", 9600, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Failed to create modbus contextn");
return -1;
}
mapping = modbus_mapping_new(0, 0, 100, 0);
if (mapping == NULL) {
fprintf(stderr, "Failed to allocate mappingn");
modbus_free(ctx);
return -1;
}
// 加锁并访问Modbus从站设备
modbus_mutex_lock(ctx);
ret = modbus_connect(ctx);
if (ret == -1) {
fprintf(stderr, "Failed to connect to Modbus devicen");
modbus_mutex_unlock(ctx);
return -1;
}
ret = modbus_write_register(ctx, 0, 123);
if (ret == -1) {
fprintf(stderr, "Failed to write registern");
modbus_mutex_unlock(ctx);
return -1;
}
modbus_close(ctx);
modbus_mutex_unlock(ctx);
// 释放资源并退出
modbus_mapping_free(mapping);
modbus_free(ctx);
return 0;
}
In the above code, the lock is added by calling the modbus_mutex-lock() function, then the Modbus slave device is accessed, and finally unlocked by calling the modbus_mutex_unlock() function. Using mutex locks ensures that only one thread can access Modbus slave devices in a multi-threaded environment, avoiding issues such as race conditions.
The following is an example code of a reentrant lock using the libmodbus library:
#include <stdio.h>
#include <modbus/modbus.h>
// 定义可重入锁
modbus_t *g_ctx = NULL;
modbus_mutex_t g_lock;
// 定义用户自定义的RTS回调函数
void custom_rts(modbus_t *ctx, int on) {
if (on) {
modbus_mutex_lock(&g_lock);
} else {
modbus_mutex_unlock(&g_lock);
}
}
int main() {
modbus_mapping_t *mapping;
int ret;
// 创建Modbus从站设备并分配数据存储区
g_ctx = modbus_new_rtu("/dev/ttyS0", 9600, 'N', 8, 1);
if (g_ctx == NULL) {
fprintf(stderr, "Failed to create modbus contextn");
return -1;
}
mapping = modbus_mapping_new(0, 0, 100, 0);
if (mapping == NULL) {
fprintf(stderr, "Failed to allocate mappingn");
modbus_free(g_ctx);
return -1;
}
// 设置用户自定义的RTS回调函数并访问Modbus从站设备
modbus_set_rts(g_ctx, custom_rts);
ret = modbus_write_register(g_ctx, 0, 123);
if (ret == -1) {
fprintf(stderr, "Failed to write registern");
quasi doloremque voluptatem deserunt ea culpa architecto est. natus voluptatibus iste ea consequatur et sed atque voluptatum exercitationem voluptatibus omnis est qui. quidem distinctio natus maxime f