From 512db75675e31e97c20c403832c414aacf408efb Mon Sep 17 00:00:00 2001 From: qiuyiuestc Date: Tue, 6 Apr 2010 01:02:55 +0000 Subject: [PATCH] port freemodbus git-svn-id: https://rt-thread.googlecode.com/svn/trunk@582 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- net/freemodbus/SConscript | 33 ++++++ net/freemodbus/modbus/mbmaster.c | 68 +++++++++++ net/freemodbus/modbus/port/demo.c | 84 ++++++++++++++ net/freemodbus/modbus/port/port.c | 34 ++++++ net/freemodbus/modbus/port/port.h | 57 ++++++++++ net/freemodbus/modbus/port/portevent.c | 55 +++++++++ net/freemodbus/modbus/port/portserial.c | 143 ++++++++++++++++++++++++ net/freemodbus/modbus/port/porttimer.c | 64 +++++++++++ 8 files changed, 538 insertions(+) create mode 100644 net/freemodbus/SConscript create mode 100644 net/freemodbus/modbus/mbmaster.c create mode 100644 net/freemodbus/modbus/port/demo.c create mode 100644 net/freemodbus/modbus/port/port.c create mode 100644 net/freemodbus/modbus/port/port.h create mode 100644 net/freemodbus/modbus/port/portevent.c create mode 100644 net/freemodbus/modbus/port/portserial.c create mode 100644 net/freemodbus/modbus/port/porttimer.c diff --git a/net/freemodbus/SConscript b/net/freemodbus/SConscript new file mode 100644 index 0000000000..d0caef66a9 --- /dev/null +++ b/net/freemodbus/SConscript @@ -0,0 +1,33 @@ +Import('env') +Import('rtconfig') +Import('RTT_ROOT') + +src_local = Split(""" +modbus/mb.c +modbus/mbmaster.c +modbus/ascii/mbascii.c +modbus/functions/mbfunccoils.c +modbus/functions/mbfuncdiag.c +modbus/functions/mbfuncdisc.c +modbus/functions/mbfuncholding.c +modbus/functions/mbfuncinput.c +modbus/functions/mbfuncother.c +modbus/functions/mbutils.c +modbus/port/demo.c +modbus/port/port.c +modbus/port/portevent.c +modbus/port/portserial.c +modbus/port/porttimer.c +modbus/rtu/mbcrc.c +modbus/rtu/mbrtu.c +modbus/tcp/mbtcp.c +""") + +# The set of source files associated with this SConscript file. +path = [RTT_ROOT + '/net/freemodbus/modbus/include', RTT_ROOT + '/net/freemodbus/modbus/port', RTT_ROOT + '/net/freemodbus/modbus/rtu', RTT_ROOT + '/net/freemodbus/modbus/ascii'] + +env.Append(CPPPATH = path) + +obj = env.Object(src_local) + +Return('obj') diff --git a/net/freemodbus/modbus/mbmaster.c b/net/freemodbus/modbus/mbmaster.c new file mode 100644 index 0000000000..e3d1a5d3de --- /dev/null +++ b/net/freemodbus/modbus/mbmaster.c @@ -0,0 +1,68 @@ +/* + * File : mbmaster.c + * This file is part of freemodbus in RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-04 yi.qiu first version + */ + +/* ----------------------- Platform includes --------------------------------*/ +#include "rtthread.h" +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbconfig.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbfunc.h" + +eMBErrorCode eMBMReadHoldingRegisters (UCHAR ucSlaveAddress, USHORT usRegStartAddress, + UBYTE ubNRegs, USHORT arusBufferOut[]) +{ + static UCHAR ucMBFrame[5]; + eMBErrorCode eStatus = MB_ENOERR; + eMBEventType eEvent; + static UCHAR ucRcvAddress; + static USHORT usLength; + + /* make up request frame */ + ucMBFrame[0] = MB_FUNC_READ_HOLDING_REGISTER; + ucMBFrame[1] = (UCHAR)(usRegStartAddress >> 8); + ucMBFrame[2] = (UCHAR)(usRegStartAddress); + ucMBFrame[3] = (UCHAR)(ubNRegs >> 8); + ucMBFrame[4] = (UCHAR)(ubNRegs); + + + rt_kprintf("send frame [%x%x%x%x%x]\n", + ucMBFrame[0], ucMBFrame[1], ucMBFrame[2], ucMBFrame[3], ucMBFrame[4]); + + + /* send request frame to slave device */ + eStatus = eMBRTUSend( ucSlaveAddress, ucMBFrame, 5 ); + + /* wait on receive event */ + if( xMBPortEventGet( &eEvent ) == TRUE ) + { + eStatus = eMBRTUReceive( &ucRcvAddress, &ucMBFrame, &usLength ); + if( eStatus == MB_ENOERR ) + { + /* Check if the frame is for us. If not ignore the frame. */ + if( ( ucRcvAddress == ucSlaveAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) ) + { + /* parse and restore data */ + rt_kprintf("parse and restore date here\n"); + } + } + } + else eStatus = MB_ETIMEDOUT; + + return eStatus; +} + diff --git a/net/freemodbus/modbus/port/demo.c b/net/freemodbus/modbus/port/demo.c new file mode 100644 index 0000000000..e11a1e7ed7 --- /dev/null +++ b/net/freemodbus/modbus/port/demo.c @@ -0,0 +1,84 @@ +/* + * File : demo.c + * This file is part of freemodbus in RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-04 yi.qiu first version + */ + +/* ----------------------- Platform includes --------------------------------*/ +#include +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbconfig.h" +#include "mbframe.h" +#include "mbproto.h" +#include "mbfunc.h" + +void rt_modbus_thread_entry(void* parameter) +{ + eMBErrorCode eStatus; + USHORT buf[100]; + + eStatus = eMBInit( MB_RTU, 0x0A, 0, 115200, MB_PAR_EVEN ); + + /* Enable the Modbus Protocol Stack. */ + eStatus = eMBEnable( ); + rt_thread_delay(50); + + while(1) + { + + eMBMReadHoldingRegisters(0x0A, 0x10000, 0x1, buf); + rt_kprintf("stop\n"); + rt_thread_delay(100); + + //while(1); + } +} + +int modbus_demo_init(void) +{ + rt_thread_t modbus_thread; + + modbus_thread = rt_thread_create("modbus", + rt_modbus_thread_entry, RT_NULL, + 2048, 20, 20); + + if (modbus_thread != RT_NULL) + rt_thread_startup(modbus_thread); + + return 0; +} + +eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ) +{ + return MB_ENOREG; +} + +eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, + eMBRegisterMode eMode ) +{ + return MB_ENOREG; +} + + +eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, + eMBRegisterMode eMode ) +{ + return MB_ENOREG; +} + +eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) +{ + return MB_ENOREG; +} + diff --git a/net/freemodbus/modbus/port/port.c b/net/freemodbus/modbus/port/port.c new file mode 100644 index 0000000000..d5d3323a77 --- /dev/null +++ b/net/freemodbus/modbus/port/port.c @@ -0,0 +1,34 @@ +/* + * File : porttimer.c + * This file is part of freemodbus in RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-04 yi.qiu first version + */ + +/* ----------------------- System includes --------------------------------*/ +#include +#include + +/* ----------------------- Modbus includes ----------------------------------*/ + +/* ----------------------- Variables ----------------------------------------*/ +static int level; + +/* ----------------------- Start implementation -----------------------------*/ +void EnterCriticalSection(void) +{ + level = rt_hw_interrupt_disable(); +} + +void ExitCriticalSection(void) +{ + rt_hw_interrupt_enable(level); +} + diff --git a/net/freemodbus/modbus/port/port.h b/net/freemodbus/modbus/port/port.h new file mode 100644 index 0000000000..5d7b744ba2 --- /dev/null +++ b/net/freemodbus/modbus/port/port.h @@ -0,0 +1,57 @@ +/* + * FreeModbus Libary: BARE Port + * Copyright (C) 2006 Christian Walter + * + * 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: port.h,v 1.1 2007/04/24 23:15:18 wolti Exp $ + */ + +#ifndef _PORT_H +#define _PORT_H + +#include + +#define INLINE +#define PR_BEGIN_EXTERN_C extern "C" { +#define PR_END_EXTERN_C } + +#define assert(x) RT_ASSERT(x) +#define ENTER_CRITICAL_SECTION() EnterCriticalSection() +#define EXIT_CRITICAL_SECTION() ExitCriticalSection() + +void EnterCriticalSection( void ); +void ExitCriticalSection( void ); + +typedef rt_uint8_t BOOL; +typedef unsigned char UBYTE; +typedef unsigned char UCHAR; +typedef char CHAR; + +typedef rt_uint16_t USHORT; +typedef rt_int16_t SHORT; + +typedef rt_uint32_t ULONG; +typedef rt_int32_t LONG; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif diff --git a/net/freemodbus/modbus/port/portevent.c b/net/freemodbus/modbus/port/portevent.c new file mode 100644 index 0000000000..d048a28fb6 --- /dev/null +++ b/net/freemodbus/modbus/port/portevent.c @@ -0,0 +1,55 @@ +/* + * File : portevent.c + * This file is part of freemodbus in RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-04 yi.qiu first version + */ + +/* ----------------------- Modbus includes ----------------------------------*/ +#include + +#include "mb.h" +#include "mbport.h" + +/* ----------------------- Variables ----------------------------------------*/ +static struct rt_event event; + +/* ----------------------- Start implementation -----------------------------*/ +BOOL xMBPortEventInit( void ) +{ + rt_event_init(&event, "modbus", RT_IPC_FLAG_FIFO); + + return TRUE; +} + +BOOL xMBPortEventPost( eMBEventType eEvent ) +{ + /* only care abot EV_FRAME_RECEIVED event */ + if(eEvent == EV_FRAME_RECEIVED) + rt_event_send(&event, 1< + +#include "port.h" +#include "serial.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbport.h" + +#define UART1 ((struct uartport *)U1BASE) + +/* ----------------------- static functions ---------------------------------*/ +static void rt_serial1_handler(int vector); +static void prvvUARTTxReadyISR(void); +static void prvvUARTRxISR(void); +extern rt_uint32_t PCLK; + +/* ----------------------- Start implementation -----------------------------*/ +void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) +{ + if( xRxEnable ) + { + INTSUBMSK &= ~(BIT_SUB_RXD1); + } + else + { + INTSUBMSK |= (BIT_SUB_RXD1); + } + if( xTxEnable ) + { + INTSUBMSK &= ~(BIT_SUB_TXD1); + prvvUARTTxReadyISR(); + } + else + { + INTSUBMSK |= (BIT_SUB_TXD1); + } +} + +void vMBPortClose( void ) +{ + /* null */ +} + +BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) +{ + int i; + + /* FIFO enable, Tx/Rx FIFO clear */ + UART1->ufcon = 0x0; + /* disable the flow control */ + UART1->umcon = 0x0; + /* Normal,No parity,1 stop,8 bit */ + UART1->ulcon = 0x3; + /* + * tx=level,rx=edge,disable timeout int.,enable rx error int. + * normal,interrupt or polling + */ + UART1->ucon = 0x245; + /* Set uart0 bps */ + UART1->ubrd = (rt_int32_t)(PCLK / (ulBaudRate * 16)) - 1; + + for (i = 0; i < 100; i++); + + SUBSRCPND |= BIT_SUB_RXD1; + SUBSRCPND |= BIT_SUB_TXD1; + + rt_hw_interrupt_install(INTUART1, rt_serial1_handler, RT_NULL); + rt_hw_interrupt_umask(INTUART1); + + return TRUE; +} + +BOOL xMBPortSerialPutByte( CHAR ucByte ) +{ + /* wait for room in the transmit FIFO */ + while(!(USTAT1 & USTAT_TXB_EMPTY)); + + UTXH1 = (UCHAR)ucByte; + + return TRUE; +} + +BOOL xMBPortSerialGetByte( CHAR * pucByte ) +{ + while ((USTAT1 & USTAT_RCV_READY) == 0); + + *pucByte = URXB1; + + return TRUE; +} + +static void rt_serial1_handler(int vector) +{ + + if (SUBSRCPND & BIT_SUB_RXD1) + { + SUBSRCPND |= BIT_SUB_RXD1; + prvvUARTRxISR(); + } + if (SUBSRCPND & BIT_SUB_TXD1) + { + SUBSRCPND |= BIT_SUB_TXD1; + prvvUARTTxReadyISR(); + } +} + +/* + * Create an interrupt handler for the transmit buffer empty interrupt + * (or an equivalent) for your target processor. This function should then + * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that + * a new character can be sent. The protocol stack will then call + * xMBPortSerialPutByte( ) to send the character. + */ +static void prvvUARTTxReadyISR( void ) +{ + pxMBFrameCBTransmitterEmpty( ); +} + +/* + * Create an interrupt handler for the receive interrupt for your target + * processor. This function should then call pxMBFrameCBByteReceived( ). The + * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the + * character. + */ +static void prvvUARTRxISR( void ) +{ + pxMBFrameCBByteReceived( ); +} diff --git a/net/freemodbus/modbus/port/porttimer.c b/net/freemodbus/modbus/port/porttimer.c new file mode 100644 index 0000000000..46c8af774f --- /dev/null +++ b/net/freemodbus/modbus/port/porttimer.c @@ -0,0 +1,64 @@ +/* + * File : porttimer.c + * This file is part of freemodbus in RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-04-04 yi.qiu first version + */ + +/* ----------------------- Platform includes --------------------------------*/ +#include + +#include +#include "port.h" + +/* ----------------------- Modbus includes ----------------------------------*/ +#include "mb.h" +#include "mbport.h" + +/* ----------------------- static functions ---------------------------------*/ +static void prvvTIMERExpiredISR( void ); +extern rt_uint32_t PCLK; + +/* ----------------------- Start implementation -----------------------------*/ +BOOL xMBPortTimersInit(USHORT usTim1Timerout50us) +{ + /* all are interrupt mode,set Timer 3 MUX 1/4 */ + TCFG1 &= 0xffff0fff; + TCFG1 |= 0x00001000; + + TCNTB3 = (rt_int32_t)(usTim1Timerout50us*(PCLK/ (4 *16* 20000))) - 1; + /* manual update */ + TCON = TCON & (~(0x0f<<16)) | (0x02<<16); + /* install interrupt handler */ + rt_hw_interrupt_install(INTTIMER3, prvvTIMERExpiredISR, RT_NULL); + rt_hw_interrupt_umask(INTTIMER3); + + /* start timer4, reload */ + TCON = TCON & (~(0x0f<<16)) | (0x09<<16); + + return TRUE; +} + +void vMBPortTimersEnable(void) +{ + /* start timer4, reload */ + TCON = TCON & (~(0x0f<<16)) | (0x09<<16); +} + +void vMBPortTimersDisable(void) +{ + TCON = TCON & (~(0x01<<16)); +} + +static void prvvTIMERExpiredISR( void ) +{ + (void)pxMBPortCBTimerExpired(); +} +