fix mb & tty

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