fix mb & tty

This commit is contained in:
wmano
2025-09-13 23:08:11 +08:00
parent ffe1456b3a
commit 349741d9e1
33 changed files with 1745 additions and 4418 deletions
+7 -4
View File
@@ -159,11 +159,14 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
# Memory Management
#
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SMALL_MEM is not set
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMHEAP is not set
CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
CONFIG_RT_USING_MEMHEAP=y
CONFIG_RT_MEMHEAP_FAST_MODE=y
# CONFIG_RT_MEMHEAP_BEST_MODE is not set
# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set
CONFIG_RT_USING_MEMHEAP_AS_HEAP=y
CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y
# CONFIG_RT_USING_SLAB_AS_HEAP is not set
# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
+516 -126
View File
@@ -1,169 +1,559 @@
#include <string.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#include "chrg_tty.h"
#include <chrg_tty.h>
#include "chrg_north.h"
#include "chrg_south.h"
#define LOG_TAG "chrg.tty"
#define DBG_LEVEL DBG_LOG
#define DBG_TAG "chrg.tty"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
struct chrg_tty_t chrgtty[TOTAL_TTY] = {
[IDX_TTY_LCD] = {
.dev = RT_NULL,
.name = DEV_NAME_LCD,
.index = IDX_TTY_LCD,
.baudrate = BAUD_RATE_115200,
.rb = RT_NULL,
},
[IDX_TTY_NORTH] = {
.dev = RT_NULL,
.name = DEV_NAME_NORTH,
.index = IDX_TTY_NORTH,
.baudrate = BAUD_RATE_2000000,
.rb = RT_NULL,
},
[IDX_TTY_SOUTH] = {
.dev = RT_NULL,
.name = DEV_NAME_SOUTH,
.index = IDX_TTY_SOUTH,
.baudrate = BAUD_RATE_2000000,
.rb = RT_NULL,
}
};
static rt_err_t chrg_lcd_tty_input (rt_device_t dev, rt_size_t size)
#ifdef TTY_USING_DMA_TX
static rt_err_t chrg_tty_send_comp_hook (rt_device_t dev, void *buffer)
{
rt_err_t ret;
struct chrg_tty_t *pTTY = &chrgtty[IDX_TTY_LCD];
struct mq_msg_t msg;
struct chrg_tty_t *pTTY = (struct chrg_tty_t *)(dev->user_data);
rt_completion_done(&pTTY->tx_comp);
if ((RT_NULL != dev) && (RT_NULL != pTTY->mq) && (size > 0)) {
msg.dev = dev;
msg.size = size;
ret = rt_mq_send(pTTY->mq, &msg, sizeof(struct mq_msg_t));
if (RT_EOK != ret) {
LOG_E("send mq '%s' failed.", pTTY->name);
}
}
return (RT_EOK);
}
#endif
return ret;
static rt_err_t chrg_tty_recv_ind_hook (rt_device_t dev, rt_size_t size)
{
struct chrg_tty_t *pTTY = (struct chrg_tty_t *)(dev->user_data);
if (pTTY->evt) {
rt_event_send(pTTY->evt, TTY_EVT_RX_IND);
}
return (RT_EOK);
}
static rt_err_t chrg_north_tty_input (rt_device_t dev, rt_size_t size)
static int chrg_tty_cal_byte_tmo (int baudrate)
{
rt_err_t ret;
struct chrg_tty_t *pTTY = &chrgtty[IDX_TTY_NORTH];
struct mq_msg_t msg;
int tmo = (40 * 1000) / baudrate;
if ((RT_NULL != dev) && (RT_NULL != pTTY->mq) && (size > 0)) {
msg.dev = dev;
msg.size = size;
ret = rt_mq_send(pTTY->mq, &msg, sizeof(struct mq_msg_t));
if (RT_EOK != ret) {
LOG_E("send mq '%s' failed.", pTTY->name);
}
}
if (tmo < TTY_BYTE_TMO_MIN) {
tmo = TTY_BYTE_TMO_MIN;
} else if (tmo > TTY_BYTE_TMO_MAX) {
tmo = TTY_BYTE_TMO_MAX;
}
return ret;
return (tmo);
}
static rt_err_t chrg_south_tty_input (rt_device_t dev, rt_size_t size)
// mode : 0--receive mode, 1--send mode
static void chrg_tty_mode_set (struct chrg_tty_t *pTTY, int mode)
{
rt_err_t ret;
struct chrg_tty_t *pTTY = &chrgtty[IDX_TTY_SOUTH];
struct mq_msg_t msg;
if (pTTY->pin < 0) {
return;
}
if ((RT_NULL != dev) && (RT_NULL != pTTY->mq) && (size > 0)) {
msg.dev = dev;
msg.size = size;
ret = rt_mq_send(pTTY->mq, &msg, sizeof(struct mq_msg_t));
if (RT_EOK != ret) {
LOG_E("send mq '%s' failed.", pTTY->name);
}
}
if (mode) {
rt_pin_write(pTTY->pin, pTTY->level);
#if (TTY_SW_DLY_US > 0)
rt_hw_us_delay(TTY_SW_DLY_US);
#endif
} else {
return ret;
#ifdef TTY_USING_DMA_TX
rt_completion_wait(&pTTY->tx_comp, TTY_TX_COMP_TMO_MAX);
rt_thread_mdelay(pTTY->tx_dly_ms); // 等待末尾数据传输完成
#elif (TTY_SW_DLY_US > 0)
rt_hw_us_delay(TTY_SW_DLY_US);
#endif
rt_pin_write(pTTY->pin, !pTTY->level);
}
}
rt_err_t chrg_tty_open (struct chrg_tty_t *pTTY)
static int chrg_tty_dev_open (struct chrg_tty_t *pTTY)
{
rt_err_t ret = RT_EOK;
if (RT_NULL == pTTY) {
return RT_EEMPTY;
}
#ifdef TTY_USING_DMA_RX
struct serial_configure cfg = {
.baud_rate = pTTY->baudrate,
.data_bits = DATA_BITS_8,
.stop_bits = STOP_BITS_1,
.parity = PARITY_NONE,
.bit_order = BIT_ORDER_LSB,
.invert = NRZ_NORMAL,
.bufsz = RT_SERIAL_RB_BUFSZ,
.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE,
};
#ifdef TTY_USING_DMA_TX
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX);
if (RT_EOK == ret) {
return (RT_EOK);
}
#endif
pTTY->dev = rt_device_find(pTTY->name);
if (RT_NULL == pTTY->dev) {
LOG_E("dev '%s' not found.", pTTY->name);
return RT_ERROR;
}
#ifdef TTY_USING_INT_TX
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_INT_TX);
if (RT_EOK == ret) {
return (RT_EOK);
}
#endif
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX);
if (ret != RT_EOK) {
LOG_E("open '%s' failed.", pTTY->name);
return ret;
}
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
if (RT_EOK == ret) {
return (RT_EOK);
}
ret = rt_device_control(pTTY->dev, RT_DEVICE_CTRL_CONFIG, &cfg);
if (ret != RT_EOK) {
LOG_E("control '%s' failed.", pTTY->name);
return ret;
}
#endif
switch (pTTY->index) {
case IDX_TTY_LCD:
rt_device_set_rx_indicate(pTTY->dev, chrg_lcd_tty_input);
break;
case IDX_TTY_NORTH:
rt_device_set_rx_indicate(pTTY->dev, chrg_north_tty_input);
break;
case IDX_TTY_SOUTH:
rt_device_set_rx_indicate(pTTY->dev, chrg_south_tty_input);
break;
default:
return RT_ERROR;
}
#ifdef TTY_USING_DMA_TX
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX);
if (RT_EOK == ret) {
return (RT_EOK);
}
#endif
pTTY->mq = rt_mq_create(pTTY->name, sizeof(struct mq_msg_t), 16, RT_IPC_FLAG_FIFO);
if (RT_NULL == pTTY->mq) {
LOG_E("create mq '%s' failed.", pTTY->name);
return RT_ERROR;
}
#ifdef TTY_USING_INT_TX
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX);
if (RT_EOK == ret) {
return (RT_EOK);
}
#endif
return RT_EOK;
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
if (RT_EOK == ret) {
return (RT_EOK);
}
return (-RT_ERROR);
}
static int chrg_tty_init (void)
/*
* @brief create tty instance dynamically
* @param name - serial device name
* @param baudrate - serial baud rate
* @param parity - serial parity mode
* @param pin - mode contrle pin
* @param level - send mode level
* @retval instance handle
*/
struct chrg_tty_t *chrg_tty_create (const char *name, int baudrate, int parity, int pin, int level)
{
struct chrg_tty_t *pTTY = RT_NULL;
int i = 0;
struct chrg_tty_t *pTTY = RT_NULL;
rt_device_t dev;
for (i = 0; i < TOTAL_TTY; i++) {
pTTY = &chrgtty[i];
chrg_tty_open(pTTY);
}
dev = rt_device_find(name);
if (RT_NULL == dev) {
LOG_E("tty device '%s' not found.", name);
return (RT_NULL);
}
return RT_EOK;
if (RT_Device_Class_Char != dev->type) {
LOG_E("tty device '%s' type is not char.", name);
return (RT_NULL);
}
pTTY = (struct chrg_tty_t *)rt_malloc(sizeof(struct chrg_tty_t));
if (RT_NULL == pTTY) {
LOG_E("no memory for tty create instance.");
return (RT_NULL);
}
pTTY->lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
if (RT_NULL == pTTY->lock) {
rt_free(pTTY);
LOG_E("create mutex failed.");
return (RT_NULL);
}
pTTY->evt = rt_event_create(name, RT_IPC_FLAG_FIFO);
if (RT_NULL == pTTY->evt) {
rt_mutex_delete(pTTY->lock);
rt_free(pTTY);
LOG_E("create event failed.");
return (RT_NULL);
}
#ifdef TTY_USING_DMA_TX
pTTY->tx_dly_ms = ((2 * 11 *1000) / baudrate) + 1;
rt_completion_init(&pTTY->tx_comp);
#endif
pTTY->dev = dev;
pTTY->status = 0;
pTTY->pin = pin;
pTTY->level = (level != 0);
pTTY->timeout = 0;
pTTY->byte_tmo = chrg_tty_cal_byte_tmo(baudrate);
chrg_tty_config(pTTY, baudrate, 8, parity, 0);
return pTTY;
}
INIT_APP_EXPORT(chrg_tty_init);
/*
* @brief destory tty instance created dynamically
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
int chrg_tty_destory (struct chrg_tty_t *pTTY)
{
if (RT_NULL == pTTY) {
LOG_E("param null.");
return (-RT_ERROR);
}
chrg_tty_disconn(pTTY);
if (pTTY->lock) {
rt_mutex_delete(pTTY->lock);
pTTY->lock = RT_NULL;
}
if (pTTY->evt) {
rt_event_delete(pTTY->evt);
pTTY->evt = RT_NULL;
}
rt_free(pTTY);
return (RT_EOK);
}
/*
* @brief config tty params
* @param pTTY - instance handle
* @param baudrate - baudrate of communication
* @param databits - data bits, 5~8
* @param parity - parity bit, 0~2, 0 - none, 1 - odd, 2 - even
* @param stopbits - stop bits, 0~1, 0 - 1 stop bit, 1 - 2 stop bits
* @retval 0 - success, other - error
*/
int chrg_tty_config (struct chrg_tty_t *pTTY,
int baudrate, int databits, int parity, int stopbits)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
if (RT_NULL == pTTY) {
LOG_E("param null.");
return (-RT_ERROR);
}
#ifdef TTY_USING_DMA_TX
pTTY->tx_dly_ms = ((2 * 11 *1000) / baudrate) + 1;
#endif
pTTY->byte_tmo = chrg_tty_cal_byte_tmo(baudrate);
config.baud_rate = baudrate;
config.data_bits = databits;
config.parity = parity;
config.stop_bits = stopbits;
rt_device_control(pTTY->dev, RT_DEVICE_CTRL_CONFIG, &config);
return (RT_EOK);
}
/*
* @brief set wait datas timeout for receiving
* @param pTTY - instance handle
* @param tmo_ms - receive wait timeout, 0--no wait, <0--wait forever, >0--wait timeout, default = 0
* @retval 0 - success, other - error
*/
int chrg_tty_set_recv_tmo (struct chrg_tty_t *pTTY, int tmo_ms)
{
if (RT_NULL == pTTY) {
LOG_E("param null.");
return (-RT_ERROR);
}
pTTY->timeout = tmo_ms;
return (RT_EOK);
}
/*
* @brief set byte interval timeout for receiving
* @param pTTY - instance handle
* @param tmo_ms - byte interval timeout, default is calculated from baudrate
* @retval 0 - success, other - error
*/
int chrg_tty_set_byte_tmo (struct chrg_tty_t *pTTY, int tmo_ms)
{
if (RT_NULL == pTTY) {
LOG_E("param null.");
return (-RT_ERROR);
}
if (tmo_ms < TTY_BYTE_TMO_MIN) {
tmo_ms = TTY_BYTE_TMO_MIN;
} else if (tmo_ms > TTY_BYTE_TMO_MAX) {
tmo_ms = TTY_BYTE_TMO_MAX;
}
pTTY->byte_tmo = tmo_ms;
return (RT_EOK);
}
/*
* @brief open tty connect
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
int chrg_tty_connect (struct chrg_tty_t * pTTY)
{
if (RT_NULL == pTTY) {
LOG_E("param null.");
return -RT_ERROR;
}
if (pTTY->status == 1) {
return RT_EOK;
}
if (chrg_tty_dev_open(pTTY) != RT_EOK) {
LOG_E("tty open failed.");
return -RT_ERROR;
}
if (pTTY->pin >= 0) {
rt_pin_mode(pTTY->pin, PIN_MODE_OUTPUT);
rt_pin_write(pTTY->pin, !pTTY->level);
}
pTTY->dev->user_data = pTTY;
pTTY->dev->rx_indicate = chrg_tty_recv_ind_hook;
#ifdef TTY_USING_DMA_TX
pTTY->dev->tx_complete = chrg_tty_send_comp_hook;
#endif
pTTY->status = 1;
return (RT_EOK);
}
/*
* @brief close tty connect
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
int chrg_tty_disconn (struct chrg_tty_t *pTTY)
{
if (RT_NULL == pTTY) {
LOG_E("param null.");
return (-RT_ERROR);
}
if (pTTY->status == 0) {
return(RT_EOK);
}
rt_mutex_take(pTTY->lock, RT_WAITING_FOREVER);
if (pTTY->dev) {
pTTY->dev->rx_indicate = RT_NULL;
#ifdef TTY_USING_DMA_TX
pTTY->dev->tx_complete = RT_NULL;
#endif
rt_device_close(pTTY->dev);
}
if (pTTY->pin >= 0) {
rt_pin_mode(pTTY->pin, PIN_MODE_INPUT);
}
pTTY->status = 0;
rt_mutex_release(pTTY->lock);
return (RT_EOK);
}
/*
* @brief receive datas from tty
* @param pTTY - instance handle
* @param buf - buffer addr
* @param size - maximum length of received datas
* @retval >=0 - length of received datas, <0 - error
*/
int chrg_tty_recv (struct chrg_tty_t *pTTY, void *buf, int size)
{
rt_err_t ret = RT_EOK;
int recv_len = 0;
rt_uint32_t recved = 0;
if (pTTY == RT_NULL || buf == RT_NULL || size == 0) {
LOG_E("param null.");
return (-RT_ERROR);
}
if (pTTY->status == 0) {
return (-RT_ERROR);
}
ret = rt_mutex_take(pTTY->lock, RT_WAITING_FOREVER);
if (RT_EOK != ret) {
LOG_E("mutex take failed. [%d]", ret);
return(-RT_ERROR);
}
while (size) {
int len = rt_device_read(pTTY->dev, 0, (char *)buf + recv_len, size);
if (len) {
recv_len += len;
size -= len;
continue;
}
rt_event_control(pTTY->evt, RT_IPC_CMD_RESET, RT_NULL);
if (recv_len) {
ret = rt_event_recv(pTTY->evt, TTY_EVT_RX_IND,
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), pTTY->byte_tmo, &recved);
if (RT_EOK != ret) {
break;
}
} else {
ret = rt_event_recv(pTTY->evt, (TTY_EVT_RX_IND | TTY_EVT_RX_BREAK),
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), pTTY->timeout, &recved);
if (RT_EOK != ret) {
break;
}
if ((recved & TTY_EVT_RX_BREAK) != 0) {
rt_mutex_release(pTTY->lock);
rt_thread_delay(2);
return 0;
}
}
}
rt_mutex_release(pTTY->lock);
return recv_len;
}
/*
* @brief send datas to tty
* @param pTTY - instance handle
* @param buf - buffer addr
* @param size - length of send datas
* @retval >=0 - length of sent datas, <0 - error
*/
int chrg_tty_send (struct chrg_tty_t *pTTY, void *buf, int size)
{
rt_err_t ret = RT_EOK;
int send_len = 0;
if (pTTY == RT_NULL || buf == RT_NULL || size == 0) {
LOG_E("param null.");
return (-RT_ERROR);
}
if (pTTY->status == 0) {
LOG_E("tty not connected.");
return (-RT_ERROR);
}
rt_kprintf("%s %d\r\n", __func__, __LINE__);
ret = rt_mutex_take(pTTY->lock, RT_WAITING_FOREVER);
if (RT_EOK != ret) {
LOG_E("mutex take failed. [%d]", ret);
return (-RT_ERROR);
}
rt_kprintf("%s %d size %d\r\n", __func__, __LINE__, size);
chrg_tty_mode_set(pTTY, 1);//set to send mode
rt_kprintf("%s %d\r\n", __func__, __LINE__);
send_len = rt_device_write(pTTY->dev, 0, buf, size);
rt_kprintf("%s %d %d\r\n", __func__, __LINE__, send_len);
chrg_tty_mode_set(pTTY, 0);//set to receive mode
rt_mutex_release(pTTY->lock);
rt_kprintf("%s %d\r\n", __func__, __LINE__);
return send_len;
}
/*
* @brief break tty receive wait
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
int chrg_tty_break_recv (struct chrg_tty_t *pTTY)
{
if ((pTTY == RT_NULL) || (pTTY->evt == RT_NULL)) {
return (-RT_ERROR);
}
rt_event_send(pTTY->evt, TTY_EVT_RX_BREAK);
return (RT_EOK);
}
/*
* @brief send data to tty and then receive response data from tty
* @param pTTY - instance handle
* @param send_buf - send buffer addr
* @param send_len - length of send datas
* @param recv_buf - recv buffer addr
* @param recv_size - maximum length of received datas
* @retval >=0 - length of received datas, <0 - error
*/
int chrg_tty_send_then_recv (struct chrg_tty_t *pTTY,
void *send_buf, int send_len, void *recv_buf, int recv_size)
{
rt_err_t ret = RT_EOK;
int recv_len = 0;
rt_uint32_t recved = 0;
if (pTTY == RT_NULL || send_buf == RT_NULL || send_len == 0 || recv_buf == RT_NULL || recv_size == 0) {
LOG_E("null param");
return(-RT_ERROR);
}
if (pTTY->status == 0) {
LOG_E("tty not connected.");
return(-RT_ERROR);
}
ret = rt_mutex_take(pTTY->lock, RT_WAITING_FOREVER);
if (RT_EOK != ret) {
LOG_E("mutex take failed. [%d]", ret);
return(-RT_ERROR);
}
chrg_tty_mode_set(pTTY, 1);//set to send mode
send_len = rt_device_write(pTTY->dev, 0, send_buf, send_len);
chrg_tty_mode_set(pTTY, 0);//set to receive mode
if (send_len < 0) {
rt_mutex_release(pTTY->lock);
LOG_E("send error.");
return(-RT_ERROR);
}
while (recv_size) {
int len = rt_device_read(pTTY->dev, 0, (char *)recv_buf + recv_len, recv_size);
if (len) {
recv_len += len;
recv_size -= len;
continue;
}
rt_event_control(pTTY->evt, RT_IPC_CMD_RESET, RT_NULL);
if (recv_len) {
ret = rt_event_recv(pTTY->evt, TTY_EVT_RX_IND,
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), pTTY->byte_tmo, &recved);
if (RT_EOK != ret) {
break;
}
} else {
ret = rt_event_recv(pTTY->evt, TTY_EVT_RX_IND,
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), pTTY->timeout, &recved);
if (RT_EOK != ret) {
break;
}
}
}
rt_mutex_release(pTTY->lock);
return recv_len;
}
+135 -22
View File
@@ -3,12 +3,11 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#define DEV_NAME_LCD "uart2"
#define DEV_NAME_NORTH "uart3"
#define DEV_NAME_SOUTH "uart6"
#define SIZE_BUF_UART 128
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
IDX_TTY_LCD = 0, // 0
@@ -18,29 +17,143 @@ typedef enum {
TOTAL_TTY
} eIDX_TTY;
struct mq_msg_t {
rt_device_t dev;
rt_size_t size;
};
//#define TTY_USING_TEST //使用测试功能
//#define TTY_USING_SAMPLE_SLAVE //使用从机示例
//#define TTY_USING_SAMPLE_MASTER //使用主机示例
//#define TTY_USING_DMA_RX //使用DMA接收
//#define TTY_USING_INT_TX //使用中断发送
//#define TTY_USING_DMA_TX //使用DMA发送
#ifndef TTY_SW_DLY_US
#define TTY_SW_DLY_US 0 // 发送引脚控制切换延时
#endif
#define SIZE_BUF_TTY 128
#define TTY_TX_COMP_TMO_MAX (3 * RT_TICK_PER_SECOND) // 最大DMA传输完成超时
#define TTY_BYTE_TMO_MIN 2 // 最小字节超时
#define TTY_BYTE_TMO_MAX 200 // 最大字节超时
#define TTY_EVT_RX_IND (1<<0)
#define TTY_EVT_RX_BREAK (1<<1)
struct chrg_tty_t {
rt_device_t dev;
const char *name;
rt_uint32_t baudrate;
eIDX_TTY index;
rt_mq_t mq;
struct rt_ringbuffer *rb;
struct rt_semaphore sem_rx;
rt_device_t dev; // serial device handle
rt_mutex_t lock; // mutex handle
rt_event_t evt; // event handle
rt_uint8_t status; // connect status
rt_uint8_t level; // control pin send mode level, 0--low, 1--high
rt_int16_t pin; // control pin number used, -1--no using
rt_int32_t timeout; // receive block timeout, ms
rt_int32_t byte_tmo; // receive byte interval timeout, ms
#ifdef TTY_USING_DMA_TX
rt_int32_t tx_dly_ms;
struct rt_completion tx_comp; // send completion
#endif
};
extern struct chrg_tty_t chrgtty[TOTAL_TTY];
/*
* @brief create tty instance dynamically
* @param serial - serial device name
* @param baudrate - serial baud rate
* @param parity - serial parity mode
* @param pin - mode contrle pin
* @param level - send mode level
* @retval instance handle
*/
struct chrg_tty_t *chrg_tty_create (const char *name, int baudrate, int parity, int pin, int level);
/*
* @brief destory tty instance created dynamically
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
extern int chrg_tty_destory (struct chrg_tty_t *pTTY);
/*
* @brief config tty params
* @param pTTY - instance handle
* @param baudrate - baudrate of communication
* @param databits - data bits, 5~8
* @param parity - parity bit, 0~2, 0 - none, 1 - odd, 2 - even
* @param stopbits - stop bits, 0~1, 0 - 1 stop bit, 1 - 2 stop bits
* @retval 0 - success, other - error
*/
extern int chrg_tty_config (struct chrg_tty_t *pTTY,
int baudrate, int databits, int parity, int stopbits);
/*
* @brief set wait datas timeout for receiving
* @param pTTY - instance handle
* @param tmo_ms - receive wait timeout, 0--no wait, <0--wait forever, >0--wait timeout, default = 0
* @retval 0 - success, other - error
*/
extern int chrg_tty_set_recv_tmo (struct chrg_tty_t *pTTY, int tmo_ms);
/*
* @brief set byte interval timeout for receiving
* @param pTTY - instance handle
* @param tmo_ms - byte interval timeout, default is calculated from baudrate
* @retval 0 - success, other - error
*/
extern int chrg_tty_set_byte_tmo (struct chrg_tty_t *pTTY, int tmo_ms);
/*
* @brief open tty connect
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
extern int chrg_tty_connect (struct chrg_tty_t *pTTY);
/*
* @brief close tty connect
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
extern int chrg_tty_disconn (struct chrg_tty_t *pTTY);
/*
* @brief receive datas from tty
* @param pTTY - instance handle
* @param buf - buffer addr
* @param size - maximum length of received datas
* @retval >=0 - length of received datas, <0 - error
*/
extern int chrg_tty_recv (struct chrg_tty_t *pTTY, void *buf, int size);
/*
* @brief send datas to tty
* @param pTTY - instance handle
* @param buf - buffer addr
* @param size - length of send datas
* @retval >=0 - length of sent datas, <0 - error
*/
extern int chrg_tty_send (struct chrg_tty_t *pTTY, void *buf, int size);
/*
* @brief break tty receive wait
* @param pTTY - instance handle
* @retval 0 - success, other - error
*/
extern int chrg_tty_break_recv (struct chrg_tty_t *pTTY);
/*
* @brief send data to tty and then receive response data from tty
* @param pTTY - instance handle
* @param send_buf - send buffer addr
* @param send_len - length of send datas
* @param recv_buf - recv buffer addr
* @param recv_size - maximum length of received datas
* @retval >=0 - length of received datas, <0 - error
*/
extern int chrg_tty_send_then_recv (struct chrg_tty_t *pTTY,
void *send_buf, int send_len, void *recv_buf, int recv_size);
#ifdef __cplusplus
}
#endif
#endif
+1 -1
View File
@@ -47,6 +47,6 @@ static int chrg_wdt_init (void)
return RT_EOK;
}
INIT_APP_EXPORT(chrg_wdt_init);
INIT_PREV_EXPORT(chrg_wdt_init);
+67 -96
View File
@@ -26,12 +26,12 @@ static pvMBFrameStop pvMBFrameStopCur;
static peMBFrameReceive peMBFrameReceiveCur;
static pvMBFrameClose pvMBFrameCloseCur;
rt_uint8_t( *pxMBFrameCBByteReceived ) ( void );
rt_uint8_t( *pxMBFrameCBTransmitterEmpty ) ( void );
rt_uint8_t( *pxMBPortCBTimerExpired ) ( void );
rt_uint8_t (*pxMBFrameCBByteReceived)(void);
rt_uint8_t (*pxMBFrameCBTransmitterEmpty)(void);
rt_uint8_t (*pxMBPortCBTimerExpired)(void);
rt_uint8_t( *pxMBFrameCBReceiveFSMCur ) ( void );
rt_uint8_t( *pxMBFrameCBTransmitFSMCur ) ( void );
rt_uint8_t (*pxMBFrameCBReceiveFSMCur)(void);
rt_uint8_t (*pxMBFrameCBTransmitFSMCur)(void);
#define MB_FUNC_HANDLERS_MAX (16)
@@ -48,12 +48,13 @@ static xMBFunctionHandler xFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
{MB_FUNC_READ_DISCRETE_INPUTS, eMBFuncReadDiscreteInputs},
};
eMBErrorCode eMBInit(rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort, rt_uint32_t ulBaudRate, eMBParity eParity )
eMBErrorCode eMBInit (rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort,
rt_uint32_t ulBaudRate, eMBParity eParity )
{
eMBErrorCode eStatus = MB_ENOERR;
if((ucSlaveAddress == MB_ADDRESS_BROADCAST) ||
(ucSlaveAddress < MB_ADDRESS_MIN)||( ucSlaveAddress > MB_ADDRESS_MAX)) {
if ((ucSlaveAddress == MB_ADDRESS_BROADCAST) ||
(ucSlaveAddress < MB_ADDRESS_MIN)||(ucSlaveAddress > MB_ADDRESS_MAX)) {
eStatus = MB_EINVAL;
} else {
ucMBAddress = ucSlaveAddress;
@@ -67,9 +68,9 @@ eMBErrorCode eMBInit(rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort, rt_uint32_t u
pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
if( eStatus == MB_ENOERR ) {
if(!xMBPortEventInit()) {
eStatus = eMBRTUInit(ucMBAddress, ucPort, ulBaudRate, eParity);
if (eStatus == MB_ENOERR) {
if (!xMBPortEventInit()) {
/* port dependent event module initalization failed. */
eStatus = MB_EPORTERR;
} else {
@@ -81,33 +82,26 @@ eMBErrorCode eMBInit(rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort, rt_uint32_t u
return eStatus;
}
eMBErrorCode eMBRegisterCB( rt_uint8_t ucFunctionCode, pxMBFunctionHandler pxHandler )
eMBErrorCode eMBRegisterCB (rt_uint8_t ucFunctionCode, pxMBFunctionHandler pxHandler)
{
int i;
eMBErrorCode eStatus;
int i;
eMBErrorCode eStatus;
if( ( 0 < ucFunctionCode ) && ( ucFunctionCode <= 127 ) ) {
if ((0 < ucFunctionCode) && (ucFunctionCode <= 127)) {
EnterCriticalSection();
if( pxHandler != NULL )
{
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
{
if( ( xFuncHandlers[i].pxHandler == NULL ) ||
( xFuncHandlers[i].pxHandler == pxHandler ) )
{
if ( pxHandler != NULL ) {
for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
if ((xFuncHandlers[i].pxHandler == NULL) ||
(xFuncHandlers[i].pxHandler == pxHandler)) {
xFuncHandlers[i].ucFunctionCode = ucFunctionCode;
xFuncHandlers[i].pxHandler = pxHandler;
break;
}
}
eStatus = ( i != MB_FUNC_HANDLERS_MAX ) ? MB_ENOERR : MB_ENORES;
}
else
{
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
{
if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
{
eStatus = (i != MB_FUNC_HANDLERS_MAX) ? MB_ENOERR : MB_ENORES;
} else {
for (i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
if (xFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
xFuncHandlers[i].ucFunctionCode = 0;
xFuncHandlers[i].pxHandler = NULL;
break;
@@ -117,107 +111,90 @@ eMBErrorCode eMBRegisterCB( rt_uint8_t ucFunctionCode, pxMBFunctionHandler pxHan
eStatus = MB_ENOERR;
}
ExitCriticalSection();
}
else
{
} else {
eStatus = MB_EINVAL;
}
return eStatus;
}
eMBErrorCode eMBClose( void )
eMBErrorCode eMBClose (void)
{
eMBErrorCode eStatus = MB_ENOERR;
eMBErrorCode eStatus = MB_ENOERR;
if( eMBState == STATE_DISABLED )
{
if( pvMBFrameCloseCur != NULL )
{
pvMBFrameCloseCur( );
if (eMBState == STATE_DISABLED) {
if (pvMBFrameCloseCur != NULL) {
pvMBFrameCloseCur();
}
}
else
{
} else {
eStatus = MB_EILLSTATE;
}
return eStatus;
}
eMBErrorCode eMBEnable( void )
eMBErrorCode eMBEnable (void)
{
eMBErrorCode eStatus = MB_ENOERR;
eMBErrorCode eStatus = MB_ENOERR;
if( eMBState == STATE_DISABLED )
{
if (eMBState == STATE_DISABLED) {
/* Activate the protocol stack. */
pvMBFrameStartCur( );
pvMBFrameStartCur();
eMBState = STATE_ENABLED;
}
else
{
} else {
eStatus = MB_EILLSTATE;
}
return eStatus;
}
eMBErrorCode eMBDisable( void )
eMBErrorCode eMBDisable (void)
{
eMBErrorCode eStatus;
eMBErrorCode eStatus;
if( eMBState == STATE_ENABLED )
{
pvMBFrameStopCur( );
if (eMBState == STATE_ENABLED) {
pvMBFrameStopCur();
eMBState = STATE_DISABLED;
eStatus = MB_ENOERR;
}
else if( eMBState == STATE_DISABLED )
{
} else if (eMBState == STATE_DISABLED) {
eStatus = MB_ENOERR;
}
else
{
} else {
eStatus = MB_EILLSTATE;
}
return eStatus;
}
eMBErrorCode eMBPoll( void )
eMBErrorCode eMBPoll (void)
{
static rt_uint8_t *ucMBFrame;
static rt_uint8_t ucRcvAddress;
static rt_uint8_t ucFunctionCode;
static rt_uint16_t usLength;
static rt_uint8_t *ucMBFrame;
static rt_uint8_t ucRcvAddress;
static rt_uint8_t ucFunctionCode;
static rt_uint16_t usLength;
static eMBException eException;
int i;
eMBErrorCode eStatus = MB_ENOERR;
eMBEventType eEvent;
int i;
eMBErrorCode eStatus = MB_ENOERR;
eMBEventType eEvent;
/* Check if the protocol stack is ready. */
if( eMBState != STATE_ENABLED )
{
if (eMBState != STATE_ENABLED) {
return MB_EILLSTATE;
}
/* Check if there is a event available. If not return control to caller.
* Otherwise we will handle the event. */
if( xMBPortEventGet( &eEvent ) == TRUE )
{
switch ( eEvent )
{
if (xMBPortEventGet(&eEvent) == TRUE) {
switch (eEvent) {
case EV_READY:
break;
case EV_FRAME_RECEIVED:
eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
if( eStatus == MB_ENOERR )
{
eStatus = peMBFrameReceiveCur(&ucRcvAddress, &ucMBFrame, &usLength);
if (eStatus == MB_ENOERR) {
/* Check if the frame is for us. If not ignore the frame. */
if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
{
( void )xMBPortEventPost( EV_EXECUTE );
if ((ucRcvAddress == ucMBAddress) || (ucRcvAddress == MB_ADDRESS_BROADCAST)) {
(void)xMBPortEventPost(EV_EXECUTE);
}
}
break;
@@ -225,32 +202,26 @@ eMBErrorCode eMBPoll( void )
case EV_EXECUTE:
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
eException = MB_EX_ILLEGAL_FUNCTION;
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
{
for (i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
/* No more function handlers registered. Abort. */
if( xFuncHandlers[i].ucFunctionCode == 0 )
{
if(xFuncHandlers[i].ucFunctionCode == 0) {
break;
}
else if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
{
eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
} else if(xFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
eException = xFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
break;
}
}
/* If the request was not sent to the broadcast address we
* return a reply. */
if( ucRcvAddress != MB_ADDRESS_BROADCAST )
{
if( eException != MB_EX_NONE )
{
if (ucRcvAddress != MB_ADDRESS_BROADCAST) {
if(eException != MB_EX_NONE) {
/* An exception occured. Build an error frame. */
usLength = 0;
ucMBFrame[usLength++] = ( rt_uint8_t )( ucFunctionCode | MB_FUNC_ERROR );
ucMBFrame[usLength++] = (rt_uint8_t)(ucFunctionCode | MB_FUNC_ERROR);
ucMBFrame[usLength++] = eException;
}
eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
eStatus = peMBFrameSendCur(ucMBAddress, ucMBFrame, usLength);
}
break;
+59 -289
View File
@@ -4,7 +4,6 @@
#include <rtthread.h>
#include <assert.h>
//#include <inttypes.h>
#ifdef __cplusplus
@@ -12,25 +11,11 @@ extern "C" {
#endif
/*! \ingroup modbus
* \brief If register should be written or read.
*
* This value is passed to the callback functions which support either
* reading or writing register values. Writing means that the application
* registers should be updated and reading means that the modbus protocol
* stack needs to know the current register values.
*
* \see eMBRegHoldingCB( ), eMBRegCoilsCB( ), eMBRegDiscreteCB( ) and
* eMBRegInputCB( ).
*/
typedef enum {
MB_REG_READ, /*!< Read register values and pass to protocol stack. */
MB_REG_WRITE /*!< Update register values. */
} eMBRegisterMode;
/*! \ingroup modbus
* \brief Errorcodes used by all function in the protocol stack.
*/
typedef enum {
MB_ENOERR, /*!< no error. */
MB_ENOREG, /*!< illegal register address. */
@@ -49,13 +34,6 @@ typedef enum {
EV_FRAME_SENT = 1<<3 /*!< Frame sent. */
} eMBEventType;
/*! \ingroup modbus
* \brief Parity used for characters in serial mode.
*
* The parity which should be applied to the characters sent over the serial
* link. Please note that this values are actually passed to the porting
* layer and therefore not all parity modes might be available.
*/
typedef enum {
MB_PAR_NONE, /*!< No parity. */
MB_PAR_ODD, /*!< Odd parity. */
@@ -95,283 +73,42 @@ typedef enum {
MB_EX_GATEWAY_TGT_FAILED = 0x0B
} eMBException;
typedef eMBException( *pxMBFunctionHandler ) ( rt_uint8_t * pucFrame, rt_uint16_t * pusLength );
typedef eMBException(*pxMBFunctionHandler) (rt_uint8_t * pucFrame, rt_uint16_t * pusLength);
eMBException prveMBError2Exception (eMBErrorCode eErrorCode);
typedef struct {
rt_uint8_t ucFunctionCode;
rt_uint8_t ucFunctionCode;
pxMBFunctionHandler pxHandler;
} xMBFunctionHandler;
/*! \ingroup modbus
* \brief Initialize the Modbus protocol stack.
*
* This functions initializes the ASCII or RTU module and calls the
* init functions of the porting layer to prepare the hardware. Please
* note that the receiver is still disabled and no Modbus frames are
* processed until eMBEnable( ) has been called.
*
* \param eMode If ASCII or RTU mode should be used.
* \param ucSlaveAddress The slave address. Only frames sent to this
* address or to the broadcast address are processed.
* \param ucPort The port to use. E.g. 1 for COM1 on windows. This value
* is platform dependent and some ports simply choose to ignore it.
* \param ulBaudRate The baudrate. E.g. 19200. Supported baudrates depend
* on the porting layer.
* \param eParity Parity used for serial transmission.
*
* \return If no error occurs the function returns eMBErrorCode::MB_ENOERR.
* The protocol is then in the disabled state and ready for activation
* by calling eMBEnable( ). Otherwise one of the following error codes
* is returned:
* - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid
* slave addresses are in the range 1 - 247.
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
*/
eMBErrorCode eMBInit(rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort,
eMBErrorCode eMBInit (rt_uint8_t ucSlaveAddress, rt_uint8_t ucPort,
rt_uint32_t ulBaudRate, eMBParity eParity );
/*! \ingroup modbus
* \brief Release resources used by the protocol stack.
*
* This function disables the Modbus protocol stack and release all
* hardware resources. It must only be called when the protocol stack
* is disabled.
*
* \note Note all ports implement this function. A port which wants to
* get an callback must define the macro MB_PORT_HAS_CLOSE to 1.
*
* \return If the resources where released it return eMBErrorCode::MB_ENOERR.
* If the protocol stack is not in the disabled state it returns
* eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBClose( void );
eMBErrorCode eMBClose (void);
/*! \ingroup modbus
* \brief Enable the Modbus protocol stack.
*
* This function enables processing of Modbus frames. Enabling the protocol
* stack is only possible if it is in the disabled state.
*
* \return If the protocol stack is now in the state enabled it returns
* eMBErrorCode::MB_ENOERR. If it was not in the disabled state it
* return eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBEnable( void );
eMBErrorCode eMBEnable (void);
/*! \ingroup modbus
* \brief Disable the Modbus protocol stack.
*
* This function disables processing of Modbus frames.
*
* \return If the protocol stack has been disabled it returns
* eMBErrorCode::MB_ENOERR. If it was not in the enabled state it returns
* eMBErrorCode::MB_EILLSTATE.
*/
eMBErrorCode eMBDisable( void );
eMBErrorCode eMBDisable (void);
/*! \ingroup modbus
* \brief The main pooling loop of the Modbus protocol stack.
*
* This function must be called periodically. The timer interval required
* is given by the application dependent Modbus slave timeout. Internally the
* function calls xMBPortEventGet() and waits for an event from the receiver or
* transmitter state machines.
*
* \return If the protocol stack is not in the enabled state the function
* returns eMBErrorCode::MB_EILLSTATE. Otherwise it returns
* eMBErrorCode::MB_ENOERR.
*/
eMBErrorCode eMBPoll( void );
eMBErrorCode eMBPoll (void);
/*! \ingroup modbus
* \brief Configure the slave id of the device.
*
* This function should be called when the Modbus function <em>Report Slave ID</em>
* is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ).
*
* \param ucSlaveID Values is returned in the <em>Slave ID</em> byte of the
* <em>Report Slave ID</em> response.
* \param xIsRunning If TRUE the <em>Run Indicator Status</em> byte is set to 0xFF.
* otherwise the <em>Run Indicator Status</em> is 0x00.
* \param pucAdditional Values which should be returned in the <em>Additional</em>
* bytes of the <em> Report Slave ID</em> response.
* \param usAdditionalLen Length of the buffer <code>pucAdditonal</code>.
*
* \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in
* mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise
* it returns eMBErrorCode::MB_ENOERR.
*/
eMBErrorCode eMBSetSlaveID( rt_uint8_t ucSlaveID, rt_uint8_t xIsRunning,
rt_uint8_t const *pucAdditional, rt_uint16_t usAdditionalLen );
eMBErrorCode eMBSetSlaveID (rt_uint8_t ucSlaveID, rt_uint8_t xIsRunning,
rt_uint8_t const *pucAdditional, rt_uint16_t usAdditionalLen);
/*! \ingroup modbus
* \brief Registers a callback handler for a given function code.
*
* This function registers a new callback handler for a given function code.
* The callback handler supplied is responsible for interpreting the Modbus PDU and
* the creation of an appropriate response. In case of an error it should return
* one of the possible Modbus exceptions which results in a Modbus exception frame
* sent by the protocol stack.
*
* \param ucFunctionCode The Modbus function code for which this handler should
* be registers. Valid function codes are in the range 1 to 127.
* \param pxHandler The function handler which should be called in case
* such a frame is received. If \c NULL a previously registered function handler
* for this function code is removed.
*
* \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
* more resources are available it returns eMBErrorCode::MB_ENORES. In this
* case the values in mbconfig.h should be adjusted. If the argument was not
* valid it returns eMBErrorCode::MB_EINVAL.
*/
eMBErrorCode eMBRegisterCB( rt_uint8_t ucFunctionCode, pxMBFunctionHandler pxHandler );
eMBErrorCode eMBRegisterCB (rt_uint8_t ucFunctionCode, pxMBFunctionHandler pxHandler);
/* ----------------------- Callback -----------------------------------------*/
eMBErrorCode eMBRegInputCB (rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress, rt_uint16_t usNRegs);
/*! \defgroup modbus_registers Modbus Registers
* \code #include "mb.h" \endcode
* The protocol stack does not internally allocate any memory for the
* registers. This makes the protocol stack very small and also usable on
* low end targets. In addition the values don't have to be in the memory
* and could for example be stored in a flash.<br>
* Whenever the protocol stack requires a value it calls one of the callback
* function with the register address and the number of registers to read
* as an argument. The application should then read the actual register values
* (for example the ADC voltage) and should store the result in the supplied
* buffer.<br>
* If the protocol stack wants to update a register value because a write
* register function was received a buffer with the new register values is
* passed to the callback function. The function should then use these values
* to update the application register values.
*/
eMBErrorCode eMBRegHoldingCB (rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNRegs, eMBRegisterMode eMode);
/*! \ingroup modbus_registers
* \brief Callback function used if the value of a <em>Input Register</em>
* is required by the protocol stack. The starting register address is given
* by \c usAddress and the last register is given by <tt>usAddress +
* usNRegs - 1</tt>.
*
* \param pucRegBuffer A buffer where the callback function should write
* the current value of the modbus registers to.
* \param usAddress The starting address of the register. Input registers
* are in the range 1 - 65535.
* \param usNRegs Number of registers the callback function must supply.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application can not supply values
* for registers within this range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response.
* - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
* currently not available and the application dependent response
* timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
* exception is sent as a response.
* - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
* a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
*/
eMBErrorCode eMBRegInputCB( rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNRegs );
eMBErrorCode eMBRegCoilsCB (rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNCoils, eMBRegisterMode eMode);
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Holding Register</em> value is
* read or written by the protocol stack. The starting register address
* is given by \c usAddress and the last register is given by
* <tt>usAddress + usNRegs - 1</tt>.
*
* \param pucRegBuffer If the application registers values should be updated the
* buffer points to the new registers values. If the protocol stack needs
* to now the current values the callback function should write them into
* this buffer.
* \param usAddress The starting address of the register.
* \param usNRegs Number of registers to read or write.
* \param eMode If eMBRegisterMode::MB_REG_WRITE the application register
* values should be updated from the values in the buffer. For example
* this would be the case when the Modbus master has issued an
* <b>WRITE SINGLE REGISTER</b> command.
* If the value eMBRegisterMode::MB_REG_READ the application should copy
* the current values into the buffer \c pucRegBuffer.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application can not supply values
* for registers within this range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response.
* - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
* currently not available and the application dependent response
* timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
* exception is sent as a response.
* - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
* a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
*/
eMBErrorCode eMBRegHoldingCB( rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNRegs, eMBRegisterMode eMode );
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Coil Register</em> value is
* read or written by the protocol stack. If you are going to use
* this function you might use the functions xMBUtilSetBits( ) and
* xMBUtilGetBits( ) for working with bitfields.
*
* \param pucRegBuffer The bits are packed in bytes where the first coil
* starting at address \c usAddress is stored in the LSB of the
* first byte in the buffer <code>pucRegBuffer</code>.
* If the buffer should be written by the callback function unused
* coil values (I.e. if not a multiple of eight coils is used) should be set
* to zero.
* \param usAddress The first coil number.
* \param usNCoils Number of coil values requested.
* \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should
* be updated from the values supplied in the buffer \c pucRegBuffer.
* If eMBRegisterMode::MB_REG_READ the application should store the current
* values in the buffer \c pucRegBuffer.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application does not map an coils
* within the requested address range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
* - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
* currently not available and the application dependent response
* timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
* exception is sent as a response.
* - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
* a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
*/
eMBErrorCode eMBRegCoilsCB( rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNCoils, eMBRegisterMode eMode );
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Input Discrete Register</em> value is
* read by the protocol stack.
*
* If you are going to use his function you might use the functions
* xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields.
*
* \param pucRegBuffer The buffer should be updated with the current
* coil values. The first discrete input starting at \c usAddress must be
* stored at the LSB of the first byte in the buffer. If the requested number
* is not a multiple of eight the remaining bits should be set to zero.
* \param usAddress The starting address of the first discrete input.
* \param usNDiscrete Number of discrete input values.
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If no such discrete inputs exists.
* In this case a <b>ILLEGAL DATA ADDRESS</b> exception frame is sent
* as a response.
* - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
* currently not available and the application dependent response
* timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
* exception is sent as a response.
* - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
* a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
*/
eMBErrorCode eMBRegDiscreteCB( rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNDiscrete );
eMBErrorCode eMBRegDiscreteCB (rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
rt_uint16_t usNDiscrete);
/*!
* Constants which defines the format of a modbus frame. The example is
@@ -403,17 +140,50 @@ eMBErrorCode eMBRegDiscreteCB( rt_uint8_t * pucRegBuffer, rt_uint16_t usAddress,
#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */
#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */
typedef void ( *pvMBFrameStart ) ( void );
#define MB_PDU_FUNC_READ_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_WRITE_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_READWRITE_READ_ADDR_OFF (MB_PDU_DATA_OFF)
typedef void ( *pvMBFrameStop ) ( void );
typedef eMBErrorCode( *peMBFrameReceive ) ( rt_uint8_t * pucRcvAddress,
rt_uint8_t ** pucFrame, rt_uint16_t * pusLength );
#define MB_PDU_FUNC_READ_DISCCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_READ_REGCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_READ_COILCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_VALUE_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF (MB_PDU_DATA_OFF + 4)
#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF (MB_PDU_DATA_OFF + 5)
typedef eMBErrorCode( *peMBFrameSend ) ( rt_uint8_t slaveAddress,
const rt_uint8_t * pucFrame, rt_uint16_t usLength );
#define MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF (MB_PDU_DATA_OFF + 4)
#define MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF (MB_PDU_DATA_OFF + 6)
#define MB_PDU_FUNC_READWRITE_BYTECNT_OFF (MB_PDU_DATA_OFF + 8)
#define MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF (MB_PDU_DATA_OFF + 9)
typedef void( *pvMBFrameClose ) ( void );
#define MB_PDU_FUNC_READ_SIZE (4)
#define MB_PDU_FUNC_WRITE_SIZE (4)
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN (5)
#define MB_PDU_FUNC_READWRITE_SIZE_MIN (9)
#define MB_PDU_FUNC_READ_DISCCNT_MAX (0x07D0)
#define MB_PDU_FUNC_READ_COILCNT_MAX (0x07D0)
#define MB_PDU_FUNC_READ_REGCNT_MAX (0x007D)
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX (0x0078)
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX (0x07B0)
typedef void (*pvMBFrameStart) (void);
typedef void (*pvMBFrameStop) (void);
typedef eMBErrorCode(*peMBFrameReceive ) (rt_uint8_t * pucRcvAddress,
rt_uint8_t ** pucFrame, rt_uint16_t * pusLength);
typedef eMBErrorCode(*peMBFrameSend) (rt_uint8_t slaveAddress,
const rt_uint8_t * pucFrame, rt_uint16_t usLength);
typedef void(*pvMBFrameClose) (void);
#ifdef __cplusplus
}
+8 -8
View File
@@ -51,19 +51,19 @@ static const rt_uint8_t aucCRCLo[] = {
0x41, 0x81, 0x80, 0x40
};
rt_uint16_t usMBCRC16( rt_uint8_t * pucFrame, rt_uint16_t usLen )
rt_uint16_t usMBCRC16 (rt_uint8_t * pucFrame, rt_uint16_t usLen)
{
rt_uint8_t ucCRCHi = 0xFF;
rt_uint8_t ucCRCLo = 0xFF;
int iIndex;
rt_uint8_t ucCRCHi = 0xFF;
rt_uint8_t ucCRCLo = 0xFF;
int iIndex;
while( usLen-- )
{
while ( usLen-- ) {
iIndex = ucCRCLo ^ *( pucFrame++ );
ucCRCLo = ( rt_uint8_t )( ucCRCHi ^ aucCRCHi[iIndex] );
ucCRCLo = (rt_uint8_t)( ucCRCHi ^ aucCRCHi[iIndex] );
ucCRCHi = aucCRCLo[iIndex];
}
return ( rt_uint16_t )( ucCRCHi << 8 | ucCRCLo );
return (rt_uint16_t)( ucCRCHi << 8 | ucCRCLo );
}
+1 -1
View File
@@ -2,7 +2,7 @@
#ifndef __MB_CRC_H__
#define __MB_CRC_H__
rt_uint16_t usMBCRC16( rt_uint8_t * pucFrame, rt_uint16_t usLen );
extern rt_uint16_t usMBCRC16 (rt_uint8_t * pucFrame, rt_uint16_t usLen);
#endif
+11 -10
View File
@@ -2,30 +2,30 @@
#include "mb.h"
#include "mbport.h"
static struct rt_event xSlaveOsEvent;
static struct rt_event xSlaveOsEvent;
rt_uint8_t xMBPortEventInit( void )
rt_uint8_t xMBPortEventInit (void)
{
rt_event_init(&xSlaveOsEvent,"slave event",RT_IPC_FLAG_PRIO);
return TRUE;
}
rt_uint8_t xMBPortEventPost( eMBEventType eEvent )
rt_uint8_t xMBPortEventPost (eMBEventType eEvent)
{
rt_event_send(&xSlaveOsEvent, eEvent);
return TRUE;
}
rt_uint8_t xMBPortEventGet( eMBEventType * eEvent )
rt_uint8_t xMBPortEventGet (eMBEventType * eEvent)
{
rt_uint32_t recvedEvent;
/* waiting forever OS event */
rt_event_recv(&xSlaveOsEvent,
EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
&recvedEvent);
switch (recvedEvent)
{
EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
&recvedEvent);
switch (recvedEvent) {
case EV_READY:
*eEvent = EV_READY;
break;
@@ -39,6 +39,7 @@ rt_uint8_t xMBPortEventGet( eMBEventType * eEvent )
*eEvent = EV_FRAME_SENT;
break;
}
return TRUE;
}
+549
View File
@@ -0,0 +1,549 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_FUNC_OTHER_REP_SLAVEID_BUF (32)
static rt_uint8_t ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF];
static rt_uint16_t usMBSlaveIDLen;
eMBErrorCode eMBSetSlaveID (rt_uint8_t ucSlaveID, rt_uint8_t xIsRunning,
rt_uint8_t const *pucAdditional, rt_uint16_t usAdditionalLen)
{
eMBErrorCode eStatus = MB_ENOERR;
/* the first byte and second byte in the buffer is reserved for
* the parameter ucSlaveID and the running flag. The rest of
* the buffer is available for additional data. */
if (usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF) {
usMBSlaveIDLen = 0;
ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;
ucMBSlaveID[usMBSlaveIDLen++] = (rt_uint8_t)(xIsRunning ? 0xFF : 0x00);
if (usAdditionalLen > 0) {
memcpy(&ucMBSlaveID[usMBSlaveIDLen], pucAdditional, (size_t)usAdditionalLen);
usMBSlaveIDLen += usAdditionalLen;
}
} else {
eStatus = MB_ENORES;
}
return eStatus;
}
eMBException eMBFuncReportSlaveID (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
memcpy(&pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], (size_t)usMBSlaveIDLen);
*usLen = (rt_uint16_t)(MB_PDU_DATA_OFF + usMBSlaveIDLen);
return MB_EX_NONE;
}
eMBException eMBFuncReadInputRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen == (MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN)) {
usRegAddress = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8);
usRegAddress |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1]);
usRegAddress++;
usRegCount = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8);
usRegCount |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1]);
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if ((usRegCount >= 1)
&& (usRegCount < MB_PDU_FUNC_READ_REGCNT_MAX)) {
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_INPUT_REGISTER;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = (rt_uint8_t)(usRegCount * 2);
*usLen += 1;
eRegStatus = eMBRegInputCB(pucFrameCur, usRegAddress, usRegCount);
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
} else {
*usLen += usRegCount * 2;
}
} else {
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
} else {
/* Can't be a valid read input register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen == (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)) {
usRegAddress = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8);
usRegAddress |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1]);
usRegAddress++;
/* Make callback to update the value. */
eRegStatus = eMBRegHoldingCB(&pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF], usRegAddress, 1, MB_REG_WRITE);
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
}
} else {
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteMultipleHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t ucRegByteCount;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen >= (MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + MB_PDU_SIZE_MIN)) {
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8 );
usRegCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] );
ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
if ((usRegCount >= 1) &&
(usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX) &&
(ucRegByteCount == (rt_uint8_t) (2 * usRegCount))) {
/* Make callback to update the register values. */
eRegStatus =
eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usRegCount, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
} else {
/* The response contains the function code, the starting
* address and the quantity of registers. We reuse the
* old values in the buffer because they are still valid.
*/
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
}
} else {
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
} else {
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncReadHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if ( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( rt_uint8_t ) ( usRegCount * 2 );
*usLen += 1;
/* Make callback to fill the buffer. */
eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
*usLen += usRegCount * 2;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncReadWriteMultipleHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegReadAddress;
rt_uint16_t usRegReadCount;
rt_uint16_t usRegWriteAddress;
rt_uint16_t usRegWriteCount;
rt_uint8_t ucRegWriteByteCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen >= ( MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN ) )
{
usRegReadAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U );
usRegReadAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] );
usRegReadAddress++;
usRegReadCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U );
usRegReadCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] );
usRegWriteAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U );
usRegWriteAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] );
usRegWriteAddress++;
usRegWriteCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U );
usRegWriteCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] );
ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];
if( ( usRegReadCount >= 1 ) && ( usRegReadCount <= 0x7D ) &&
( usRegWriteCount >= 1 ) && ( usRegWriteCount <= 0x79 ) &&
( ( 2 * usRegWriteCount ) == ucRegWriteByteCount ) )
{
/* Make callback to update the register values. */
eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
if( eRegStatus == MB_ENOERR )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( rt_uint8_t ) ( usRegReadCount * 2 );
*usLen += 1;
/* Make the read callback. */
eRegStatus =
eMBRegHoldingCB( pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ );
if( eRegStatus == MB_ENOERR )
{
*usLen += 2 * usRegReadCount;
}
}
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
return eStatus;
}
eMBException eMBFuncReadCoils (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint16_t usCoilCount;
rt_uint8_t ucNBytes;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen == (MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN)) {
usRegAddress = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8);
usRegAddress |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1]);
usRegAddress++;
usCoilCount = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8);
usCoilCount |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1]);
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if ((usCoilCount >= 1) &&
(usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX)) {
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_COILS;
*usLen += 1;
/* Test if the quantity of coils is a multiple of 8. If not last
* byte is only partially field with unused coils set to zero. */
if ((usCoilCount & 0x0007) != 0) {
ucNBytes = (rt_uint8_t)(usCoilCount / 8 + 1);
} else {
ucNBytes = (rt_uint8_t)(usCoilCount / 8);
}
*pucFrameCur++ = ucNBytes;
*usLen += 1;
eRegStatus = eMBRegCoilsCB(pucFrameCur, usRegAddress, usCoilCount, MB_REG_READ);
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
} else {
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen += ucNBytes;;
}
} else {
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
} else {
/* Can't be a valid read coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteCoil (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint8_t ucBuf[2];
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen == (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)) {
usRegAddress = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8);
usRegAddress |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1]);
usRegAddress++;
if ((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00) &&
((pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF) ||
(pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00))) {
ucBuf[1] = 0;
if (pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF) {
ucBuf[0] = 1;
} else {
ucBuf[0] = 0;
}
eRegStatus = eMBRegCoilsCB(&ucBuf[0], usRegAddress, 1, MB_REG_WRITE);
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
}
} else {
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
} else {
/* Can't be a valid write coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteMultipleCoils (rt_uint8_t * pucFrame, rt_uint16_t * usLen)
{
rt_uint16_t usRegAddress;
rt_uint16_t usCoilCnt;
rt_uint8_t ucByteCount;
rt_uint8_t ucByteCountVerify;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if (*usLen > (MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN)) {
usRegAddress = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8);
usRegAddress |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1]);
usRegAddress++;
usCoilCnt = (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8);
usCoilCnt |= (rt_uint16_t)(pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1]);
ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
/* Compute the number of expected bytes in the request. */
if ((usCoilCnt & 0x0007) != 0) {
ucByteCountVerify = (rt_uint8_t)(usCoilCnt / 8 + 1);
} else {
ucByteCountVerify = (rt_uint8_t)(usCoilCnt / 8);
}
if ((usCoilCnt >= 1) &&
(usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX) &&
(ucByteCountVerify == ucByteCount)) {
eRegStatus = eMBRegCoilsCB(&pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usCoilCnt, MB_REG_WRITE);
/* If an error occured convert it into a Modbus exception. */
if (eRegStatus != MB_ENOERR) {
eStatus = prveMBError2Exception(eRegStatus);
} else {
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
}
} else {
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
} else {
/* Can't be a valid write coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncReadDiscreteInputs( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usDiscreteCnt;
rt_uint8_t ucNBytes;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usDiscreteCnt = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 );
usDiscreteCnt |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usDiscreteCnt >= 1 ) &&
( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS;
*usLen += 1;
/* Test if the quantity of coils is a multiple of 8. If not last
* byte is only partially field with unused coils set to zero. */
if( ( usDiscreteCnt & 0x0007 ) != 0 )
{
ucNBytes = ( rt_uint8_t ) ( usDiscreteCnt / 8 + 1 );
}
else
{
ucNBytes = ( rt_uint8_t ) ( usDiscreteCnt / 8 );
}
*pucFrameCur++ = ucNBytes;
*usLen += 1;
eRegStatus =
eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen += ucNBytes;;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid read coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
+10 -10
View File
@@ -10,25 +10,25 @@
extern "C" {
#endif
eMBException eMBFuncReportSlaveID( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReportSlaveID (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncReadInputRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReadInputRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncReadHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReadHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncWriteHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncWriteHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncWriteMultipleHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncWriteMultipleHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncReadCoils( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReadCoils (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncWriteCoil( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncWriteCoil (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncWriteMultipleCoils( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncWriteMultipleCoils (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncReadDiscreteInputs( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReadDiscreteInputs (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
eMBException eMBFuncReadWriteMultipleHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen );
eMBException eMBFuncReadWriteMultipleHoldingRegister (rt_uint8_t * pucFrame, rt_uint16_t * usLen);
#ifdef __cplusplus
-221
View File
@@ -1,221 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
#define MB_PDU_FUNC_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READ_SIZE ( 4 )
#define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 )
#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF )
#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF )
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ( 0x07B0 )
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
eMBException eMBFuncReadCoils( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usCoilCount;
rt_uint8_t ucNBytes;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usCoilCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 );
usCoilCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usCoilCount >= 1 ) &&
( usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_COILS;
*usLen += 1;
/* Test if the quantity of coils is a multiple of 8. If not last
* byte is only partially field with unused coils set to zero. */
if( ( usCoilCount & 0x0007 ) != 0 )
{
ucNBytes = ( rt_uint8_t )( usCoilCount / 8 + 1 );
}
else
{
ucNBytes = ( rt_uint8_t )( usCoilCount / 8 );
}
*pucFrameCur++ = ucNBytes;
*usLen += 1;
eRegStatus =
eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount,
MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen += ucNBytes;;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid read coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteCoil( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint8_t ucBuf[2];
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
usRegAddress++;
if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) &&
( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) ||
( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) )
{
ucBuf[1] = 0;
if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF )
{
ucBuf[0] = 1;
}
else
{
ucBuf[0] = 0;
}
eRegStatus =
eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid write coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteMultipleCoils( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usCoilCnt;
rt_uint8_t ucByteCount;
rt_uint8_t ucByteCountVerify;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen > ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
usRegAddress++;
usCoilCnt = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 );
usCoilCnt |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] );
ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
/* Compute the number of expected bytes in the request. */
if( ( usCoilCnt & 0x0007 ) != 0 )
{
ucByteCountVerify = ( rt_uint8_t )( usCoilCnt / 8 + 1 );
}
else
{
ucByteCountVerify = ( rt_uint8_t )( usCoilCnt / 8 );
}
if( ( usCoilCnt >= 1 ) &&
( usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ) &&
( ucByteCountVerify == ucByteCount ) )
{
eRegStatus =
eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usCoilCnt, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid write coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
-92
View File
@@ -1,92 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
#define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READ_SIZE ( 4 )
#define MB_PDU_FUNC_READ_DISCCNT_MAX ( 0x07D0 )
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
eMBException eMBFuncReadDiscreteInputs( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usDiscreteCnt;
rt_uint8_t ucNBytes;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usDiscreteCnt = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 );
usDiscreteCnt |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usDiscreteCnt >= 1 ) &&
( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS;
*usLen += 1;
/* Test if the quantity of coils is a multiple of 8. If not last
* byte is only partially field with unused coils set to zero. */
if( ( usDiscreteCnt & 0x0007 ) != 0 )
{
ucNBytes = ( rt_uint8_t ) ( usDiscreteCnt / 8 + 1 );
}
else
{
ucNBytes = ( rt_uint8_t ) ( usDiscreteCnt / 8 );
}
*pucFrameCur++ = ucNBytes;
*usLen += 1;
eRegStatus =
eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting address
* and the quantity of registers. We reuse the old values in the
* buffer because they are still valid. */
*usLen += ucNBytes;;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid read coil register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
-257
View File
@@ -1,257 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
#define MB_PDU_FUNC_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READ_SIZE ( 4 )
#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ( 0x0078 )
#define MB_PDU_FUNC_READWRITE_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
#define MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 4 )
#define MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF ( MB_PDU_DATA_OFF + 6 )
#define MB_PDU_FUNC_READWRITE_BYTECNT_OFF ( MB_PDU_DATA_OFF + 8 )
#define MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF ( MB_PDU_DATA_OFF + 9 )
#define MB_PDU_FUNC_READWRITE_SIZE_MIN ( 9 )
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
eMBException eMBFuncWriteHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
usRegAddress++;
/* Make callback to update the value. */
eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
usRegAddress, 1, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
}
else
{
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncWriteMultipleHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t ucRegByteCount;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen >= ( MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8 );
usRegCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] );
ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
if( ( usRegCount >= 1 ) &&
( usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ) &&
( ucRegByteCount == ( rt_uint8_t ) ( 2 * usRegCount ) ) )
{
/* Make callback to update the register values. */
eRegStatus =
eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
usRegAddress, usRegCount, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
/* The response contains the function code, the starting
* address and the quantity of registers. We reuse the
* old values in the buffer because they are still valid.
*/
*usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncReadHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( rt_uint8_t ) ( usRegCount * 2 );
*usLen += 1;
/* Make callback to fill the buffer. */
eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
*usLen += usRegCount * 2;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid request because the length is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
eMBException eMBFuncReadWriteMultipleHoldingRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegReadAddress;
rt_uint16_t usRegReadCount;
rt_uint16_t usRegWriteAddress;
rt_uint16_t usRegWriteCount;
rt_uint8_t ucRegWriteByteCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen >= ( MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN ) )
{
usRegReadAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U );
usRegReadAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] );
usRegReadAddress++;
usRegReadCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U );
usRegReadCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] );
usRegWriteAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U );
usRegWriteAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] );
usRegWriteAddress++;
usRegWriteCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U );
usRegWriteCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] );
ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];
if( ( usRegReadCount >= 1 ) && ( usRegReadCount <= 0x7D ) &&
( usRegWriteCount >= 1 ) && ( usRegWriteCount <= 0x79 ) &&
( ( 2 * usRegWriteCount ) == ucRegWriteByteCount ) )
{
/* Make callback to update the register values. */
eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
if( eRegStatus == MB_ENOERR )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( rt_uint8_t ) ( usRegReadCount * 2 );
*usLen += 1;
/* Make the read callback. */
eRegStatus =
eMBRegHoldingCB( pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ );
if( eRegStatus == MB_ENOERR )
{
*usLen += 2 * usRegReadCount;
}
}
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
return eStatus;
}
-83
View File
@@ -1,83 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
#define MB_PDU_FUNC_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
#define MB_PDU_FUNC_READ_SIZE ( 4 )
#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
#define MB_PDU_FUNC_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF )
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
eMBException eMBFuncReadInputRegister( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
rt_uint16_t usRegAddress;
rt_uint16_t usRegCount;
rt_uint8_t *pucFrameCur;
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount |= ( rt_uint16_t )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
*/
if( ( usRegCount >= 1 )
&& ( usRegCount < MB_PDU_FUNC_READ_REGCNT_MAX ) )
{
/* Set the current PDU data pointer to the beginning. */
pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
*usLen = MB_PDU_FUNC_OFF;
/* First byte contains the function code. */
*pucFrameCur++ = MB_FUNC_READ_INPUT_REGISTER;
*usLen += 1;
/* Second byte in the response contain the number of bytes. */
*pucFrameCur++ = ( rt_uint8_t )( usRegCount * 2 );
*usLen += 1;
eRegStatus =
eMBRegInputCB( pucFrameCur, usRegAddress, usRegCount );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
eStatus = prveMBError2Exception( eRegStatus );
}
else
{
*usLen += usRegCount * 2;
}
}
else
{
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
}
else
{
/* Can't be a valid read input register request because the length
* is incorrect. */
eStatus = MB_EX_ILLEGAL_DATA_VALUE;
}
return eStatus;
}
-51
View File
@@ -1,51 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#include "mb.h"
#define MB_FUNC_OTHER_REP_SLAVEID_BUF (32)
static rt_uint8_t ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF];
static rt_uint16_t usMBSlaveIDLen;
eMBErrorCode eMBSetSlaveID( rt_uint8_t ucSlaveID, rt_uint8_t xIsRunning,
rt_uint8_t const *pucAdditional, rt_uint16_t usAdditionalLen )
{
eMBErrorCode eStatus = MB_ENOERR;
/* the first byte and second byte in the buffer is reserved for
* the parameter ucSlaveID and the running flag. The rest of
* the buffer is available for additional data. */
if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF )
{
usMBSlaveIDLen = 0;
ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;
ucMBSlaveID[usMBSlaveIDLen++] = ( rt_uint8_t )( xIsRunning ? 0xFF : 0x00 );
if( usAdditionalLen > 0 )
{
memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional,
( size_t )usAdditionalLen );
usMBSlaveIDLen += usAdditionalLen;
}
}
else
{
eStatus = MB_ENORES;
}
return eStatus;
}
eMBException eMBFuncReportSlaveID( rt_uint8_t * pucFrame, rt_uint16_t * usLen )
{
memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen );
*usLen = ( rt_uint16_t )( MB_PDU_DATA_OFF + usMBSlaveIDLen );
return MB_EX_NONE;
}
+39 -45
View File
@@ -8,6 +8,9 @@
#include <assert.h>
#include <inttypes.h>
#include <rtdef.h>
#include "drv_gpio.h"
#include "mb.h"
@@ -23,56 +26,47 @@ extern "C" {
#define FALSE 0
#endif
#define RT_MODBUS_SLAVE_USE_CONTROL_PIN
#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
#define MODBUS_SLAVE_RT_CONTROL_PIN_INDEX GET_PIN(A, 8)
#endif
rt_uint8_t xMBPortEventInit (void);
rt_uint8_t xMBPortEventPost (eMBEventType eEvent);
rt_uint8_t xMBPortEventGet (eMBEventType * eEvent);
rt_uint8_t xMBPortSerialInit (rt_uint8_t ucPort, rt_uint32_t ulBaudRate,
rt_uint8_t ucDataBits, eMBParity eParity);
void vMBPortClose (void);
void xMBPortSerialClose (void);
void vMBPortSerialEnable (rt_uint8_t xRxEnable, rt_uint8_t xTxEnable);
rt_uint8_t xMBPortSerialGetByte (char * pucByte );
rt_uint8_t xMBPortSerialPutByte (char ucByte );
rt_uint8_t xMBPortTimersInit (rt_uint16_t usTimeOut50us);
void xMBPortTimersClose (void);
void vMBPortTimersEnable (void);
void vMBPortTimersDisable (void);
rt_uint8_t xMBPortEventInit( void );
extern rt_uint8_t (*pxMBFrameCBByteReceived) (void);
rt_uint8_t xMBPortEventPost( eMBEventType eEvent );
extern rt_uint8_t (*pxMBFrameCBTransmitterEmpty) (void);
rt_uint8_t xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
extern rt_uint8_t (*pxMBPortCBTimerExpired) (void);
rt_uint8_t xMBPortSerialInit( rt_uint8_t ucPort, rt_uint32_t ulBaudRate,
rt_uint8_t ucDataBits, eMBParity eParity );
void vMBPortClose( void );
void xMBPortSerialClose( void );
void vMBPortSerialEnable( rt_uint8_t xRxEnable, rt_uint8_t xTxEnable );
rt_uint8_t xMBPortSerialGetByte(char * pucByte );
rt_uint8_t xMBPortSerialPutByte(char ucByte );
rt_uint8_t xMBPortTimersInit( rt_uint16_t usTimeOut50us );
void xMBPortTimersClose( void );
void vMBPortTimersEnable( void );
void vMBPortTimersDisable( void );
/*!
* \brief Callback function for the porting layer when a new byte is
* available.
*
* Depending upon the mode this callback function is used by the RTU or
* ASCII transmission layers. In any case a call to xMBPortSerialGetByte()
* must immediately return a new character.
*
* \return <code>TRUE</code> if a event was posted to the queue because
* a new byte was received. The port implementation should wake up the
* tasks which are currently blocked on the eventqueue.
*/
extern rt_uint8_t( *pxMBFrameCBByteReceived ) ( void );
extern rt_uint8_t( *pxMBFrameCBTransmitterEmpty ) ( void );
extern rt_uint8_t( *pxMBPortCBTimerExpired ) ( void );
void EnterCriticalSection(void);
void ExitCriticalSection(void);
void EnterCriticalSection (void);
void ExitCriticalSection (void);
#ifdef __cplusplus
+5 -10
View File
@@ -101,17 +101,14 @@ rt_uint8_t xMBPortSerialInit(rt_uint8_t ucPORT, rt_uint32_t ulBaudRate,
void vMBPortSerialEnable(rt_uint8_t xRxEnable, rt_uint8_t xTxEnable)
{
rt_uint32_t recved_event;
if (xRxEnable)
{
if (xRxEnable) {
/* enable RX interrupt */
serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
/* switch 485 to receive mode */
#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_LOW);
#endif
}
else
{
} else {
/* switch 485 to transmit mode */
#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_HIGH);
@@ -119,13 +116,11 @@ void vMBPortSerialEnable(rt_uint8_t xRxEnable, rt_uint8_t xTxEnable)
/* disable RX interrupt */
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
}
if (xTxEnable)
{
if (xTxEnable) {
/* start serial transmit */
rt_event_send(&event_serial, EVENT_SERIAL_TRANS_START);
}
else
{
} else {
/* stop serial transmit */
rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0,
+14 -14
View File
@@ -8,17 +8,17 @@
#define BITS_UCHAR 8U
void xMBUtilSetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
rt_uint8_t ucNBits, rt_uint8_t ucValue )
void xMBUtilSetBits (rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
rt_uint8_t ucNBits, rt_uint8_t ucValue)
{
rt_uint16_t usWordBuf;
rt_uint16_t usMask;
rt_uint16_t usByteOffset;
rt_uint16_t usNPreBits;
rt_uint16_t usValue = ucValue;
rt_uint16_t usWordBuf;
rt_uint16_t usMask;
rt_uint16_t usByteOffset;
rt_uint16_t usNPreBits;
rt_uint16_t usValue = ucValue;
RT_ASSERT( ucNBits <= 8 );
RT_ASSERT( ( size_t )BITS_UCHAR == sizeof( rt_uint8_t ) * 8 );
RT_ASSERT(ucNBits <= 8);
RT_ASSERT((size_t)BITS_UCHAR == sizeof(rt_uint8_t) * 8);
/* Calculate byte offset for first byte containing the bit values starting
* at usBitOffset. */
@@ -46,12 +46,12 @@ void xMBUtilSetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
ucByteBuf[usByteOffset + 1] = ( rt_uint8_t )( usWordBuf >> BITS_UCHAR );
}
rt_uint8_t xMBUtilGetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset, rt_uint8_t ucNBits )
rt_uint8_t xMBUtilGetBits (rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset, rt_uint8_t ucNBits)
{
rt_uint16_t usWordBuf;
rt_uint16_t usMask;
rt_uint16_t usByteOffset;
rt_uint16_t usNPreBits;
rt_uint16_t usWordBuf;
rt_uint16_t usMask;
rt_uint16_t usByteOffset;
rt_uint16_t usNPreBits;
/* Calculate byte offset for first byte containing the bit values starting
* at usBitOffset. */
+4 -13
View File
@@ -5,16 +5,7 @@
#ifdef __cplusplus
extern "C" {
#endif
/*! \defgroup modbus_utils Utilities
*
* This module contains some utility functions which can be used by
* the application. It includes some special functions for working with
* bitfields backed by a character array buffer.
*
*/
/*! \addtogroup modbus_utils
* @{
*/
/*! \brief Function to set bits in a byte buffer.
*
* This function allows the efficient use of an array to implement bitfields.
@@ -46,8 +37,8 @@ extern "C" {
* xMBUtilSetBits( ucBits, 8, 8, 0x5A);
* \endcode
*/
void xMBUtilSetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
rt_uint8_t ucNBits, rt_uint8_t ucValues );
void xMBUtilSetBits (rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
rt_uint8_t ucNBits, rt_uint8_t ucValues);
/*! \brief Function to read bits in a byte buffer.
*
@@ -68,7 +59,7 @@ void xMBUtilSetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
* ucResult = xMBUtilGetBits( ucBits, 3, 8 );
* \endcode
*/
rt_uint8_t xMBUtilGetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset, rt_uint8_t ucNBits );
rt_uint8_t xMBUtilGetBits (rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset, rt_uint8_t ucNBits);
/*! @} */
+25 -8
View File
@@ -22,8 +22,8 @@ int chrg_north_send (rt_uint8_t *data, rt_size_t length)
rt_ssize_t ret = -1;
struct chrg_tty_t *pTTY = chrgnorth.tty;
if ((RT_NULL != pTTY)&&(RT_NULL != pTTY->dev)) {
ret = rt_device_write(pTTY->dev, 0, data, length);
if (RT_NULL != pTTY) {
ret = chrg_tty_send(pTTY, data, length);
}
return ret;
@@ -37,12 +37,24 @@ static void chrg_north_thread_entry (void *data)
return ;
}
rt_uint8_t crc8 = 0;
rt_size_t len_mq = 0, len_get = 0, len_msg = 0;
//rt_uint8_t crc8 = 0;
//rt_size_t len_mq = 0, len_get = 0, len_msg = 0;
struct chrg_tty_t *pTTY = pNOR->tty;
struct mq_msg_t msg;
//struct mq_msg_t msg;
int len = 0;
chrg_tty_set_recv_tmo(pTTY, 200);
if (chrg_tty_connect(pTTY) != RT_EOK) {
chrg_tty_destory(pTTY);
return;
}
while (1) {
len = chrg_tty_recv(pTTY, pNOR->rx_buf, sizeof(pNOR->rx_buf));
if (len > 0) {
chrg_tty_send(pTTY, pNOR->rx_buf, len);
}
/*
rt_memset(&msg, 0, sizeof(struct mq_msg_t));
len_mq = rt_mq_recv(pTTY->mq, &msg, sizeof(struct mq_msg_t), RT_WAITING_FOREVER);
if (len_mq <= 0) {
@@ -72,7 +84,7 @@ static void chrg_north_thread_entry (void *data)
pNOR->rx_len = 0;
}
}
*/
}
}
@@ -82,8 +94,13 @@ static int chrg_north_init (void)
rt_err_t ret;
struct chrg_north_t *pNOR = &chrgnorth;
pNOR->tty = &chrgtty[IDX_TTY_NORTH];
rt_memset(pNOR->rx_buf, 0, SIZE_BUF_UART);
pNOR->tty = chrg_tty_create("uart3", 2000000, 0, -1, 1);
if (RT_NULL == pNOR->tty) {
LOG_E("tty can't create.");
return -1;
}
rt_memset(pNOR->rx_buf, 0, SIZE_BUF_TTY);
ret = rt_mutex_init(&pNOR->lock, pNOR->name, RT_IPC_FLAG_FIFO);
if (ret != RT_EOK) {
+1 -1
View File
@@ -16,7 +16,7 @@ struct chrg_north_t {
struct chrg_tty_t *tty;
rt_uint16_t rx_len;
rt_uint8_t rx_buf[SIZE_BUF_UART];
rt_uint8_t rx_buf[SIZE_BUF_TTY];
struct chrg_switch_t sw[TOTAL_CHS];
};
+26 -17
View File
@@ -21,8 +21,8 @@ int chrg_south_send (rt_uint8_t *data, rt_size_t length)
rt_ssize_t ret = -1;
struct chrg_tty_t *pTTY = chrgsouth.tty;
if ((RT_NULL != pTTY)&&(RT_NULL != pTTY->dev)) {
ret = rt_device_write(pTTY->dev, 0, data, length);
if (RT_NULL != pTTY) {
ret = chrg_tty_send(pTTY, data, length);
}
return ret;
@@ -36,12 +36,24 @@ static void chrg_south_thread_entry (void *data)
return ;
}
rt_uint8_t crc8 = 0;
rt_size_t len_mq = 0, len_get = 0, len_msg = 0;
//rt_uint8_t crc8 = 0;
//rt_size_t len_mq = 0, len_get = 0, len_msg = 0;
struct chrg_tty_t *pTTY = pSOU->tty;
struct mq_msg_t msg;
//struct mq_msg_t msg;
int len = 0;
chrg_tty_set_recv_tmo(pTTY, 200);
if (chrg_tty_connect(pTTY) != RT_EOK) {
chrg_tty_destory(pTTY);
return;
}
while (1) {
len = chrg_tty_recv(pTTY, pSOU->rx_buf, sizeof(pSOU->rx_buf));
if (len > 0) {
chrg_tty_send(pTTY, pSOU->rx_buf, len);
}
/*
rt_memset(&msg, 0, sizeof(struct mq_msg_t));
len_mq = rt_mq_recv(pTTY->mq, &msg, sizeof(struct mq_msg_t), RT_WAITING_FOREVER);
if (len_mq <= 0) {
@@ -71,7 +83,7 @@ static void chrg_south_thread_entry (void *data)
pSOU->rx_len = 0;
}
}
*/
}
}
@@ -81,8 +93,13 @@ static int chrg_south_init (void)
rt_err_t ret;
struct chrg_south_t *pSOU = &chrgsouth;
pSOU->tty = &chrgtty[IDX_TTY_SOUTH];
rt_memset(pSOU->rx_buf, 0, SIZE_BUF_UART);
pSOU->tty = chrg_tty_create("uart6", 2000000, 0, -1, 1);
if (RT_NULL == pSOU->tty) {
LOG_E("tty can't create.");
return -1;
}
rt_memset(pSOU->rx_buf, 0, SIZE_BUF_TTY);
ret = rt_mutex_init(&pSOU->lock, pSOU->name, RT_IPC_FLAG_FIFO);
if (ret != RT_EOK) {
@@ -106,15 +123,7 @@ INIT_APP_EXPORT(chrg_south_init);
static int south_send(rt_uint8_t argc, char **argv)
{
rt_err_t ret;
struct chrg_south_t *pSOU = &chrgsouth;
struct chrg_tty_t *pTTY = pSOU->tty;
if (RT_NULL != pTTY->dev) {
ret = rt_device_write(pTTY->dev, 0, "1234567890abcdef", 16);
}
return ret;
return chrg_south_send("1234567890abcdef", 16);
}
+1 -1
View File
@@ -15,7 +15,7 @@ struct chrg_south_t {
struct chrg_tty_t *tty;
rt_uint16_t rx_len;
rt_uint8_t rx_buf[SIZE_BUF_UART];
rt_uint8_t rx_buf[SIZE_BUF_TTY];
struct chrg_switch_t sw[TOTAL_SOUTH_CHS];
};
+3 -1
View File
@@ -1,10 +1,12 @@
#include <string.h>
#include <rtthread.h>
#include "chrg_pkg.h"
#include "chrg_utils.h"
int chrg_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_in,
rt_uint8_t len_in, rt_uint8_t *data_out, rt_uint8_t *len_out)
rt_uint8_t len_in, rt_uint8_t *data_out, rt_uint16_t *len_out)
{
if ((RT_NULL == data_in)||(RT_NULL == data_out)||(0 == len_in)) {
return -1;
+1 -1
View File
@@ -7,7 +7,7 @@
#include "chrg_def.h"
extern int chrg_pkg_encode (eIDX_ID id, rt_uint8_t cmd, rt_uint8_t *data_in,
rt_uint8_t len_in, rt_uint8_t *data_out, rt_uint8_t *len_out);
rt_uint8_t len_in, rt_uint8_t *data_out, rt_uint16_t *len_out);
extern int chrg_pkg_decode (eIDX_ID id, rt_uint8_t *data);
+2 -2
View File
@@ -3,12 +3,12 @@
#include "chrg_source.h"
#include "chrg_north.h"
#include "chrg_pkg.h"
#include "chrg_utils.h"
int source_get_vc (rt_uint16_t vol, rt_uint16_t cur)
{
rt_size_t len = 0;
rt_uint16_t len = 0;
rt_uint8_t data[12] = {0};
rt_uint8_t frame[16] = {0};
+191 -211
View File
@@ -16,7 +16,7 @@
<TargetCommonOption>
<Device>STM32F405RG</Device>
<Vendor>STMicroelectronics</Vendor>
<PackID>Keil.STM32F4xx_DFP.2.17.1</PackID>
<PackID>Keil.STM32F4xx_DFP.3.1.0</PackID>
<PackURL>https://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) CPUTYPE("Cortex-M4") FPU2</Cpu>
<FlashUtilSpec></FlashUtilSpec>
@@ -337,9 +337,9 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>__STDC_LIMIT_MACROS, __RTTHREAD__, STM32F405xx, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_LIBC, RT_USING_ARMLIBC, USE_HAL_DRIVER</Define>
<Define>__CLK_TCK=RT_TICK_PER_SECOND, __STDC_LIMIT_MACROS, __RTTHREAD__, RT_USING_LIBC, STM32F405xx, USE_HAL_DRIVER, RT_USING_ARMLIBC</Define>
<Undefine></Undefine>
<IncludePath>..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers\config;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\drivers\include;..\..\rt-thread\libcpu\arm\common;..\..\rt-thread\components\libc\compilers\common\extension;board\ports;..\..\rt-thread\components\libc\posix\io\epoll;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\libc\posix\io\eventfd;applications\mb;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\libc\compilers\common\include;..\..\rt-thread\components\finsh;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers;..\..\libs\cmsis-core\Include;..\..\rt-thread\components\libc\compilers\common\extension\fcntl\octal;..\..\rt-thread\components\drivers\phy;..\..\rt-thread\components\libc\posix\io\poll;applications\bsp;..\..\rt-thread\components\drivers\include;board\CubeMX_Config\Inc;..\..\libs\stm32f4\STM32F4_CMSIS\Include;..\..\rt-thread\components\drivers\include;..\..\rt-thread\libcpu\arm\cortex-m4;..\..\rt-thread\include;applications\utils;.;..\..\rt-thread\components\drivers\smp_call;applications\thread;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\drivers\include;applications;board;..\..\libs\stm32f4\STM32F4_HAL\Inc;..\..\rt-thread\components\fal\inc;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers\drv_flash;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers;..\..\libs\stm32f4\STM32F4_HAL\Inc\Legacy;..\..\rt-thread\components\libc\posix\ipc</IncludePath>
<IncludePath>board\ports;applications\utils;..\..\libs\stm32f4\STM32F4_CMSIS\Include;..\..\rt-thread\components\fal\inc;..\..\rt-thread\components\libc\compilers\common\extension\fcntl\octal;..\..\rt-thread\components\drivers\include;..\..\libs\stm32f4\STM32F4_HAL\Inc\Legacy;..\..\rt-thread\components\finsh;..\..\rt-thread\components\drivers\include;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers\config;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\libc\compilers\common\include;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\libc\posix\io\eventfd;..\..\rt-thread\components\drivers\include;..\..\rt-thread\components\drivers\include;.;..\..\rt-thread\components\drivers\phy;..\..\rt-thread\components\libc\posix\io\poll;..\..\libs\stm32f4\STM32F4_HAL\Inc;applications\bsp;..\..\rt-thread\components\drivers\smp_call;applications\mb;..\..\rt-thread\libcpu\arm\cortex-m4;..\..\rt-thread\components\drivers\include;..\..\libs\cmsis-core\Include;..\..\rt-thread\components\libc\posix\ipc;..\..\rt-thread\components\libc\posix\io\epoll;..\..\rt-thread\components\drivers\include;applications;board;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers;applications\thread;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers;..\..\rt-thread\components\libc\compilers\common\extension;..\..\rt-thread\include;board\CubeMX_Config\Inc;..\..\rt-thread\components\drivers\include;..\..\rt-thread\libcpu\arm\common;..\..\rt-thread\bsp\stm32\libraries\HAL_Drivers\drivers\drv_flash</IncludePath>
</VariousControls>
</Cads>
<Aads>
@@ -393,6 +393,41 @@
<Group>
<GroupName>Applications/bsp</GroupName>
<Files>
<File>
<FileName>chrg_fal.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_fal.c</FilePath>
</File>
<File>
<FileName>chrg_clk.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_clk.c</FilePath>
</File>
<File>
<FileName>chrg_wdt.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_wdt.c</FilePath>
</File>
<File>
<FileName>chrg_intr.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_intr.c</FilePath>
</File>
<File>
<FileName>chrg_switch.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_switch.c</FilePath>
</File>
<File>
<FileName>chrg_tty.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_tty.c</FilePath>
</File>
<File>
<FileName>chrg_can.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_can.c</FilePath>
</File>
<File>
<FileName>chrg_i2c.c</FileName>
<FileType>1</FileType>
@@ -408,155 +443,95 @@
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_pin.c</FilePath>
</File>
<File>
<FileName>chrg_clk.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_clk.c</FilePath>
</File>
<File>
<FileName>chrg_fal.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_fal.c</FilePath>
</File>
<File>
<FileName>chrg_switch.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_switch.c</FilePath>
</File>
<File>
<FileName>chrg_intr.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_intr.c</FilePath>
</File>
<File>
<FileName>chrg_can.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_can.c</FilePath>
</File>
<File>
<FileName>chrg_wdt.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_wdt.c</FilePath>
</File>
<File>
<FileName>chrg_tty.c</FileName>
<FileType>1</FileType>
<FilePath>applications\bsp\chrg_tty.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Applications/mb</GroupName>
<Files>
<File>
<FileName>mbfunccoils.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfunccoils.c</FilePath>
</File>
<File>
<FileName>mbrtu.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbrtu.c</FilePath>
</File>
<File>
<FileName>mbfuncholding.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfuncholding.c</FilePath>
</File>
<File>
<FileName>mb.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mb.c</FilePath>
</File>
<File>
<FileName>mbfuncother.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfuncother.c</FilePath>
</File>
<File>
<FileName>mbutils.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbutils.c</FilePath>
</File>
<File>
<FileName>mbserial.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbserial.c</FilePath>
</File>
<File>
<FileName>mbcrc.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbcrc.c</FilePath>
</File>
<File>
<FileName>mbfuncinput.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfuncinput.c</FilePath>
</File>
<File>
<FileName>mbfuncdisc.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfuncdisc.c</FilePath>
</File>
<File>
<FileName>mbport.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbport.c</FilePath>
</File>
<File>
<FileName>mbtimer.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbtimer.c</FilePath>
</File>
<File>
<FileName>mbport.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbport.c</FilePath>
</File>
<File>
<FileName>mb.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mb.c</FilePath>
</File>
<File>
<FileName>mbserial.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbserial.c</FilePath>
</File>
<File>
<FileName>mbevent.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbevent.c</FilePath>
</File>
<File>
<FileName>mbutils.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbutils.c</FilePath>
</File>
<File>
<FileName>mbcrc.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbcrc.c</FilePath>
</File>
<File>
<FileName>mbfunc.c</FileName>
<FileType>1</FileType>
<FilePath>applications\mb\mbfunc.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Applications/thread</GroupName>
<Files>
<File>
<FileName>chrg_south.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_south.c</FilePath>
</File>
<File>
<FileName>chrg_lcd.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_lcd.c</FilePath>
</File>
<File>
<FileName>chrg_north.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_north.c</FilePath>
</File>
<File>
<FileName>chrg_comm.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_comm.c</FilePath>
</File>
<File>
<FileName>chrg_south.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_south.c</FilePath>
</File>
<File>
<FileName>chrg_north.c</FileName>
<FileType>1</FileType>
<FilePath>applications\thread\chrg_north.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Applications/utils</GroupName>
<Files>
<File>
<FileName>chrg_source.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_source.c</FilePath>
</File>
<File>
<FileName>chrg_sink.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_sink.c</FilePath>
</File>
<File>
<FileName>chrg_mb.c</FileName>
<FileName>chrg_source.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_mb.c</FilePath>
<FilePath>applications\utils\chrg_source.c</FilePath>
</File>
<File>
<FileName>chrg_pkg.c</FileName>
@@ -564,15 +539,20 @@
<FilePath>applications\utils\chrg_pkg.c</FilePath>
</File>
<File>
<FileName>chrg_pcf8574.c</FileName>
<FileName>chrg_mb.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_pcf8574.c</FilePath>
<FilePath>applications\utils\chrg_mb.c</FilePath>
</File>
<File>
<FileName>chrg_utils.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_utils.c</FilePath>
</File>
<File>
<FileName>chrg_pcf8574.c</FileName>
<FileType>1</FileType>
<FilePath>applications\utils\chrg_pcf8574.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -1691,51 +1671,51 @@
<Group>
<GroupName>Fal</GroupName>
<Files>
<File>
<FileName>fal_rtt.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\fal\src\fal_rtt.c</FilePath>
</File>
<File>
<FileName>fal_partition.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\fal\src\fal_partition.c</FilePath>
</File>
<File>
<FileName>fal_flash.c</FileName>
<FileName>fal_rtt.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\fal\src\fal_flash.c</FilePath>
<FilePath>..\..\rt-thread\components\fal\src\fal_rtt.c</FilePath>
</File>
<File>
<FileName>fal.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\fal\src\fal.c</FilePath>
</File>
<File>
<FileName>fal_flash.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\fal\src\fal_flash.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Finsh</GroupName>
<Files>
<File>
<FileName>msh_parse.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\msh_parse.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\cmd.c</FilePath>
</File>
<File>
<FileName>shell.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\shell.c</FilePath>
</File>
<File>
<FileName>msh_parse.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\msh_parse.c</FilePath>
</File>
<File>
<FileName>msh.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\msh.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\components\finsh\cmd.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -2190,9 +2170,9 @@
</FileOption>
</File>
<File>
<FileName>mem.c</FileName>
<FileName>memheap.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\mem.c</FilePath>
<FilePath>..\..\rt-thread\src\memheap.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
@@ -2587,19 +2567,9 @@
<GroupName>klibc</GroupName>
<Files>
<File>
<FileName>kstring.c</FileName>
<FileName>kstdio.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\kstring.c</FilePath>
</File>
<File>
<FileName>rt_vsnprintf_tiny.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\rt_vsnprintf_tiny.c</FilePath>
</File>
<File>
<FileName>rt_vsscanf.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\rt_vsscanf.c</FilePath>
<FilePath>..\..\rt-thread\src\klibc\kstdio.c</FilePath>
</File>
<File>
<FileName>kerrno.c</FileName>
@@ -2607,9 +2577,19 @@
<FilePath>..\..\rt-thread\src\klibc\kerrno.c</FilePath>
</File>
<File>
<FileName>kstdio.c</FileName>
<FileName>kstring.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\kstdio.c</FilePath>
<FilePath>..\..\rt-thread\src\klibc\kstring.c</FilePath>
</File>
<File>
<FileName>rt_vsscanf.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\rt_vsscanf.c</FilePath>
</File>
<File>
<FileName>rt_vsnprintf_tiny.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\rt-thread\src\klibc\rt_vsnprintf_tiny.c</FilePath>
</File>
</Files>
</Group>
@@ -2662,14 +2642,24 @@
<GroupName>STM32F4-HAL</GroupName>
<Files>
<File>
<FileName>stm32f4xx_hal_flash_ramfunc.c</FileName>
<FileName>stm32f4xx_hal_pwr.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash_ramfunc.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_pwr.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_can.c</FileName>
<FileName>stm32f4xx_hal_flash_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_can.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_dma_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_dma_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_usart.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_usart.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_cortex.c</FileName>
@@ -2677,29 +2667,9 @@
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_cortex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_wwdg.c</FileName>
<FileName>stm32f4xx_hal_iwdg.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_wwdg.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_uart.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_uart.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_pwr_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_pwr_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_lptim.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_lptim.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_crc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_crc.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_iwdg.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_cryp.c</FileName>
@@ -2707,9 +2677,19 @@
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_cryp.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_gpio.c</FileName>
<FileName>stm32f4xx_hal_lptim.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_gpio.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_lptim.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_i2c.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_i2c.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_flash_ramfunc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash_ramfunc.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_dma.c</FileName>
@@ -2722,24 +2702,9 @@
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_cec.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_dma_ex.c</FileName>
<FileName>stm32f4xx_hal_wwdg.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_dma_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_rng.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_rng.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_i2c_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_i2c_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_rcc_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_rcc_ex.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_wwdg.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_tim_ex.c</FileName>
@@ -2747,14 +2712,34 @@
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_tim_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_flash_ex.c</FileName>
<FileName>stm32f4xx_hal_cryp_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash_ex.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_cryp_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_usart.c</FileName>
<FileName>stm32f4xx_hal_uart.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_usart.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_uart.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_gpio.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_gpio.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_i2c_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_i2c_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_flash.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_rcc_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_rcc_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_rcc.c</FileName>
@@ -2762,40 +2747,35 @@
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_rcc.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_i2c.c</FileName>
<FileName>stm32f4xx_hal_can.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_i2c.c</FilePath>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_can.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_crc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_crc.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_pwr_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_pwr_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_rng.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_rng.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_cryp_ex.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_cryp_ex.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_tim.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_tim.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_iwdg.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_iwdg.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_pwr.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_pwr.c</FilePath>
</File>
<File>
<FileName>stm32f4xx_hal_flash.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libs\stm32f4\STM32F4_HAL\Src\stm32f4xx_hal_flash.c</FilePath>
</File>
</Files>
</Group>
</Groups>
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -97,8 +97,10 @@
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_MEMHEAP
#define RT_MEMHEAP_FAST_MODE
#define RT_USING_MEMHEAP_AS_HEAP
#define RT_USING_MEMHEAP_AUTO_BINDING
#define RT_USING_HEAP
/* end of Memory Management */
#define RT_USING_DEVICE
Binary file not shown.
+65
View File
@@ -0,0 +1,65 @@
300W电源板Modbus RTU标准通讯协议指令
角色切换,默认是电子负载
1.读取当前角色信息
01 03 00 04 00 01 C5 CB
2.设置电源模式
01 06 00 04 00 01 09 CB
3.设置电子负载模式
01 06 00 04 00 02 49 CA
1.恒流恒压模式读取
01 03 00 1F 00 01 B5 CC
2.设置恒压模式
01 06 00 1F 00 01 79 CC
3.设置恒流模式
01 06 00 1F 00 02 39 CD
输入输出控制
启动: 01 06 00 1E 00 01 28 0C
停止: 01 06 00 1E 00 02 68 0D
故障复位:01 06 00 1E 00 03 A9 CD
先发送:01 06 00 29 00 00 58 02
//1V,最小被限制在3.0V,显示:3.287V;
01 06 00 2C 03 E8 A8 BC
//5V,实际显示:5.280-----------------标准电源
01 06 00 2A 13 88 A5 54
//6V,实际显示:6.280
电压指令,先发送: 电流指令:先发送:01 06 00 2B 00 00 F9 C2
01 06 00 2A 17 70 A6 16 :保护电流12A
//9V------------------------------------QC标准 //默认1A
01 06 00 2A 23 28 B1 2C //01 06 00 2C 03 E8 48 BD
//10V //2A
01 06 00 2A 27 10 B2 3E //01 06 00 2C 07 D0 4B AF
//11V //3A
01 06 00 2A 2E E0 B4 2A //01 06 00 2C 0B B8 4F 41
//12V-----------------------------------QC标准 //5A
01 06 00 2A 2E E0 B4 2A //01 06 00 2C 13 88 45 55
//15V //10A
01 06 00 2A 3A 98 BB 08 //01 06 00 2C 27 10 52 3F
//20V-----------------------------------PD标准 //11A
01 06 00 2A 4E 20 9C 7A //01 06 00 2C 2A F8 56 E1
//21V
01 06 00 2A 52 08 94 A4
//24V
01 06 00 2A 5D C0 90 C2
//28V
01 06 00 2A 6D 60 84 BA
//32V
01 06 00 2A 7D 00 89 52
//36V
01 06 00 2A 8C A0 CC BA
//42V
01 06 00 2A A4 10 D3 0E
//45V
01 06 00 2A AF C8 D4 64
//48V
01 06 00 2A BB 80 DB 52
//48.5V
01 06 00 2A BD 74 D9 75
电流: