fix mb & tty
This commit is contained in:
+7
-4
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
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 ret;
|
||||
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 ((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 (pTTY->pin < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
return ret;
|
||||
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 {
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#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_DMA_RX);
|
||||
if (RT_EOK == ret) {
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
#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_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
|
||||
|
||||
#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
|
||||
|
||||
ret = rt_device_open(pTTY->dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||
if (RT_EOK == ret) {
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
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_control(pTTY->dev, RT_DEVICE_CTRL_CONFIG, &cfg);
|
||||
if (ret != RT_EOK) {
|
||||
LOG_E("control '%s' failed.", pTTY->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
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,73 +111,61 @@ 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
@@ -196,28 +178,23 @@ eMBErrorCode eMBPoll( void )
|
||||
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;
|
||||
|
||||
|
||||
+58
-288
@@ -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,7 +73,9 @@ 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;
|
||||
@@ -103,275 +83,32 @@ typedef struct {
|
||||
} 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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
#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;
|
||||
@@ -17,8 +17,8 @@ void xMBUtilSetBits( rt_uint8_t * ucByteBuf, rt_uint16_t usBitOffset,
|
||||
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,7 +46,7 @@ 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
Binary file not shown.
@@ -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
|
||||
|
||||
电流:
|
||||
|
||||
Reference in New Issue
Block a user