我实际的控制器是gd32f103的,然后建立项目的时候选的stm32f103的,直接pin to pin的,现在有个问题,我根据串口部分的教程弄了两个信号量用来做modbus通讯,现在的现象是只要在finsh终端使用list_sem命令,finsh终端就没反应了,但是串口依旧可打印出数据来,截图如下
/* modbus_slave */
/*
- Copyright (c) 2006-2021, RT-Thread Development Team
- SPDX-License-Identifier: Apache-2.0
- Change Logs:
- Date Author Notes
- 2022-07-12 lenovo the first version
*/
#include "rs485_slave.h"
#include <board.h>
#define DBG_TAG "rs485_slave"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#define RS485_SLAVE_RE_PIN GET_PIN(E, 15)
#define RS485_SLAVE_TX_EN() rt_pin_write(RS485_SLAVE_RE_PIN, PIN_HIGH)
#define RS485_SLAVE_RX_EN() rt_pin_write(RS485_SLAVE_RE_PIN, PIN_LOW)
static rt_device_t _dev = RT_NULL;
static rt_sem_t _rx_sem = RT_NULL;
#define TAB_MAX_NUM 10
static uint8_t _tab_bits[TAB_MAX_NUM] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
static uint8_t _tab_input_bits[TAB_MAX_NUM] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
static uint16_t _tab_registers[TAB_MAX_NUM] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static uint16_t _tab_input_registers[TAB_MAX_NUM] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
/**
*/
static int slave_callback(agile_modbus_t *ctx, struct agile_modbus_slave_info *slave_info)
{
int function = slave_info->sft->function;
int ret = 0;
switch (function) {
case AGILE_MODBUS_FC_READ_COILS:
case AGILE_MODBUS_FC_READ_DISCRETE_INPUTS: {
int address = slave_info->address;
int nb = slave_info->nb;
int send_index = slave_info->send_index;
int is_input = (function == AGILE_MODBUS_FC_READ_DISCRETE_INPUTS);
for (int now_address = address, i = 0; now_address < address + nb; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
agile_modbus_slave_io_set(ctx->send_buf + send_index, i,
is_input ? _tab_input_bits[index] : _tab_bits[index]);
}
}
} break;
case AGILE_MODBUS_FC_READ_HOLDING_REGISTERS:
case AGILE_MODBUS_FC_READ_INPUT_REGISTERS: {
int address = slave_info->address;
int nb = slave_info->nb;
int send_index = slave_info->send_index;
int is_input = (function == AGILE_MODBUS_FC_READ_INPUT_REGISTERS);
for (int now_address = address, i = 0; now_address < address + nb; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
agile_modbus_slave_register_set(ctx->send_buf + send_index, i,
is_input ? _tab_input_registers[index] : _tab_registers[index]);
}
}
} break;
case AGILE_MODBUS_FC_WRITE_SINGLE_COIL:
case AGILE_MODBUS_FC_WRITE_MULTIPLE_COILS: {
int address = slave_info->address;
if (function == AGILE_MODBUS_FC_WRITE_SINGLE_COIL) {
if (address >= 0 && address < TAB_MAX_NUM) {
int index = address - 0;
int data = *((int *)slave_info->buf);
_tab_bits[index] = data;
}
} else {
int nb = slave_info->nb;
for (int now_address = address, i = 0; now_address < address + nb; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
uint8_t status = agile_modbus_slave_io_get(slave_info->buf, i);
_tab_bits[index] = status;
}
}
}
} break;
case AGILE_MODBUS_FC_WRITE_SINGLE_REGISTER:
case AGILE_MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
int address = slave_info->address;
if (function == AGILE_MODBUS_FC_WRITE_SINGLE_REGISTER) {
if (address >= 0 && address < TAB_MAX_NUM) {
int index = address - 0;
int data = *((int *)slave_info->buf);
_tab_registers[index] = data;
}
} else {
int nb = slave_info->nb;
for (int now_address = address, i = 0; now_address < address + nb; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
uint16_t data = agile_modbus_slave_register_get(slave_info->buf, i);
_tab_registers[index] = data;
}
}
}
} break;
case AGILE_MODBUS_FC_MASK_WRITE_REGISTER: {
int address = slave_info->address;
if (address >= 0 && address < TAB_MAX_NUM) {
int index = address - 0;
uint16_t data = _tab_registers[index];
uint16_t and = (slave_info->buf[0] << 8) + slave_info->buf[1];
uint16_t or = (slave_info->buf[2] << 8) + slave_info->buf[3];
data = (data & and) | (or &(~and));
_tab_registers[index] = data;
}
} break;
case AGILE_MODBUS_FC_WRITE_AND_READ_REGISTERS: {
int address = slave_info->address;
int nb = (slave_info->buf[0] << 8) + slave_info->buf[1];
uint16_t address_write = (slave_info->buf[2] << 8) + slave_info->buf[3];
int nb_write = (slave_info->buf[4] << 8) + slave_info->buf[5];
int send_index = slave_info->send_index;
for (int now_address = address_write, i = 0; now_address < address_write + nb_write; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
uint16_t data = agile_modbus_slave_register_get(slave_info->buf + 7, i);
_tab_registers[index] = data;
}
}
for (int now_address = address, i = 0; now_address < address + nb; now_address++, i++) {
if (now_address >= 0 && now_address < TAB_MAX_NUM) {
int index = now_address - 0;
agile_modbus_slave_register_set(ctx->send_buf + send_index, i, _tab_registers[index]);
}
}
} break;
default:
ret = -AGILE_MODBUS_EXCEPTION_ILLEGAL_FUNCTION;
break;
}
return ret;
}
static rt_err_t rs485_ind_cb(rt_device_t dev, rt_size_t size)
{
if (size > 0) {
rt_sem_release(_rx_sem);
}
return RT_EOK;
}
int rs485_slave_send(uint8_t *buf, int len)
{
RS485_SLAVE_TX_EN();
rt_device_write(_dev, 0, buf, len);
RS485_SLAVE_RX_EN();
return len;
}
int rs485_slave_receive(uint8_t *buf, int bufsz, int timeout, int bytes_timeout)
{
int len = 0;
while(1)
{
rt_sem_control(_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
int rc = rt_device_read(_dev, 0, buf + len, bufsz);
if(rc > 0)
{
timeout = bytes_timeout;
len += rc;
bufsz -= rc;
if(bufsz == 0)
break;
continue;
}
if(rt_sem_take(_rx_sem, rt_tick_from_millisecond(timeout)) != RT_EOK)
break;
timeout = bytes_timeout;
}
return len;
}
int rs485_slave_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_pin_mode(RS485_SLAVE_RE_PIN, PIN_MODE_OUTPUT);
RS485_SLAVE_TX_EN();
_rx_sem = rt_sem_create("M_slave", 0, RT_IPC_FLAG_FIFO);
if(_rx_sem == RT_NULL)
{
LOG_E("create rs485_slave_rx_sem failed.");
return -RT_ERROR;
}
_dev = rt_device_find("uart3");
if (_dev == RT_NULL)
{
LOG_E("can't find device uart3.");
rt_sem_delete(_rx_sem);
return -RT_ERROR;
}
config.baud_rate = BAUD_RATE_9600;
config.data_bits = DATA_BITS_8;
config.stop_bits = STOP_BITS_1;
config.bufsz = 1024;
config.parity = PARITY_NONE;
rt_device_control(_dev, RT_DEVICE_CTRL_CONFIG, &config);
rt_device_set_rx_indicate(_dev, rs485_ind_cb);
rt_device_open(_dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
RS485_SLAVE_RX_EN();
return RT_EOK;
}
void rs485_slave_thread_entry(void *p)
{
uint8_t ctx_send_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
uint8_t ctx_read_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
agile_modbus_rtu_t ctx_rtu;
agile_modbus_t *ctx = &ctx_rtu._ctx;
agile_modbus_rtu_init(&ctx_rtu, ctx_send_buf, sizeof(ctx_send_buf), ctx_read_buf, sizeof(ctx_read_buf));
agile_modbus_set_slave(ctx, 1);
while(1)
{
rt_thread_mdelay(100);
int read_len = rs485_slave_receive(ctx->read_buf, ctx->read_bufsz, 1000, 20);
if (read_len == 0)
{
continue;
}
int rc = agile_modbus_slave_handle(ctx, read_len, 1, slave_callback, NULL);
if (rc < 0)
{
LOG_W("Master Cmd Receive failed.");
if (rc != -1)
LOG_W("Error code:%d", -128 - rc);
continue;
}
rs485_slave_send(ctx->send_buf, rc);
}
}
int rs485_slave_app(void)
{
rt_thread_t rs485_slave_thread = RT_NULL;
rs485_slave_thread = rt_thread_create("M_slave_app", rs485_slave_thread_entry, RT_NULL, 2048, 15, 10);
if(rs485_slave_thread == RT_NULL)
{
return RT_ERROR;
}
rt_thread_startup(rs485_slave_thread);
rs485_slave_init();
return RT_EOK;
}
INIT_APP_EXPORT(rs485_slave_app);
/* modbus_master */
/*
- Copyright (c) 2006-2021, RT-Thread Development Team
- SPDX-License-Identifier: Apache-2.0
- Change Logs:
- Date Author Notes
- 2022-07-11 lenovo the first version
*/
#include "rs485_master.h"
#include <board.h>
#define DBG_TAG "rs485_master"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#define RS485_MASTER_RE_PIN GET_PIN(A, 1)
#define RS485_MASTER_TX_EN() rt_pin_write(RS485_MASTER_RE_PIN, PIN_HIGH)
#define RS485_MASTER_RX_EN() rt_pin_write(RS485_MASTER_RE_PIN, PIN_LOW)
static rt_device_t _dev = RT_NULL;
static rt_sem_t _rx_sem = RT_NULL;
static rt_err_t rs485_master_ind_cb(rt_device_t dev, rt_size_t size)
{
if (size > 0) {
rt_sem_release(_rx_sem);
}
return RT_EOK;
}
int rs485_master_send(uint8_t *buf, int len)
{
RS485_MASTER_TX_EN();
rt_device_write(_dev, 0, buf, len);
RS485_MASTER_RX_EN();
return len;
}
int rs485_master_receive(uint8_t *buf, int bufsz, int timeout, int bytes_timeout)
{
int len = 0;
while(1)
{
rt_sem_control(_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
int rc = rt_device_read(_dev, 0, buf + len, bufsz);
if(rc > 0)
{
timeout = bytes_timeout;
len += rc;
bufsz -= rc;
if(bufsz == 0)
break;
continue;
}
if(rt_sem_take(_rx_sem, rt_tick_from_millisecond(timeout)) != RT_EOK)
break;
timeout = bytes_timeout;
}
return len;
}
int rs485_master_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_pin_mode(RS485_MASTER_RE_PIN, PIN_MODE_OUTPUT);
RS485_MASTER_RX_EN();
_rx_sem = rt_sem_create("M_master", 0, RT_IPC_FLAG_FIFO);
if(_rx_sem == RT_NULL)
{
LOG_E("create rs485_master_rx_sem failed.");
return -RT_ERROR;
}
_dev = rt_device_find("uart2");
if (_dev == RT_NULL)
{
LOG_E("can't find device uart2.");
rt_sem_delete(_rx_sem);
return -RT_ERROR;
}
config.baud_rate = BAUD_RATE_9600;
config.data_bits = DATA_BITS_8;
config.stop_bits = STOP_BITS_1;
config.bufsz = 1024;
config.parity = PARITY_NONE;
rt_device_control(_dev, RT_DEVICE_CTRL_CONFIG, &config);
rt_device_set_rx_indicate(_dev, rs485_master_ind_cb);
rt_device_open(_dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
return RT_EOK;
}
#define RegisterCount 10
void rs485_master_thread_entry(void *p)
{
uint8_t ctx_send_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
uint8_t ctx_read_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
uint16_t hold_register[RegisterCount];
uint8_t coli_register[RegisterCount] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
agile_modbus_rtu_t ctx_rtu;
agile_modbus_t *ctx = &ctx_rtu._ctx;
agile_modbus_rtu_init(&ctx_rtu, ctx_send_buf, sizeof(ctx_send_buf), ctx_read_buf, sizeof(ctx_read_buf));
agile_modbus_set_slave(ctx, 1);
LOG_I("rs485_master_thread Running.");
while (1)
{
rt_thread_mdelay(500);
agile_modbus_set_slave(ctx, 1);
int send_len = agile_modbus_serialize_read_registers(ctx, 64, RegisterCount);
rs485_master_send(ctx->send_buf, send_len);
int read_len = rs485_master_receive(ctx->read_buf, ctx->read_bufsz, 1000, 20);
if (read_len == 0)
{
continue;
}
int rc = agile_modbus_deserialize_read_registers(ctx, read_len, hold_register);
if (rc < 0)
{
if (rc != -1)
LOG_W("Error code:%d", -128 - rc);
continue;
}
/* LOG_I("Hold Registers:");
for (int i = 0; i < RegisterCount; i++)
LOG_I("Register [%d]: 0x%04X", i, hold_register[i]);
rt_kprintf("\r\n\r\n\r\n");*/
for(int j = 0; j < RegisterCount; j++)
{
coli_register[j] = !coli_register[j];
}
agile_modbus_set_slave(ctx, 2);
send_len = agile_modbus_serialize_write_bits(ctx, 0, RegisterCount, &coli_register[0]);
rs485_master_send(ctx->send_buf, send_len);
read_len = rs485_master_receive(ctx->read_buf, ctx->read_bufsz, 1000, 20);
if (read_len == 0)
{
continue;
}
rc = agile_modbus_deserialize_write_bits(ctx, read_len);
if (rc < 0)
{
//LOG_W("address 2 Receive failed.")
if (rc != -1)
LOG_W("Error code:%d", -128 - rc)
continue
}else {
/LOG_I("Write Coils Registers is Ok!");/
}
}
}
int rs485_master_app(void)
{
rt_thread_t rs485_master_thread = RT_NULL;
rs485_master_thread = rt_thread_create("M_master_app", rs485_master_thread_entry, RT_NULL, 2048, 14, 10);
if(rs485_master_thread == RT_NULL)
{
return RT_ERROR;
}
rt_thread_startup(rs485_master_thread);
rs485_master_init();
return RT_EOK;
}
INIT_APP_EXPORT(rs485_master_app);