mbfuncholding.c
上传用户:kongshuqi
上传日期:2013-10-09
资源大小:59k
文件大小:8k
源码类别:

通讯编程

开发平台:

Visual C++

  1.  /*
  2.   * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS
  3.   * Copyright (C) 2006 Christian Walter <wolti@sil.at>
  4.   *
  5.   * This library is free software; you can redistribute it and/or
  6.   * modify it under the terms of the GNU Lesser General Public
  7.   * License as published by the Free Software Foundation; either
  8.   * version 2.1 of the License, or (at your option) any later version.
  9.   *
  10.   * This library is distributed in the hope that it will be useful,
  11.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.   * Lesser General Public License for more details.
  14.   *
  15.   * You should have received a copy of the GNU Lesser General Public
  16.   * License along with this library; if not, write to the Free Software
  17.   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18.   */
  19. /* ----------------------- System includes ----------------------------------*/
  20. #include "stdlib.h"
  21. #include "string.h"
  22. /* ----------------------- Platform includes --------------------------------*/
  23. #include "port.h"
  24. /* ----------------------- Modbus includes ----------------------------------*/
  25. #include "mb.h"
  26. #include "mbframe.h"
  27. #include "mbproto.h"
  28. #include "mbconfig.h"
  29. /* ----------------------- Defines ------------------------------------------*/
  30. #define MB_PDU_FUNC_READ_ADDR_OFF           ( MB_PDU_DATA_OFF )
  31. #define MB_PDU_FUNC_READ_REGCNT_OFF         ( MB_PDU_DATA_OFF + 2 )
  32. #define MB_PDU_FUNC_READ_SIZE               ( 4 )
  33. #define MB_PDU_FUNC_READ_REGCNT_MAX         ( 0x007D )
  34. #define MB_PDU_FUNC_WRITE_ADDR_OFF          ( MB_PDU_DATA_OFF )
  35. #define MB_PDU_FUNC_WRITE_VALUE_OFF         ( MB_PDU_DATA_OFF + 2 )
  36. #define MB_PDU_FUNC_WRITE_SIZE              ( 4 )
  37. #define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF      ( MB_PDU_DATA_OFF )
  38. #define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF    ( MB_PDU_DATA_OFF + 2 )
  39. #define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF   ( MB_PDU_DATA_OFF + 4 )
  40. #define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF    ( MB_PDU_DATA_OFF + 5 )
  41. #define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN      ( 5 )
  42. #define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX    ( 0x0078 )
  43. /* ----------------------- Static functions ---------------------------------*/
  44. eMBException    prveMBError2Exception( eMBErrorCode eErrorCode );
  45. /* ----------------------- Start implementation -----------------------------*/
  46. #if MB_FUNC_WRITE_HOLDING_ENABLED > 0
  47. eMBException
  48. eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
  49. {
  50.     USHORT          usRegAddress;
  51.     eMBException    eStatus = MB_EX_NONE;
  52.     eMBErrorCode    eRegStatus;
  53.     if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
  54.     {
  55.         usRegAddress = pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8;
  56.         usRegAddress |= pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1];
  57.         usRegAddress++;
  58.         /* Make callback to update the value. */
  59.         eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
  60.                                       usRegAddress, 1, MB_REG_WRITE );
  61.         /* If an error occured convert it into a Modbus exception. */
  62.         if( eRegStatus != MB_ENOERR )
  63.         {
  64.             eStatus = prveMBError2Exception( eRegStatus );
  65.         }
  66.     }
  67.     else
  68.     {
  69.         /* Can't be a valid request because the length is incorrect. */
  70.         eStatus = MB_EX_ILLEGAL_DATA_VALUE;
  71.     }
  72.     return eStatus;
  73. }
  74. #endif
  75. #if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
  76. eMBException
  77. eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
  78. {
  79.     USHORT          usRegAddress;
  80.     USHORT          usRegCount;
  81.     UCHAR           ucRegByteCount;
  82.     eMBException    eStatus = MB_EX_NONE;
  83.     eMBErrorCode    eRegStatus;
  84.     if( *usLen >= ( MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + MB_PDU_SIZE_MIN ) )
  85.     {
  86.         usRegAddress = pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8;
  87.         usRegAddress |= pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1];
  88.         usRegAddress++;
  89.         usRegCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8;
  90.         usRegCount |= pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1];
  91.         ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
  92.         if( ( usRegCount >= 1 ) &&
  93.             ( usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ) &&
  94.             ( ucRegByteCount == ( UCHAR )( 2 * usRegCount ) ) )
  95.         {
  96.             /* Make callback to update the register values. */
  97.             eRegStatus =
  98.                 eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
  99.                                  usRegAddress, usRegCount, MB_REG_WRITE );
  100.             /* If an error occured convert it into a Modbus exception. */
  101.             if( eRegStatus != MB_ENOERR )
  102.             {
  103.                 eStatus = prveMBError2Exception( eRegStatus );
  104.             }
  105.             else
  106.             {
  107.                 /* The response contains the function code, the starting
  108.                  * address and the quantity of registers. We reuse the
  109.                  * old values in the buffer because they are still valid.
  110.                  */
  111.                 *usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
  112.             }
  113.         }
  114.         else
  115.         {
  116.             eStatus = MB_EX_ILLEGAL_DATA_VALUE;
  117.         }
  118.     }
  119.     else
  120.     {
  121.         /* Can't be a valid request because the length is incorrect. */
  122.         eStatus = MB_EX_ILLEGAL_DATA_VALUE;
  123.     }
  124.     return eStatus;
  125. }
  126. #endif
  127. #if MB_FUNC_READ_HOLDING_ENABLED > 0
  128. eMBException
  129. eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
  130. {
  131.     USHORT          usRegAddress;
  132.     USHORT          usRegCount;
  133.     UCHAR          *pucFrameCur;
  134.     eMBException    eStatus = MB_EX_NONE;
  135.     eMBErrorCode    eRegStatus;
  136.     if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
  137.     {
  138.         usRegAddress = pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8;
  139.         usRegAddress |= pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1];
  140.         usRegAddress++;
  141.         usRegCount = pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8;
  142.         usRegCount = pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1];
  143.         /* Check if the number of registers to read is valid. If not
  144.          * return Modbus illegal data value exception. 
  145.          */
  146.         if( ( usRegCount >= 1 )
  147.             && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
  148.         {
  149.             /* Set the current PDU data pointer to the beginning. */
  150.             pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
  151.             *usLen = MB_PDU_FUNC_OFF;
  152.             /* First byte contains the function code. */
  153.             *pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
  154.             *usLen += 1;
  155.             /* Second byte in the response contain the number of bytes. */
  156.             *pucFrameCur++ = ( UCHAR )( usRegCount * 2 );
  157.             *usLen += 1;
  158.             /* Make callback to fill the buffer. */
  159.             eRegStatus =
  160.                 eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount,
  161.                                  MB_REG_READ );
  162.             /* If an error occured convert it into a Modbus exception. */
  163.             if( eRegStatus != MB_ENOERR )
  164.             {
  165.                 eStatus = prveMBError2Exception( eRegStatus );
  166.             }
  167.             else
  168.             {
  169.                 *usLen += usRegCount * 2;
  170.             }
  171.         }
  172.         else
  173.         {
  174.             eStatus = MB_EX_ILLEGAL_DATA_VALUE;
  175.         }
  176.     }
  177.     else
  178.     {
  179.         /* Can't be a valid request because the length is incorrect. */
  180.         eStatus = MB_EX_ILLEGAL_DATA_VALUE;
  181.     }
  182.     return eStatus;
  183. }
  184. #endif