summaryrefslogtreecommitdiff
path: root/components/net
diff options
context:
space:
mode:
authorarmink <[email protected]>2015-02-05 19:27:24 +0800
committerarmink <[email protected]>2015-02-05 19:44:25 +0800
commit2a14e4071c6aaba74a345197623ea7ebec9e7806 (patch)
tree1184752de8096599d39a90aab2b739714665234c /components/net
parentd8bbb5f1264c58c600d7f1fb1f1e95fbbfb94115 (diff)
[modbus]port modbus master and slave by rtt device framework.
Diffstat (limited to 'components/net')
-rw-r--r--components/net/freemodbus-v1.6.0/port/port.c15
-rw-r--r--components/net/freemodbus-v1.6.0/port/port.h14
-rw-r--r--components/net/freemodbus-v1.6.0/port/portevent.c38
-rw-r--r--components/net/freemodbus-v1.6.0/port/portevent_m.c206
-rw-r--r--components/net/freemodbus-v1.6.0/port/portserial.c275
-rw-r--r--components/net/freemodbus-v1.6.0/port/portserial_m.c273
-rw-r--r--components/net/freemodbus-v1.6.0/port/porttimer.c72
-rw-r--r--components/net/freemodbus-v1.6.0/port/porttimer_m.c118
-rw-r--r--components/net/freemodbus-v1.6.0/port/user_mb_app.c413
-rw-r--r--components/net/freemodbus-v1.6.0/port/user_mb_app.h60
-rw-r--r--components/net/freemodbus-v1.6.0/port/user_mb_app_m.c294
11 files changed, 1078 insertions, 700 deletions
diff --git a/components/net/freemodbus-v1.6.0/port/port.c b/components/net/freemodbus-v1.6.0/port/port.c
index 459481cc1d..527af909ac 100644
--- a/components/net/freemodbus-v1.6.0/port/port.c
+++ b/components/net/freemodbus-v1.6.0/port/port.c
@@ -1,6 +1,6 @@
/*
- * FreeModbus Libary: LPC214X Port
- * Copyright (C) 2007 Tiago Prado Lone <[email protected]>
+ * FreeModbus Libary: RT-Thread Port
+ * Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
- * File: $Id: port.c,v 1.1 2007/04/24 23:15:18 wolti Exp $
+ * File: $Id: portevent.c,v 1.60 2015/02/01 9:18:05 Armink $
*/
/* ----------------------- System includes --------------------------------*/
@@ -24,16 +24,15 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "port.h"
/* ----------------------- Variables ----------------------------------------*/
-
+static rt_base_t level;
/* ----------------------- Start implementation -----------------------------*/
void EnterCriticalSection(void)
{
- //�ر�ȫ���ж�
- __disable_irq();
+ level = rt_hw_interrupt_disable();
}
void ExitCriticalSection(void)
{
- //����ȫ���ж�
- __enable_irq();
+ rt_hw_interrupt_enable(level);
}
+
diff --git a/components/net/freemodbus-v1.6.0/port/port.h b/components/net/freemodbus-v1.6.0/port/port.h
index c79df3d887..92056116b8 100644
--- a/components/net/freemodbus-v1.6.0/port/port.h
+++ b/components/net/freemodbus-v1.6.0/port/port.h
@@ -1,6 +1,6 @@
/*
* FreeModbus Libary: BARE Port
- * Copyright (C) 2006 Christian Walter <[email protected]>
+ * Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,18 +34,9 @@
#define PR_BEGIN_EXTERN_C extern "C" {
#define PR_END_EXTERN_C }
-//TODO ��ʱ��дB13���ţ�����������ʱ��ȷ��
-#define SLAVE_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
-#define SLAVE_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
-#define MASTER_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
-#define MASTER_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
-
#define ENTER_CRITICAL_SECTION() EnterCriticalSection()
#define EXIT_CRITICAL_SECTION() ExitCriticalSection()
-void EnterCriticalSection(void);
-void ExitCriticalSection(void);
-
typedef uint8_t BOOL;
typedef unsigned char UCHAR;
@@ -65,4 +56,7 @@ typedef int32_t LONG;
#define FALSE 0
#endif
+void EnterCriticalSection(void);
+void ExitCriticalSection(void);
+
#endif
diff --git a/components/net/freemodbus-v1.6.0/port/portevent.c b/components/net/freemodbus-v1.6.0/port/portevent.c
index 86c7b5e7a5..1a881166be 100644
--- a/components/net/freemodbus-v1.6.0/port/portevent.c
+++ b/components/net/freemodbus-v1.6.0/port/portevent.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -24,35 +24,45 @@
#include "mbport.h"
/* ----------------------- Variables ----------------------------------------*/
-static eMBEventType eQueuedEvent;
-static BOOL xEventInQueue;
-
+static struct rt_event xSlaveOsEvent;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit( void )
{
- xEventInQueue = FALSE;
+ rt_event_init(&xSlaveOsEvent,"slave event",RT_IPC_FLAG_PRIO);
return TRUE;
}
BOOL
xMBPortEventPost( eMBEventType eEvent )
{
- xEventInQueue = TRUE;
- eQueuedEvent = eEvent;
+ rt_event_send(&xSlaveOsEvent, eEvent);
return TRUE;
}
BOOL
xMBPortEventGet( eMBEventType * eEvent )
{
- BOOL xEventHappened = FALSE;
-
- if( xEventInQueue )
+ 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)
{
- *eEvent = eQueuedEvent;
- xEventInQueue = FALSE;
- xEventHappened = TRUE;
+ case EV_READY:
+ *eEvent = EV_READY;
+ break;
+ case EV_FRAME_RECEIVED:
+ *eEvent = EV_FRAME_RECEIVED;
+ break;
+ case EV_EXECUTE:
+ *eEvent = EV_EXECUTE;
+ break;
+ case EV_FRAME_SENT:
+ *eEvent = EV_FRAME_SENT;
+ break;
}
- return xEventHappened;
+ return TRUE;
}
diff --git a/components/net/freemodbus-v1.6.0/port/portevent_m.c b/components/net/freemodbus-v1.6.0/port/portevent_m.c
index c78b6cbcb2..031a3b84ef 100644
--- a/components/net/freemodbus-v1.6.0/port/portevent_m.c
+++ b/components/net/freemodbus-v1.6.0/port/portevent_m.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -21,41 +21,219 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
+#include "mb_m.h"
#include "mbport.h"
+#include "port.h"
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
+#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
+/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Variables ----------------------------------------*/
-static eMBMasterEventType eMasterQueuedEvent;
-static BOOL xMasterEventInQueue;
-
+static struct rt_semaphore xMasterRunRes;
+static struct rt_event xMasterOsEvent;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortEventInit( void )
{
- xMasterEventInQueue = FALSE;
+ rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO);
return TRUE;
}
BOOL
xMBMasterPortEventPost( eMBMasterEventType eEvent )
{
- xMasterEventInQueue = TRUE;
- eMasterQueuedEvent = eEvent;
+ rt_event_send(&xMasterOsEvent, eEvent);
return TRUE;
}
BOOL
xMBMasterPortEventGet( eMBMasterEventType * eEvent )
{
- BOOL xEventHappened = FALSE;
+ rt_uint32_t recvedEvent;
+ /* waiting forever OS event */
+ rt_event_recv(&xMasterOsEvent,
+ EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
+ EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
+ &recvedEvent);
+ /* the enum type couldn't convert to int type */
+ switch (recvedEvent)
+ {
+ case EV_MASTER_READY:
+ *eEvent = EV_MASTER_READY;
+ break;
+ case EV_MASTER_FRAME_RECEIVED:
+ *eEvent = EV_MASTER_FRAME_RECEIVED;
+ break;
+ case EV_MASTER_EXECUTE:
+ *eEvent = EV_MASTER_EXECUTE;
+ break;
+ case EV_MASTER_FRAME_SENT:
+ *eEvent = EV_MASTER_FRAME_SENT;
+ break;
+ case EV_MASTER_ERROR_PROCESS:
+ *eEvent = EV_MASTER_ERROR_PROCESS;
+ break;
+ }
+ return TRUE;
+}
+/**
+ * This function is initialize the OS resource for modbus master.
+ * Note:The resource is define by OS.If you not use OS this function can be empty.
+ *
+ */
+void vMBMasterOsResInit( void )
+{
+ rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO);
+}
+
+/**
+ * This function is take Mobus Master running resource.
+ * Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE.
+ *
+ * @param lTimeOut the waiting time.
+ *
+ * @return resource taked result
+ */
+BOOL xMBMasterRunResTake( LONG lTimeOut )
+{
+ /*If waiting time is -1 .It will wait forever */
+ return rt_sem_take(&xMasterRunRes, lTimeOut) ? FALSE : TRUE ;
+}
+
+/**
+ * This function is release Mobus Master running resource.
+ * Note:The resource is define by Operating System.If you not use OS this function can be empty.
+ *
+ */
+void vMBMasterRunResRelease( void )
+{
+ /* release resource */
+ rt_sem_release(&xMasterRunRes);
+}
+
+/**
+ * This is modbus master respond timeout error process callback function.
+ * @note There functions will block modbus master poll while execute OS waiting.
+ * So,for real-time of system.Do not execute too much waiting process.
+ *
+ * @param ucDestAddress destination salve address
+ * @param pucPDUData PDU buffer data
+ * @param ucPDULength PDU buffer length
+ *
+ */
+void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData,
+ USHORT ucPDULength) {
+ /**
+ * @note This code is use OS's event mechanism for modbus master protocol stack.
+ * If you don't use OS, you can change it.
+ */
+ rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT);
+
+ /* You can add your code under here. */
- if( xMasterEventInQueue )
+}
+
+/**
+ * This is modbus master receive data error process callback function.
+ * @note There functions will block modbus master poll while execute OS waiting.
+ * So,for real-time of system.Do not execute too much waiting process.
+ *
+ * @param ucDestAddress destination salve address
+ * @param pucPDUData PDU buffer data
+ * @param ucPDULength PDU buffer length
+ *
+ */
+void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData,
+ USHORT ucPDULength) {
+ /**
+ * @note This code is use OS's event mechanism for modbus master protocol stack.
+ * If you don't use OS, you can change it.
+ */
+ rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RECEIVE_DATA);
+
+ /* You can add your code under here. */
+
+}
+
+/**
+ * This is modbus master execute function error process callback function.
+ * @note There functions will block modbus master poll while execute OS waiting.
+ * So,for real-time of system.Do not execute too much waiting process.
+ *
+ * @param ucDestAddress destination salve address
+ * @param pucPDUData PDU buffer data
+ * @param ucPDULength PDU buffer length
+ *
+ */
+void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData,
+ USHORT ucPDULength) {
+ /**
+ * @note This code is use OS's event mechanism for modbus master protocol stack.
+ * If you don't use OS, you can change it.
+ */
+ rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION);
+
+ /* You can add your code under here. */
+
+}
+
+/**
+ * This is modbus master request process success callback function.
+ * @note There functions will block modbus master poll while execute OS waiting.
+ * So,for real-time of system.Do not execute too much waiting process.
+ *
+ */
+void vMBMasterCBRequestScuuess( void ) {
+ /**
+ * @note This code is use OS's event mechanism for modbus master protocol stack.
+ * If you don't use OS, you can change it.
+ */
+ rt_event_send(&xMasterOsEvent, EV_MASTER_PROCESS_SUCESS);
+
+ /* You can add your code under here. */
+
+}
+
+/**
+ * This function is wait for modbus master request finish and return result.
+ * Waiting result include request process success, request respond timeout,
+ * receive data error and execute function error.You can use the above callback function.
+ * @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run
+ * much user custom delay for waiting.
+ *
+ * @return request error code
+ */
+eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
+ eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
+ rt_uint32_t recvedEvent;
+ /* waiting for OS event */
+ rt_event_recv(&xMasterOsEvent,
+ EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
+ | EV_MASTER_ERROR_RECEIVE_DATA
+ | EV_MASTER_ERROR_EXECUTE_FUNCTION,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
+ &recvedEvent);
+ switch (recvedEvent)
{
- *eEvent = eMasterQueuedEvent;
- xMasterEventInQueue = FALSE;
- xEventHappened = TRUE;
+ case EV_MASTER_PROCESS_SUCESS:
+ break;
+ case EV_MASTER_ERROR_RESPOND_TIMEOUT:
+ {
+ eErrStatus = MB_MRE_TIMEDOUT;
+ break;
+ }
+ case EV_MASTER_ERROR_RECEIVE_DATA:
+ {
+ eErrStatus = MB_MRE_REV_DATA;
+ break;
+ }
+ case EV_MASTER_ERROR_EXECUTE_FUNCTION:
+ {
+ eErrStatus = MB_MRE_EXE_FUN;
+ break;
+ }
}
- return xEventHappened;
+ return eErrStatus;
}
#endif
diff --git a/components/net/freemodbus-v1.6.0/port/portserial.c b/components/net/freemodbus-v1.6.0/port/portserial.c
index 3768702087..0ba8dfbaec 100644
--- a/components/net/freemodbus-v1.6.0/port/portserial.c
+++ b/components/net/freemodbus-v1.6.0/port/portserial.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -24,122 +24,148 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
+#include "rtdevice.h"
+#include "bsp.h"
+
+/* ----------------------- Static variables ---------------------------------*/
+ALIGN(RT_ALIGN_SIZE)
+/* software simulation serial transmit IRQ handler thread stack */
+static rt_uint8_t serial_soft_trans_irq_stack[512];
+/* software simulation serial transmit IRQ handler thread */
+static struct rt_thread thread_serial_soft_trans_irq;
+/* serial event */
+static struct rt_event event_serial;
+/* modbus slave serial device */
+static rt_serial_t *serial;
+
+/* ----------------------- Defines ------------------------------------------*/
+/* serial transmit event */
+#define EVENT_SERIAL_TRANS_START (1<<0)
+
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
-/* ----------------------- Start implementation -----------------------------*/
-
-void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
-{
- if (xRxEnable)
- {
- SLAVE_RS485_RECEIVE_MODE;
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- }
- else
- {
- SLAVE_RS485_SEND_MODE;
- USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
- }
- if (xTxEnable)
- {
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- }
- else
- {
- USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
- }
-}
+static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size);
+static void serial_soft_trans_irq(void* parameter);
-void vMBPortClose(void)
-{
- USART_ITConfig(USART1, USART_IT_TXE | USART_IT_RXNE, DISABLE);
- USART_Cmd(USART1, DISABLE);
-}
-//Ĭ��һ���ӻ� ����1 �����ʿ����� ��ż���������
+/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
- eMBParity eParity)
+ eMBParity eParity)
{
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //======================ʱ�ӳ�ʼ��=======================================
- RCC_APB2PeriphClockCmd(
- RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1,
- ENABLE);
- //======================IO��ʼ��=======================================
- //USART1_TX
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //USART1_RX
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //����485���ͺͽ���ģʽ
-// TODO ��ʱ��дB13 ��֮����������ʱ���޸�
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- //======================���ڳ�ʼ��=======================================
- USART_InitStructure.USART_BaudRate = ulBaudRate;
- //����У��ģʽ
- switch (eParity)
- {
- case MB_PAR_NONE: //����
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- break;
- case MB_PAR_ODD: //����
- USART_InitStructure.USART_Parity = USART_Parity_Odd;
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- break;
- case MB_PAR_EVEN: //żУ��
- USART_InitStructure.USART_Parity = USART_Parity_Even;
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- break;
- default:
- return FALSE;
- }
+ /**
+ * set 485 mode receive and transmit control IO
+ * @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
+ */
+ rt_pin_mode(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_MODE_OUTPUT);
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_HardwareFlowControl =
- USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- if (ucPORT != 1)
- return FALSE;
+ /* set serial name */
+ if (ucPORT == 1) {
+#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
+ extern struct rt_serial_device serial1;
+ serial = &serial1;
+#endif
+ } else if (ucPORT == 2) {
+#if defined(RT_USING_UART2)
+ extern struct rt_serial_device serial2;
+ serial = &serial2;
+#endif
+ } else if (ucPORT == 3) {
+#if defined(RT_USING_UART3)
+ extern struct rt_serial_device serial3;
+ serial = &serial3;
+#endif
+ }
+ /* set serial configure parameter */
+ serial->config.baud_rate = ulBaudRate;
+ serial->config.stop_bits = STOP_BITS_1;
+ switch(eParity){
+ case MB_PAR_NONE: {
+ serial->config.data_bits = DATA_BITS_8;
+ serial->config.parity = PARITY_NONE;
+ break;
+ }
+ case MB_PAR_ODD: {
+ serial->config.data_bits = DATA_BITS_9;
+ serial->config.parity = PARITY_ODD;
+ break;
+ }
+ case MB_PAR_EVEN: {
+ serial->config.data_bits = DATA_BITS_9;
+ serial->config.parity = PARITY_EVEN;
+ break;
+ }
+ }
+ /* set serial configure */
+ serial->ops->configure(serial, &(serial->config));
- ENTER_CRITICAL_SECTION(); //��ȫ���ж�
+ /* open serial device */
+ if (!serial->parent.open(&serial->parent,
+ RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX )) {
+ serial->parent.rx_indicate = serial_rx_ind;
+ } else {
+ return FALSE;
+ }
- USART_Init(USART1, &USART_InitStructure);
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- USART_Cmd(USART1, ENABLE);
+ /* software initialize */
+ rt_thread_init(&thread_serial_soft_trans_irq,
+ "slave trans",
+ serial_soft_trans_irq,
+ RT_NULL,
+ serial_soft_trans_irq_stack,
+ sizeof(serial_soft_trans_irq_stack),
+ 10, 5);
+ rt_thread_startup(&thread_serial_soft_trans_irq);
+ rt_event_init(&event_serial, "slave event", RT_IPC_FLAG_PRIO);
- //=====================�жϳ�ʼ��======================================
- //����NVIC���ȼ�����ΪGroup2��0-3��ռʽ���ȼ���0-3����Ӧʽ���ȼ�
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
+ return TRUE;
+}
- EXIT_CRITICAL_SECTION(); //��ȫ���ж�
+void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
+{
+ rt_uint32_t recved_event;
+ 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 */
+ rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_LOW);
+ }
+ else
+ {
+ /* switch 485 to transmit mode */
+ rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_HIGH);
+ /* disable RX interrupt */
+ serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
+ }
+ if (xTxEnable)
+ {
+ /* start serial transmit */
+ rt_event_send(&event_serial, EVENT_SERIAL_TRANS_START);
+ }
+ else
+ {
+ /* stop serial transmit */
+ rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0,
+ &recved_event);
+ }
+}
- return TRUE;
+void vMBPortClose(void)
+{
+ serial->parent.close(&(serial->parent));
}
BOOL xMBPortSerialPutByte(CHAR ucByte)
{
- USART_SendData(USART1, ucByte);
- return TRUE;
+ serial->parent.write(&(serial->parent), 0, &ucByte, 1);
+ return TRUE;
}
BOOL xMBPortSerialGetByte(CHAR * pucByte)
{
- *pucByte = USART_ReceiveData(USART1);
- return TRUE;
+ serial->parent.read(&(serial->parent), 0, pucByte, 1);
+ return TRUE;
}
/*
@@ -151,7 +177,7 @@ BOOL xMBPortSerialGetByte(CHAR * pucByte)
*/
void prvvUARTTxReadyISR(void)
{
- pxMBFrameCBTransmitterEmpty();
+ pxMBFrameCBTransmitterEmpty();
}
/*
@@ -162,28 +188,35 @@ void prvvUARTTxReadyISR(void)
*/
void prvvUARTRxISR(void)
{
- pxMBFrameCBByteReceived();
+ pxMBFrameCBByteReceived();
}
-/*******************************************************************************
- * Function Name : USART1_IRQHandler
- * Description : This function handles USART1 global interrupt request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
-void USART1_IRQHandler(void)
-{
- rt_interrupt_enter();
- //�����ж�
- if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
- {
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);
- prvvUARTRxISR();
- }
- //�����ж�
- if (USART_GetITStatus(USART1, USART_IT_TXE) == SET)
- {
- prvvUARTTxReadyISR();
- }
- rt_interrupt_leave();
+
+/**
+ * Software simulation serial transmit IRQ handler.
+ *
+ * @param parameter parameter
+ */
+static void serial_soft_trans_irq(void* parameter) {
+ rt_uint32_t recved_event;
+ while (1)
+ {
+ /* waiting for serial transmit start */
+ rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START, RT_EVENT_FLAG_OR,
+ RT_WAITING_FOREVER, &recved_event);
+ /* execute modbus callback */
+ prvvUARTTxReadyISR();
+ }
+}
+
+/**
+ * This function is serial receive callback function
+ *
+ * @param dev the device of serial
+ * @param size the data size that receive
+ *
+ * @return return RT_EOK
+ */
+static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
+ prvvUARTRxISR();
+ return RT_EOK;
}
diff --git a/components/net/freemodbus-v1.6.0/port/portserial_m.c b/components/net/freemodbus-v1.6.0/port/portserial_m.c
index ca76a81963..4dc02d92bd 100644
--- a/components/net/freemodbus-v1.6.0/port/portserial_m.c
+++ b/components/net/freemodbus-v1.6.0/port/portserial_m.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -24,123 +24,149 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
+#include "rtdevice.h"
+#include "bsp.h"
+
+#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
+/* ----------------------- Static variables ---------------------------------*/
+ALIGN(RT_ALIGN_SIZE)
+/* software simulation serial transmit IRQ handler thread stack */
+static rt_uint8_t serial_soft_trans_irq_stack[512];
+/* software simulation serial transmit IRQ handler thread */
+static struct rt_thread thread_serial_soft_trans_irq;
+/* serial event */
+static struct rt_event event_serial;
+/* modbus slave serial device */
+static rt_serial_t *serial;
+
+/* ----------------------- Defines ------------------------------------------*/
+/* serial transmit event */
+#define EVENT_SERIAL_TRANS_START (1<<0)
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
-/* ----------------------- Start implementation -----------------------------*/
-
-void vMBMasterPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
-{
- if (xRxEnable)
- {
- MASTER_RS485_RECEIVE_MODE;
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- }
- else
- {
- MASTER_RS485_SEND_MODE;
- USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
- }
- if (xTxEnable)
- {
- USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
- }
- else
- {
- USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
- }
-}
+static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size);
+static void serial_soft_trans_irq(void* parameter);
-void vMBMasterPortClose(void)
-{
- USART_ITConfig(USART2, USART_IT_TXE | USART_IT_RXNE, DISABLE);
- USART_Cmd(USART2, DISABLE);
-}
-//Ĭ��һ������ ����2 �����ʿ����� ��ż���������
+/* ----------------------- Start implementation -----------------------------*/
BOOL xMBMasterPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
- eMBParity eParity)
+ eMBParity eParity)
{
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //======================ʱ�ӳ�ʼ��=======================================
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- //======================IO��ʼ��=======================================
- //USART2_TX
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //USART2_RX
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //����485���ͺͽ���ģʽ
-// TODO ��ʱ��дB13 ��֮����������ʱ���޸�
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- //======================���ڳ�ʼ��=======================================
- USART_InitStructure.USART_BaudRate = ulBaudRate;
- //����У��ģʽ
- switch (eParity)
- {
- case MB_PAR_NONE: //����
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- break;
- case MB_PAR_ODD: //����
- USART_InitStructure.USART_Parity = USART_Parity_Odd;
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- break;
- case MB_PAR_EVEN: //żУ��
- USART_InitStructure.USART_Parity = USART_Parity_Even;
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- break;
- default:
- return FALSE;
- }
+ /**
+ * set 485 mode receive and transmit control IO
+ * @note MODBUS_MASTER_RT_CONTROL_PIN_INDEX need be defined by user
+ */
+ rt_pin_mode(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_MODE_OUTPUT);
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_HardwareFlowControl =
- USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- if (ucPORT != 2)
- return FALSE;
+ /* set serial name */
+ if (ucPORT == 1) {
+#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
+ extern struct rt_serial_device serial1;
+ serial = &serial1;
+#endif
+ } else if (ucPORT == 2) {
+#if defined(RT_USING_UART2)
+ extern struct rt_serial_device serial2;
+ serial = &serial2;
+#endif
+ } else if (ucPORT == 3) {
+#if defined(RT_USING_UART3)
+ extern struct rt_serial_device serial3;
+ serial = &serial3;
+#endif
+ }
+ /* set serial configure parameter */
+ serial->config.baud_rate = ulBaudRate;
+ serial->config.stop_bits = STOP_BITS_1;
+ switch(eParity){
+ case MB_PAR_NONE: {
+ serial->config.data_bits = DATA_BITS_8;
+ serial->config.parity = PARITY_NONE;
+ break;
+ }
+ case MB_PAR_ODD: {
+ serial->config.data_bits = DATA_BITS_9;
+ serial->config.parity = PARITY_ODD;
+ break;
+ }
+ case MB_PAR_EVEN: {
+ serial->config.data_bits = DATA_BITS_9;
+ serial->config.parity = PARITY_EVEN;
+ break;
+ }
+ }
+ /* set serial configure */
+ serial->ops->configure(serial, &(serial->config));
- ENTER_CRITICAL_SECTION(); //��ȫ���ж�
+ /* open serial device */
+ if (!serial->parent.open(&serial->parent,
+ RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX )) {
+ serial->parent.rx_indicate = serial_rx_ind;
+ } else {
+ return FALSE;
+ }
- USART_Init(USART2, &USART_InitStructure);
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
- USART_Cmd(USART2, ENABLE);
+ /* software initialize */
+ rt_thread_init(&thread_serial_soft_trans_irq,
+ "slave trans",
+ serial_soft_trans_irq,
+ RT_NULL,
+ serial_soft_trans_irq_stack,
+ sizeof(serial_soft_trans_irq_stack),
+ 10, 5);
+ rt_thread_startup(&thread_serial_soft_trans_irq);
+ rt_event_init(&event_serial, "slave event", RT_IPC_FLAG_PRIO);
- //=====================�жϳ�ʼ��======================================
- //����NVIC���ȼ�����ΪGroup2��0-3��ռʽ���ȼ���0-3����Ӧʽ���ȼ�
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
+ return TRUE;
+}
- EXIT_CRITICAL_SECTION(); //��ȫ���ж�
+void vMBMasterPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
+{
+ rt_uint32_t recved_event;
+ 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 */
+ rt_pin_write(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_LOW);
+ }
+ else
+ {
+ /* switch 485 to transmit mode */
+ rt_pin_write(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_HIGH);
+ /* disable RX interrupt */
+ serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
+ }
+ if (xTxEnable)
+ {
+ /* start serial transmit */
+ rt_event_send(&event_serial, EVENT_SERIAL_TRANS_START);
+ }
+ else
+ {
+ /* stop serial transmit */
+ rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0,
+ &recved_event);
+ }
+}
- return TRUE;
+void vMBMasterPortClose(void)
+{
+ serial->parent.close(&(serial->parent));
}
BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
{
- USART_SendData(USART2, ucByte);
+ serial->parent.write(&(serial->parent), 0, &ucByte, 1);
return TRUE;
}
BOOL xMBMasterPortSerialGetByte(CHAR * pucByte)
{
- *pucByte = USART_ReceiveData(USART2);
- return TRUE;
+ serial->parent.read(&(serial->parent), 0, pucByte, 1);
+ return TRUE;
}
/*
@@ -152,7 +178,7 @@ BOOL xMBMasterPortSerialGetByte(CHAR * pucByte)
*/
void prvvUARTTxReadyISR(void)
{
- pxMBMasterFrameCBTransmitterEmpty();
+ pxMBMasterFrameCBTransmitterEmpty();
}
/*
@@ -163,30 +189,37 @@ void prvvUARTTxReadyISR(void)
*/
void prvvUARTRxISR(void)
{
- pxMBMasterFrameCBByteReceived();
+ pxMBMasterFrameCBByteReceived();
}
-/*******************************************************************************
- * Function Name : USART2_IRQHandler
- * Description : This function handles USART2 global interrupt request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
-void USART2_IRQHandler(void)
-{
- rt_interrupt_enter();
- //�����ж�
- if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
- {
- USART_ClearITPendingBit(USART2, USART_IT_RXNE);
- prvvUARTRxISR();
- }
- //�����ж�
- if (USART_GetITStatus(USART2, USART_IT_TXE) == SET)
- {
- prvvUARTTxReadyISR();
- }
- rt_interrupt_leave();
+
+/**
+ * Software simulation serial transmit IRQ handler.
+ *
+ * @param parameter parameter
+ */
+static void serial_soft_trans_irq(void* parameter) {
+ rt_uint32_t recved_event;
+ while (1)
+ {
+ /* waiting for serial transmit start */
+ rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START, RT_EVENT_FLAG_OR,
+ RT_WAITING_FOREVER, &recved_event);
+ /* execute modbus callback */
+ prvvUARTTxReadyISR();
+ }
+}
+
+/**
+ * This function is serial receive callback function
+ *
+ * @param dev the device of serial
+ * @param size the data size that receive
+ *
+ * @return return RT_EOK
+ */
+static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
+ prvvUARTRxISR();
+ return RT_EOK;
}
#endif
diff --git a/components/net/freemodbus-v1.6.0/port/porttimer.c b/components/net/freemodbus-v1.6.0/port/porttimer.c
index b7b74ce078..6f017d8759 100644
--- a/components/net/freemodbus-v1.6.0/port/porttimer.c
+++ b/components/net/freemodbus-v1.6.0/port/porttimer.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -27,81 +27,37 @@
#include "mbport.h"
/* ----------------------- static functions ---------------------------------*/
+static struct rt_timer timer;
static void prvvTIMERExpiredISR(void);
+static void timer_timeout_ind(void* parameter);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
{
-
- uint16_t PrescalerValue = 0;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- //====================================ʱ�ӳ�ʼ��===========================
- //ʹ�ܶ�ʱ��3ʱ��
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- //====================================��ʱ����ʼ��===========================
- //��ʱ��ʱ�������˵��
- //HCLKΪ72MHz��APB1����2��ƵΪ36MHz
- //TIM3��ʱ�ӱ�Ƶ��Ϊ72MHz��Ӳ���Զ���Ƶ,�ﵽ���
- //TIM3�ķ�Ƶϵ��Ϊ3599��ʱ���Ƶ��Ϊ72 / (1 + Prescaler) = 20KHz,��׼Ϊ50us
- //TIM������ֵΪusTim1Timerout50u
-
- PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
- //��ʱ��1��ʼ��
- TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us;
- TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- //Ԥװ��ʹ��
- TIM_ARRPreloadConfig(TIM3, ENABLE);
- //====================================�жϳ�ʼ��===========================
- //����NVIC���ȼ�����ΪGroup2��0-3��ռʽ���ȼ���0-3����Ӧʽ���ȼ�
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- //�������жϱ�־λ
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
- //��ʱ��3����жϹر�
- TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
- //��ʱ��3����
- TIM_Cmd(TIM3, DISABLE);
- return TRUE;
+ rt_timer_init(&timer, "slave timer",
+ timer_timeout_ind, /* bind timeout callback function */
+ RT_NULL,
+ (50*usTim1Timerout50us)/(1000*1000/RT_TICK_PER_SECOND),
+ RT_TIMER_FLAG_ONE_SHOT); /* one shot */
+ return TRUE;
}
void vMBPortTimersEnable()
{
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
- TIM_SetCounter(TIM3, 0);
- TIM_Cmd(TIM3, ENABLE);
+ rt_timer_start(&timer);
}
void vMBPortTimersDisable()
{
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
- TIM_ITConfig(TIM3, TIM_IT_Update, DISABLE);
- TIM_SetCounter(TIM3, 0);
- TIM_Cmd(TIM3, DISABLE);
+ rt_timer_stop(&timer);
}
void prvvTIMERExpiredISR(void)
{
- (void) pxMBPortCBTimerExpired();
+ (void) pxMBPortCBTimerExpired();
}
-void TIM3_IRQHandler(void)
+static void timer_timeout_ind(void* parameter)
{
- rt_interrupt_enter();
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
- {
-
- TIM_ClearFlag(TIM3, TIM_FLAG_Update); //���жϱ��
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //�����ʱ��T3����жϱ�־λ
- prvvTIMERExpiredISR();
- }
- rt_interrupt_leave();
+ prvvTIMERExpiredISR();
}
diff --git a/components/net/freemodbus-v1.6.0/port/porttimer_m.c b/components/net/freemodbus-v1.6.0/port/porttimer_m.c
index 1881b47053..69bdc54879 100644
--- a/components/net/freemodbus-v1.6.0/port/porttimer_m.c
+++ b/components/net/freemodbus-v1.6.0/port/porttimer_m.c
@@ -1,5 +1,5 @@
/*
- * FreeModbus Libary: STM32 Port
+ * FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -27,10 +27,12 @@
#include "mb_m.h"
#include "mbport.h"
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
+#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Variables ----------------------------------------*/
static USHORT usT35TimeOut50us;
-static USHORT usPrescalerValue = 0;
+static struct rt_timer timer;
+static void prvvTIMERExpiredISR(void);
+static void timer_timeout_ind(void* parameter);
/* ----------------------- static functions ---------------------------------*/
static void prvvTIMERExpiredISR(void);
@@ -38,120 +40,68 @@ static void prvvTIMERExpiredISR(void);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
{
- NVIC_InitTypeDef NVIC_InitStructure;
- //====================================ʱ�ӳ�ʼ��===========================
- //ʹ�ܶ�ʱ��2ʱ��
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- //====================================��ʱ����ʼ��===========================
- //��ʱ��ʱ�������˵��
- //HCLKΪ72MHz��APB1����2��ƵΪ36MHz
- //TIM2��ʱ�ӱ�Ƶ��Ϊ72MHz��Ӳ���Զ���Ƶ,�ﵽ���
- //TIM2�ķ�Ƶϵ��Ϊ3599��ʱ���Ƶ��Ϊ72 / (1 + Prescaler) = 20KHz,��׼Ϊ50us
- //TIM������ֵΪusTim1Timerout50u
- usPrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
- //����T35��ʱ������ֵ
- usT35TimeOut50us = usTimeOut50us;
+ /* backup T35 ticks */
+ usT35TimeOut50us = usTimeOut50us;
+
+ rt_timer_init(&timer, "master timer",
+ timer_timeout_ind, /* bind timeout callback function */
+ RT_NULL,
+ (50 * usT35TimeOut50us) / (1000 * 1000 / RT_TICK_PER_SECOND),
+ RT_TIMER_FLAG_ONE_SHOT); /* one shot */
- //Ԥװ��ʹ��
- TIM_ARRPreloadConfig(TIM2, ENABLE);
- //====================================�жϳ�ʼ��===========================
- //����NVIC���ȼ�����ΪGroup2��0-3��ռʽ���ȼ���0-3����Ӧʽ���ȼ�
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- //�������жϱ�־λ
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- //��ʱ��3����жϹر�
- TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
- //��ʱ��3����
- TIM_Cmd(TIM2, DISABLE);
- return TRUE;
+ return TRUE;
}
void vMBMasterPortTimersT35Enable()
{
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+ rt_tick_t timer_tick = (50 * usT35TimeOut50us)
+ / (1000 * 1000 / RT_TICK_PER_SECOND);
- /* Set current timer mode,don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_T35);
+ /* Set current timer mode, don't change it.*/
+ vMBMasterSetCurTimerMode(MB_TMODE_T35);
- TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseStructure.TIM_Period = (uint16_t) usT35TimeOut50us;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+ rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
- TIM_SetCounter(TIM2, 0);
- TIM_Cmd(TIM2, ENABLE);
+ rt_timer_start(&timer);
}
void vMBMasterPortTimersConvertDelayEnable()
{
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+ rt_tick_t timer_tick = MB_MASTER_DELAY_MS_CONVERT * RT_TICK_PER_SECOND / 1000;
- /* Set current timer mode,don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
+ /* Set current timer mode, don't change it.*/
+ vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
- TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_DELAY_MS_CONVERT * 1000 / 50);
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+ rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
- TIM_SetCounter(TIM2, 0);
- TIM_Cmd(TIM2, ENABLE);
+ rt_timer_start(&timer);
}
void vMBMasterPortTimersRespondTimeoutEnable()
{
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+ rt_tick_t timer_tick = MB_MASTER_TIMEOUT_MS_RESPOND * RT_TICK_PER_SECOND / 1000;
- /* Set current timer mode,don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
+ /* Set current timer mode, don't change it.*/
+ vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
- TIM_TimeBaseStructure.TIM_Prescaler = usPrescalerValue;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_TIMEOUT_MS_RESPOND * 1000 / 50);
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+ rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
- TIM_SetCounter(TIM2, 0);
- TIM_Cmd(TIM2, ENABLE);
+ rt_timer_start(&timer);
}
void vMBMasterPortTimersDisable()
{
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
- TIM_SetCounter(TIM2, 0);
- TIM_Cmd(TIM2, DISABLE);
+ rt_timer_stop(&timer);
}
void prvvTIMERExpiredISR(void)
{
- (void) pxMBMasterPortCBTimerExpired();
+ (void) pxMBMasterPortCBTimerExpired();
}
-void TIM2_IRQHandler(void)
+static void timer_timeout_ind(void* parameter)
{
- rt_interrupt_enter();
- if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
- {
-
- TIM_ClearFlag(TIM2, TIM_FLAG_Update); //���жϱ��
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //�����ʱ��TIM2����жϱ�־λ
- prvvTIMERExpiredISR();
- }
- rt_interrupt_leave();
+ prvvTIMERExpiredISR();
}
#endif
diff --git a/components/net/freemodbus-v1.6.0/port/user_mb_app.c b/components/net/freemodbus-v1.6.0/port/user_mb_app.c
index a99615c235..e6fdede11f 100644
--- a/components/net/freemodbus-v1.6.0/port/user_mb_app.c
+++ b/components/net/freemodbus-v1.6.0/port/user_mb_app.c
@@ -1,4 +1,25 @@
+/*
+ * FreeModbus Libary: user callback functions and buffer define in slave mode
+ * Copyright (C) 2013 Armink <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $
+ */
#include "user_mb_app.h"
+
/*------------------------Slave mode use these variables----------------------*/
//Slave mode:DiscreteInputs variables
USHORT usSDiscInStart = S_DISCRETE_INPUT_START;
@@ -20,81 +41,41 @@ USHORT usSRegInBuf[S_REG_INPUT_NREGS] ;
//Slave mode:HoldingRegister variables
USHORT usSRegHoldStart = S_REG_HOLDING_START;
USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;
-/*-----------------------Master mode use these variables----------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-//Master mode:DiscreteInputs variables
-USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
-#if M_DISCRETE_INPUT_NDISCRETES%8
-UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
-#else
-UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
-#endif
-//Master mode:Coils variables
-USHORT usMCoilStart = M_COIL_START;
-#if M_COIL_NCOILS%8
-UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
-#else
-UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
-#endif
-//Master mode:InputRegister variables
-USHORT usMRegInStart = M_REG_INPUT_START;
-USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
-//Master mode:HoldingRegister variables
-USHORT usMRegHoldStart = M_REG_HOLDING_START;
-USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
-#endif
-//******************************����Ĵ����ص�����**********************************
-//��������: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
-//�� ��������Ĵ�����صĹ��ܣ�������������
-//��ڲ�����pucRegBuffer : �ص�������Modbus�Ĵ����ĵ�ǰֵд��Ļ�����
-// usAddress : �Ĵ�������ʼ��ַ������Ĵ����ĵ�ַ��Χ��1-65535��
-// usNRegs : �Ĵ�������
-//���ڲ�����eMBErrorCode : ������������صĴ�����
-//�� ע��Editor��Armink 2010-10-31 Company: BXXJS
-//**********************************************************************************
-eMBErrorCode
-eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
+
+/**
+ * Modbus slave input register callback function.
+ *
+ * @param pucRegBuffer input register buffer
+ * @param usAddress input register address
+ * @param usNRegs input register number
+ *
+ * @return result
+ */
+eMBErrorCode eMBRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
- int iRegIndex;
+ USHORT iRegIndex;
USHORT * pusRegInputBuf;
- UCHAR REG_INPUT_START;
- UCHAR REG_INPUT_NREGS;
- UCHAR usRegInStart;
+ USHORT REG_INPUT_START;
+ USHORT REG_INPUT_NREGS;
+ USHORT usRegInStart;
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress()];
- REG_INPUT_START = M_REG_INPUT_START;
- REG_INPUT_NREGS = M_REG_INPUT_NREGS;
- usRegInStart = usMRegInStart;
- }
- else
- {
- pusRegInputBuf = usSRegInBuf;
- REG_INPUT_START = S_REG_INPUT_START;
- REG_INPUT_NREGS = S_REG_INPUT_NREGS;
- usRegInStart = usSRegInStart;
- }
+ pusRegInputBuf = usSRegInBuf;
+ REG_INPUT_START = S_REG_INPUT_START;
+ REG_INPUT_NREGS = S_REG_INPUT_NREGS;
+ usRegInStart = usSRegInStart;
- if( ( usAddress >= REG_INPUT_START )
- && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= REG_INPUT_START)
+ && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
{
- iRegIndex = ( int )( usAddress - usRegInStart );
- while( usNRegs > 0 )
+ iRegIndex = usAddress - usRegInStart;
+ while (usNRegs > 0)
{
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
- pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
- }
- else
- {
- *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] >> 8 );
- *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] & 0xFF );
- }
+ *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);
+ *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);
iRegIndex++;
usNRegs--;
}
@@ -106,67 +87,55 @@ eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
return eStatus;
}
-//******************************���ּĴ����ص�����**********************************
-//��������: eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
-//�� �������ּĴ�����صĹ��ܣ�������������д������д��
-//��ڲ�����pucRegBuffer : �����Ҫ�����û��Ĵ�����ֵ���������������ָ���µļĴ�����ֵ��
-// ���Э��ջ��֪����ǰ����ֵ���ص��������뽫��ǰֵд�����������
-// usAddress : �Ĵ�������ʼ��ַ��
-// usNRegs : �Ĵ�������
-// eMode : ����ò���ΪeMBRegisterMode::MB_REG_WRITE���û���Ӧ����ֵ����pucRegBuffer�еõ����¡�
-// ����ò���ΪeMBRegisterMode::MB_REG_READ���û���Ҫ����ǰ��Ӧ�����ݴ洢��pucRegBuffer��
-//���ڲ�����eMBErrorCode : ������������صĴ�����
-//�� ע��Editor��Armink 2010-10-31 Company: BXXJS
-//**********************************************************************************
-eMBErrorCode
-eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
+
+/**
+ * Modbus slave holding register callback function.
+ *
+ * @param pucRegBuffer holding register buffer
+ * @param usAddress holding register address
+ * @param usNRegs holding register number
+ * @param eMode read or write
+ *
+ * @return result
+ */
+eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNRegs, eMBRegisterMode eMode)
{
eMBErrorCode eStatus = MB_ENOERR;
- int iRegIndex;
+ USHORT iRegIndex;
USHORT * pusRegHoldingBuf;
- UCHAR REG_HOLDING_START;
- UCHAR REG_HOLDING_NREGS;
- UCHAR usRegHoldStart;
+ USHORT REG_HOLDING_START;
+ USHORT REG_HOLDING_NREGS;
+ USHORT usRegHoldStart;
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress()];
- REG_HOLDING_START = M_REG_HOLDING_START;
- REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
- usRegHoldStart = usMRegHoldStart;
- //If mode is read,the master will wirte the received date to bufffer.
- eMode = MB_REG_WRITE;
- }
- else
- {
- pusRegHoldingBuf = usSRegHoldBuf;
- REG_HOLDING_START = S_REG_HOLDING_START;
- REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
- usRegHoldStart = usSRegHoldStart;
- }
+ pusRegHoldingBuf = usSRegHoldBuf;
+ REG_HOLDING_START = S_REG_HOLDING_START;
+ REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
+ usRegHoldStart = usSRegHoldStart;
- if( ( usAddress >= REG_HOLDING_START ) &&
- ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= REG_HOLDING_START)
+ && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
{
- iRegIndex = ( int )( usAddress - usRegHoldStart );
- switch ( eMode )
+ iRegIndex = usAddress - usRegHoldStart;
+ switch (eMode)
{
- /* Pass current register values to the protocol stack. */
+ /* read current register values from the protocol stack. */
case MB_REG_READ:
- while( usNRegs > 0 )
+ while (usNRegs > 0)
{
- *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] >> 8 );
- *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] & 0xFF );
+ *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
+ *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
iRegIndex++;
usNRegs--;
}
break;
- /* Update current register values with new values from the
- * protocol stack. */
+ /* write current register values with new values from the protocol stack. */
case MB_REG_WRITE:
- while( usNRegs > 0 )
+ while (usNRegs > 0)
{
pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
@@ -182,83 +151,76 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
}
return eStatus;
}
-//****************************��Ȧ״̬�Ĵ����ص�����********************************
-//��������: eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
-//�� ������Ȧ״̬�Ĵ�����صĹ��ܣ�������������д������д��
-//��ڲ�����pucRegBuffer : λ���һ���ֽڣ���ʼ�Ĵ�����Ӧ��λ���ڸ��ֽ�pucRegBuffer�����λLSB��
-// ����ص�����Ҫд�����������û���õ�����Ȧ�����粻��8��һ�����Ȧ״̬����Ӧ��λ����ֵ��������λ0��
-// usAddress : ��һ����Ȧ��ַ��
-// usNCoils : �������Ȧ����
-// eMode ������ò���ΪeMBRegisterMode::MB_REG_WRITE���û���Ӧ����ֵ����pucRegBuffer�еõ����¡�
-// ����ò���ΪeMBRegisterMode::MB_REG_READ���û���Ҫ����ǰ��Ӧ�����ݴ洢��pucRegBuffer��
-//���ڲ�����eMBErrorCode : ������������صĴ�����
-//�� ע��Editor��Armink 2010-10-31 Company: BXXJS
-//**********************************************************************************
-eMBErrorCode
-eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
+
+/**
+ * Modbus slave coils callback function.
+ *
+ * @param pucRegBuffer coils buffer
+ * @param usAddress coils address
+ * @param usNCoils coils number
+ * @param eMode read or write
+ *
+ * @return result
+ */
+eMBErrorCode eMBRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNCoils, eMBRegisterMode eMode)
{
eMBErrorCode eStatus = MB_ENOERR;
- int iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucCoilBuf;
- UCHAR COIL_START;
- UCHAR COIL_NCOILS;
- UCHAR usCoilStart;
- iNReg = usNCoils / 8 + 1; //ռ�üĴ�������
+ USHORT iRegIndex , iRegBitIndex , iNReg;
+ UCHAR * pucCoilBuf;
+ USHORT COIL_START;
+ USHORT COIL_NCOILS;
+ USHORT usCoilStart;
+ iNReg = usNCoils / 8 + 1;
+ pucCoilBuf = ucSCoilBuf;
+ COIL_START = S_COIL_START;
+ COIL_NCOILS = S_COIL_NCOILS;
+ usCoilStart = usSCoilStart;
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress()];
- COIL_START = M_COIL_START;
- COIL_NCOILS = M_COIL_NCOILS;
- usCoilStart = usMCoilStart;
- //If mode is read,the master will wirte the received date to bufffer.
- eMode = MB_REG_WRITE;
- }
- else
- {
- pucCoilBuf = ucSCoilBuf;
- COIL_START = S_COIL_START;
- COIL_NCOILS = S_COIL_NCOILS;
- usCoilStart = usSCoilStart;
- }
+ /* it already plus one in modbus function method. */
+ usAddress--;
if( ( usAddress >= COIL_START ) &&
( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
{
- iRegIndex = ( int )( usAddress - usCoilStart ) / 8 ; //ÿ���Ĵ�����8��
- iRegBitIndex = ( int )( usAddress - usCoilStart ) % 8 ; //����ڼĴ����ڲ���λ��ַ
+ iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
+ iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
switch ( eMode )
{
- /* Pass current coil values to the protocol stack. */
+ /* read current coil values from the protocol stack. */
case MB_REG_READ:
- while( iNReg > 0 )
+ while (iNReg > 0)
{
- *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8);
- iNReg --;
+ *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
+ iRegBitIndex, 8);
+ iNReg--;
}
- pucRegBuffer --;
- usNCoils = usNCoils % 8; //���µ���Ȧ��
- *pucRegBuffer = *pucRegBuffer <<(8 - usNCoils); //�����
- *pucRegBuffer = *pucRegBuffer >>(8 - usNCoils);
+ pucRegBuffer--;
+ /* last coils */
+ usNCoils = usNCoils % 8;
+ /* filling zero to high bit */
+ *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
+ *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
break;
- /* Update current coil values with new values from the
- * protocol stack. */
+ /* write current coil values with new values from the protocol stack. */
case MB_REG_WRITE:
- while(iNReg > 1) //���������������������
+ while (iNReg > 1)
{
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
+ xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
+ *pucRegBuffer++);
iNReg--;
}
- usNCoils = usNCoils % 8; //���µ���Ȧ��
- if (usNCoils != 0) //xMBUtilSetBits���� �ڲ���λ����Ϊ0ʱ����bug
- {
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
- *pucRegBuffer++);
- }
- break;
+ /* last coils */
+ usNCoils = usNCoils % 8;
+ /* xMBUtilSetBits has bug when ucNBits is zero */
+ if (usNCoils != 0)
+ {
+ xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
+ *pucRegBuffer++);
+ }
+ break;
}
}
else
@@ -267,78 +229,52 @@ eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegis
}
return eStatus;
}
-//****************************��ɢ����Ĵ����ص�����********************************
-//��������: eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
-//�� ������ɢ����Ĵ�����صĹ��ܣ�������������
-//��ڲ�����pucRegBuffer : �õ�ǰ����Ȧ���ݸ�������Ĵ�������ʼ�Ĵ�����Ӧ��λ���ڸ��ֽ�pucRegBuffer�����λLSB��
-// ����ص�����Ҫд�����������û���õ�����Ȧ�����粻��8��һ�����Ȧ״̬����Ӧ��λ����ֵ��������Ϊ0��
-// usAddress : ��ɢ�������ʼ��ַ
-// usNDiscrete : ��ɢ���������
-//���ڲ�����eMBErrorCode : ������������صĴ�����
-//�� ע��Editor��Armink 2010-10-31 Company: BXXJS
-//**********************************************************************************
-eMBErrorCode
-eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
+
+/**
+ * Modbus slave discrete callback function.
+ *
+ * @param pucRegBuffer discrete buffer
+ * @param usAddress discrete address
+ * @param usNDiscrete discrete number
+ *
+ * @return result
+ */
+eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
eMBErrorCode eStatus = MB_ENOERR;
- int iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucDiscreteInputBuf;
- UCHAR DISCRETE_INPUT_START;
- UCHAR DISCRETE_INPUT_NDISCRETES;
- UCHAR usDiscreteInputStart;
- iNReg = usNDiscrete / 8 + 1; //ռ�üĴ�������
+ USHORT iRegIndex , iRegBitIndex , iNReg;
+ UCHAR * pucDiscreteInputBuf;
+ USHORT DISCRETE_INPUT_START;
+ USHORT DISCRETE_INPUT_NDISCRETES;
+ USHORT usDiscreteInputStart;
+ iNReg = usNDiscrete / 8 + 1;
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress()];
- DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
- DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
- usDiscreteInputStart = usMDiscInStart;
- }
- else
- {
- pucDiscreteInputBuf = ucSDiscInBuf;
- DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
- DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
- usDiscreteInputStart = usSDiscInStart;
- }
+ pucDiscreteInputBuf = ucSDiscInBuf;
+ DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
+ DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
+ usDiscreteInputStart = usSDiscInStart;
+
+ /* it already plus one in modbus function method. */
+ usAddress--;
- if( ( usAddress >= DISCRETE_INPUT_START )
- && ( usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES ) )
+ if ((usAddress >= DISCRETE_INPUT_START)
+ && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
{
- iRegIndex = ( int )( usAddress - usDiscreteInputStart ) / 8 ; //ÿ���Ĵ�����8��
- iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ; //����ڼĴ����ڲ���λ��ַ
+ iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8; //ÿ���Ĵ�����8��
+ iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8; //����ڼĴ����ڲ���λ��ַ
- //Determine the master or slave
- if (xMBMasterGetCBRunInMasterMode())
- {
- /* Update current coil values with new values from the
- * protocol stack. */
- while(iNReg > 1) //���������������������
- {
- xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
- iNReg--;
- }
- usNDiscrete = usNDiscrete % 8; //���µ���Ȧ��
- if (usNDiscrete != 0) //xMBUtilSetBits���� �ڲ���λ����Ϊ0ʱ����bug
- {
- xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
- usNDiscrete, *pucRegBuffer++);
- }
- }
- else
- {
- while( iNReg > 0 )
- {
- *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
- iNReg --;
- }
- pucRegBuffer --;
- usNDiscrete = usNDiscrete % 8; //���µ���Ȧ��
- *pucRegBuffer = *pucRegBuffer <<(8 - usNDiscrete); //�����
- *pucRegBuffer = *pucRegBuffer >>(8 - usNDiscrete);
- }
+ while (iNReg > 0)
+ {
+ *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],
+ iRegBitIndex, 8);
+ iNReg--;
+ }
+ pucRegBuffer--;
+ /* last discrete */
+ usNDiscrete = usNDiscrete % 8;
+ /* filling zero to high bit */
+ *pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);
+ *pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);
}
else
{
@@ -347,3 +283,4 @@ eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
return eStatus;
}
+
diff --git a/components/net/freemodbus-v1.6.0/port/user_mb_app.h b/components/net/freemodbus-v1.6.0/port/user_mb_app.h
index 440ca82135..846b9a3a48 100644
--- a/components/net/freemodbus-v1.6.0/port/user_mb_app.h
+++ b/components/net/freemodbus-v1.6.0/port/user_mb_app.h
@@ -1,4 +1,4 @@
-#ifndef USER_APP
+#ifndef USER_APP
#define USER_APP
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
@@ -8,47 +8,41 @@
#include "mbutils.h"
/* -----------------------Slave Defines -------------------------------------*/
-#define S_DISCRETE_INPUT_START 1
+#define S_DISCRETE_INPUT_START 0
#define S_DISCRETE_INPUT_NDISCRETES 16
-#define S_COIL_START 1
+#define S_COIL_START 0
#define S_COIL_NCOILS 64
-#define S_REG_INPUT_START 1
+#define S_REG_INPUT_START 0
#define S_REG_INPUT_NREGS 100
-#define S_REG_HOLDING_START 1
+#define S_REG_HOLDING_START 0
#define S_REG_HOLDING_NREGS 100
-//�ӻ�ģʽ���ڱ��ּĴ����У�������ַ��Ӧ�Ĺ��ܶ���
-#define S_HD_RESERVE 0 //����
-#define S_HD_CPU_USAGE_MAJOR 1 //��ǰCPU�����ʵ�����λ
-#define S_HD_CPU_USAGE_MINOR 2 //��ǰCPU�����ʵ�С��λ
-
-//�ӻ�ģʽ��������Ĵ����У�������ַ��Ӧ�Ĺ��ܶ���
-#define S_IN_RESERVE 0 //����
-
-//�ӻ�ģʽ������Ȧ�У�������ַ��Ӧ�Ĺ��ܶ���
-#define S_CO_RESERVE 2 //����
-
-//�ӻ�ģʽ������ɢ�����У�������ַ��Ӧ�Ĺ��ܶ���
-#define S_DI_RESERVE 1 //����
+/* salve mode: holding register's all address */
+#define S_HD_RESERVE 0
+#define S_HD_CPU_USAGE_MAJOR 1
+#define S_HD_CPU_USAGE_MINOR 2
+/* salve mode: input register's all address */
+#define S_IN_RESERVE 0
+/* salve mode: coil's all address */
+#define S_CO_RESERVE 0
+/* salve mode: discrete's all address */
+#define S_DI_RESERVE 0
/* -----------------------Master Defines -------------------------------------*/
-#define M_DISCRETE_INPUT_START 1
+#define M_DISCRETE_INPUT_START 0
#define M_DISCRETE_INPUT_NDISCRETES 16
-#define M_COIL_START 1
+#define M_COIL_START 0
#define M_COIL_NCOILS 64
-#define M_REG_INPUT_START 1
+#define M_REG_INPUT_START 0
#define M_REG_INPUT_NREGS 100
-#define M_REG_HOLDING_START 1
+#define M_REG_HOLDING_START 0
#define M_REG_HOLDING_NREGS 100
-//����ģʽ���ڱ��ּĴ����У�������ַ��Ӧ�Ĺ��ܶ���
-#define M_HD_RESERVE 0 //����
-
-//����ģʽ��������Ĵ����У�������ַ��Ӧ�Ĺ��ܶ���
-#define M_IN_RESERVE 0 //����
-
-//����ģʽ������Ȧ�У�������ַ��Ӧ�Ĺ��ܶ���
-#define M_CO_RESERVE 2 //����
-
-//����ģʽ������ɢ�����У�������ַ��Ӧ�Ĺ��ܶ���
-#define M_DI_RESERVE 1 //����
+/* master mode: holding register's all address */
+#define M_HD_RESERVE 0
+/* master mode: input register's all address */
+#define M_IN_RESERVE 0
+/* master mode: coil's all address */
+#define M_CO_RESERVE 0
+/* master mode: discrete's all address */
+#define M_DI_RESERVE 0
#endif
diff --git a/components/net/freemodbus-v1.6.0/port/user_mb_app_m.c b/components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
new file mode 100644
index 0000000000..12fabf21ac
--- /dev/null
+++ b/components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
@@ -0,0 +1,294 @@
+/*
+ * FreeModbus Libary: user callback functions and buffer define in master mode
+ * Copyright (C) 2013 Armink <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * File: $Id: user_mb_app_m.c,v 1.60 2013/11/23 11:49:05 Armink $
+ */
+#include "user_mb_app.h"
+
+/*-----------------------Master mode use these variables----------------------*/
+#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
+//Master mode:DiscreteInputs variables
+USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
+#if M_DISCRETE_INPUT_NDISCRETES%8
+UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
+#else
+UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
+#endif
+//Master mode:Coils variables
+USHORT usMCoilStart = M_COIL_START;
+#if M_COIL_NCOILS%8
+UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
+#else
+UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
+#endif
+//Master mode:InputRegister variables
+USHORT usMRegInStart = M_REG_INPUT_START;
+USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
+//Master mode:HoldingRegister variables
+USHORT usMRegHoldStart = M_REG_HOLDING_START;
+USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
+
+/**
+ * Modbus master input register callback function.
+ *
+ * @param pucRegBuffer input register buffer
+ * @param usAddress input register address
+ * @param usNRegs input register number
+ *
+ * @return result
+ */
+eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
+{
+ eMBErrorCode eStatus = MB_ENOERR;
+ USHORT iRegIndex;
+ USHORT * pusRegInputBuf;
+ USHORT REG_INPUT_START;
+ USHORT REG_INPUT_NREGS;
+ USHORT usRegInStart;
+
+ pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress() - 1];
+ REG_INPUT_START = M_REG_INPUT_START;
+ REG_INPUT_NREGS = M_REG_INPUT_NREGS;
+ usRegInStart = usMRegInStart;
+
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= REG_INPUT_START)
+ && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
+ {
+ iRegIndex = usAddress - usRegInStart;
+ while (usNRegs > 0)
+ {
+ pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
+ pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
+ iRegIndex++;
+ usNRegs--;
+ }
+ }
+ else
+ {
+ eStatus = MB_ENOREG;
+ }
+
+ return eStatus;
+}
+
+/**
+ * Modbus master holding register callback function.
+ *
+ * @param pucRegBuffer holding register buffer
+ * @param usAddress holding register address
+ * @param usNRegs holding register number
+ * @param eMode read or write
+ *
+ * @return result
+ */
+eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNRegs, eMBRegisterMode eMode)
+{
+ eMBErrorCode eStatus = MB_ENOERR;
+ USHORT iRegIndex;
+ USHORT * pusRegHoldingBuf;
+ USHORT REG_HOLDING_START;
+ USHORT REG_HOLDING_NREGS;
+ USHORT usRegHoldStart;
+
+ pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress() - 1];
+ REG_HOLDING_START = M_REG_HOLDING_START;
+ REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
+ usRegHoldStart = usMRegHoldStart;
+ /* if mode is read, the master will write the received date to buffer. */
+ eMode = MB_REG_WRITE;
+
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= REG_HOLDING_START)
+ && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
+ {
+ iRegIndex = usAddress - usRegHoldStart;
+ switch (eMode)
+ {
+ /* read current register values from the protocol stack. */
+ case MB_REG_READ:
+ while (usNRegs > 0)
+ {
+ *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
+ *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
+ iRegIndex++;
+ usNRegs--;
+ }
+ break;
+ /* write current register values with new values from the protocol stack. */
+ case MB_REG_WRITE:
+ while (usNRegs > 0)
+ {
+ pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
+ pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
+ iRegIndex++;
+ usNRegs--;
+ }
+ break;
+ }
+ }
+ else
+ {
+ eStatus = MB_ENOREG;
+ }
+ return eStatus;
+}
+
+/**
+ * Modbus master coils callback function.
+ *
+ * @param pucRegBuffer coils buffer
+ * @param usAddress coils address
+ * @param usNCoils coils number
+ * @param eMode read or write
+ *
+ * @return result
+ */
+eMBErrorCode eMBMasterRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNCoils, eMBRegisterMode eMode)
+{
+ eMBErrorCode eStatus = MB_ENOERR;
+ USHORT iRegIndex , iRegBitIndex , iNReg;
+ UCHAR * pucCoilBuf;
+ USHORT COIL_START;
+ USHORT COIL_NCOILS;
+ USHORT usCoilStart;
+ iNReg = usNCoils / 8 + 1;
+
+ pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress() - 1];
+ COIL_START = M_COIL_START;
+ COIL_NCOILS = M_COIL_NCOILS;
+ usCoilStart = usMCoilStart;
+
+ /* if mode is read,the master will write the received date to buffer. */
+ eMode = MB_REG_WRITE;
+
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= COIL_START)
+ && (usAddress + usNCoils <= COIL_START + COIL_NCOILS))
+ {
+ iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
+ iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
+ switch (eMode)
+ {
+ /* read current coil values from the protocol stack. */
+ case MB_REG_READ:
+ while (iNReg > 0)
+ {
+ *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
+ iRegBitIndex, 8);
+ iNReg--;
+ }
+ pucRegBuffer--;
+ /* last coils */
+ usNCoils = usNCoils % 8;
+ /* filling zero to high bit */
+ *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
+ *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
+ break;
+
+ /* write current coil values with new values from the protocol stack. */
+ case MB_REG_WRITE:
+ while (iNReg > 1)
+ {
+ xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
+ *pucRegBuffer++);
+ iNReg--;
+ }
+ /* last coils */
+ usNCoils = usNCoils % 8;
+ /* xMBUtilSetBits has bug when ucNBits is zero */
+ if (usNCoils != 0)
+ {
+ xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
+ *pucRegBuffer++);
+ }
+ break;
+ }
+ }
+ else
+ {
+ eStatus = MB_ENOREG;
+ }
+ return eStatus;
+}
+
+/**
+ * Modbus master discrete callback function.
+ *
+ * @param pucRegBuffer discrete buffer
+ * @param usAddress discrete address
+ * @param usNDiscrete discrete number
+ *
+ * @return result
+ */
+eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
+{
+ eMBErrorCode eStatus = MB_ENOERR;
+ USHORT iRegIndex , iRegBitIndex , iNReg;
+ UCHAR * pucDiscreteInputBuf;
+ USHORT DISCRETE_INPUT_START;
+ USHORT DISCRETE_INPUT_NDISCRETES;
+ USHORT usDiscreteInputStart;
+ iNReg = usNDiscrete / 8 + 1;
+
+ pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress() - 1];
+ DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
+ DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
+ usDiscreteInputStart = usMDiscInStart;
+
+ /* it already plus one in modbus function method. */
+ usAddress--;
+
+ if ((usAddress >= DISCRETE_INPUT_START)
+ && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
+ {
+ iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
+ iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
+
+ /* write current discrete values with new values from the protocol stack. */
+ while (iNReg > 1)
+ {
+ xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex, 8,
+ *pucRegBuffer++);
+ iNReg--;
+ }
+ /* last discrete */
+ usNDiscrete = usNDiscrete % 8;
+ /* xMBUtilSetBits has bug when ucNBits is zero */
+ if (usNDiscrete != 0)
+ {
+ xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
+ usNDiscrete, *pucRegBuffer++);
+ }
+ }
+ else
+ {
+ eStatus = MB_ENOREG;
+ }
+
+ return eStatus;
+}
+#endif