2024-07-08 10:27:17 +08:00
# include "host_modbus_rtu.h"
///////////////////////////////////////////////////////////////////////////////////
//Valid slave device addresses are in the range of 0 ? 247 decimal. //
//The individual slave devices are assigned addresses in the range of 1 ? 247. //
//Address 0 is used for the broadcast address, which all slave devices recognize.//
// 在 RTU 模式, 报文帧由时长至少为3.5 个字符时间的空闲间隔区分。
// 假如通信波特率为 19200, 那么:
// 1.5 个字符间隔 = 1/19200 *11*1.5*1000=0.86ms
// 3.5 个字符间隔 = 1/19200 *11*3.5*1000=2ms
// 在通信速率等于或低于19200 Bps 时,这两个定时必须严格遵守;
// 对于波特率大于19200 Bps 的情形, 应该使用2 个定时的固定值:建议的字符间超时时间(t1.5)为750μs, 帧间的超时时间(t1.5) 为1.750ms。
/////////////////////////////////////////////////////////////////////////////////
CHostModbusRtuProcessItem : : CHostModbusRtuProcessItem ( )
{
m_nFramePoll = 0 ;
m_nPollCount = - 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
}
CHostModbusRtuProcessItem : : ~ CHostModbusRtuProcessItem ( )
{
m_nFramePoll = 0 ;
m_nPollCount = - 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
}
void CHostModbusRtuProcessItem : : AddFrames ( struModbusExtFrame * yxs , struModbusExtFrame * ycs , struModbusExtFrame * yms )
{
int i = 0 , j = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + ) {
if ( yxs [ j ] . FrameType = = 0 | | yxs [ j ] . FuncCode = = 0 | | yxs [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & yxs [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + ) {
if ( ycs [ j ] . FrameType = = 0 | | ycs [ j ] . FuncCode = = 0 | | ycs [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & ycs [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + ) {
if ( yms [ j ] . FrameType = = 0 | | yms [ j ] . FuncCode = = 0 | | yms [ j ] . RegCount = = 0 ) continue ;
memcpy ( & m_nModbusFrames [ i ] , & yms [ j ] , sizeof ( struModbusExtFrame ) ) ;
i + + ;
if ( i > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) break ;
}
}
struModbusExtFrame * CHostModbusRtuProcessItem : : GetNextFrame ( void )
{
int last ;
if ( m_nCurFrame > = MODBUS_RTU_AUTOMATIC_FRAME_MAX ) return NULL ;
if ( m_nCurFrame < 0 ) m_nCurFrame = - 1 ;
last = m_nCurFrame ;
for ( m_nCurFrame + + ; m_nCurFrame < MODBUS_RTU_AUTOMATIC_FRAME_MAX ; m_nCurFrame + + ) {
if ( m_nModbusFrames [ m_nCurFrame ] . FuncCode = = 0 | | m_nModbusFrames [ m_nCurFrame ] . FrameType = = 0 ) break ;
return & m_nModbusFrames [ m_nCurFrame ] ;
}
for ( m_nCurFrame = 0 ; m_nCurFrame < = last ; m_nCurFrame + + ) {
if ( m_nModbusFrames [ m_nCurFrame ] . FuncCode = = 0 | | m_nModbusFrames [ m_nCurFrame ] . FrameType = = 0 ) break ;
return & m_nModbusFrames [ m_nCurFrame ] ;
}
return NULL ;
}
void CHostModbusRtuProcessItem : : Attach ( int uid , int physicsAddress /* = 0 */ , int commonAddress /* = 0 */ , int originatorAddress /* = 0 */ )
{
CPortProcessItem : : Attach ( uid , physicsAddress ) ;
m_nFramePoll = 0 ;
m_nPollCount = - 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
}
void CHostModbusRtuProcessItem : : Release ( void )
{
m_nFramePoll = 0 ;
m_nPollCount = - 1 ;
m_nCurFrame = 0 ;
memset ( m_nModbusFrames , 0 , sizeof ( m_nModbusFrames ) ) ;
CPortProcessItem : : Release ( ) ;
}
CHostModbusRtuProcess : : CHostModbusRtuProcess ( )
{
m_nNeedCount = 2 ;
m_nState = MODBUSS_SYNC ;
m_nCount = 0 ;
m_nFrameCount = 0 ;
m_nCurFrame = 0 ;
m_nSendPoint = 0 ;
m_nCurBeginReg = 0 ;
m_nNeedSend = FALSE ;
m_nFramePoll = 0 ;
}
CHostModbusRtuProcess : : ~ CHostModbusRtuProcess ( )
{
}
CPortProcessItem * CHostModbusRtuProcess : : CreateItem ( int ord )
{
return dynamic_cast < CPortProcessItem * > ( new CHostModbusRtuProcessItem ) ;
}
void CHostModbusRtuProcess : : DestroyItem ( int ord , BOOLEAN bDeleted /* = FALSE */ )
{
CHostModbusRtuProcessItem * pItem = ( CHostModbusRtuProcessItem * ) GetItem ( ord ) ;
if ( pItem ! = NULL & & ! bDeleted )
{
delete pItem ;
return CPortProcess : : DestroyItem ( ord , TRUE ) ;
}
return CPortProcess : : DestroyItem ( ord , bDeleted ) ;
}
void CHostModbusRtuProcess : : sort1 ( STRUCT_PARAM * params , int count )
{
int i , j , n ;
STRUCT_PARAM temp ;
n = count ;
for ( i = 0 ; i < n - 1 ; + + i )
{ //比较n-1轮
for ( j = 0 ; j < n - 1 - i ; + + j )
{ //每轮比较n-1-i次,
if ( params [ j ] . param [ 0 ] > params [ j + 1 ] . param [ 0 ] )
{
memcpy ( & temp , & params [ j ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j ] , & params [ j + 1 ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j + 1 ] , & temp , sizeof ( STRUCT_PARAM ) ) ;
}
}
}
}
void CHostModbusRtuProcess : : sort2 ( STRUCT_PARAM * params , int count )
{
int i , j , n ;
STRUCT_PARAM temp ;
n = count ;
for ( i = 0 ; i < n - 1 ; + + i ) { //比较n-1轮
for ( j = 0 ; j < n - 1 - i ; + + j )
{ //每轮比较n-1-i次,
int addr1 = ( int ) MAKEWORD ( params [ j ] . param [ 1 ] , params [ j ] . param [ 2 ] ) ;
int addr2 = ( int ) MAKEWORD ( params [ j + 1 ] . param [ 1 ] , params [ j + 1 ] . param [ 2 ] ) ;
if ( addr1 > addr2 )
{
memcpy ( & temp , & params [ j ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j ] , & params [ j + 1 ] , sizeof ( STRUCT_PARAM ) ) ;
memcpy ( & params [ j + 1 ] , & temp , sizeof ( STRUCT_PARAM ) ) ;
}
}
}
}
void CHostModbusRtuProcess : : calc1 ( void )
{
int i , j , n , uid ;
BYTE addr ;
CHostModbusRtuProcessItem * pItem ;
for ( i = 0 ; i < PROCESS_UNIT_NUM ; i + + )
{
pItem = ( CHostModbusRtuProcessItem * ) GetItem ( i ) ;
if ( NULL = = pItem ) continue ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) continue ;
if ( GetUnitAddr ( uid , & addr , 1 ) )
{ //获取单元地址成功,则该段原地址采用配置地址,否则该单元为无效地址。
pItem - > Attach ( uid , addr ) ;
}
struModbusExtFrame ycframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
struModbusExtFrame ymframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
struModbusExtFrame yxframes [ MODBUS_RTU_AUTOMATIC_FRAME ] ;
memset ( ycframes , 0 , sizeof ( ycframes ) ) ;
memset ( ymframes , 0 , sizeof ( ymframes ) ) ;
memset ( yxframes , 0 , sizeof ( yxframes ) ) ;
struUnitModbusOption option ;
if ( GetUnitOption ( uid , & option , sizeof ( option ) ) )
{
if ( option . use_owner_config )
{ //采用协议配置
if ( option . modbus . yx1Enable )
{
yxframes [ 0 ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ 0 ] . FuncCode = option . modbus . yx1FuncCode ;
yxframes [ 0 ] . RegBegin = option . modbus . yx1Begin ;
yxframes [ 0 ] . RegCount = option . modbus . yx1Count ;
}
if ( option . modbus . yx2Enable )
{
yxframes [ 1 ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ 1 ] . FuncCode = option . modbus . yx2FuncCode ;
yxframes [ 1 ] . RegBegin = option . modbus . yx2Begin ;
yxframes [ 1 ] . RegCount = option . modbus . yx2Count ;
}
if ( option . modbus . yc1Enable )
{
ycframes [ 0 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 0 ] . FuncCode = option . modbus . yc1FuncCode ;
ycframes [ 0 ] . RegBegin = option . modbus . yc1Begin ;
ycframes [ 0 ] . RegCount = option . modbus . yc1Count ;
}
if ( option . modbus . yc2Enable )
{
ycframes [ 1 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 1 ] . FuncCode = option . modbus . yc2FuncCode ;
ycframes [ 1 ] . RegBegin = option . modbus . yc2Begin ;
ycframes [ 1 ] . RegCount = option . modbus . yc2Count ;
}
if ( option . modbus . yc3Enable )
{
ycframes [ 2 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 2 ] . FuncCode = option . modbus . yc3FuncCode ;
ycframes [ 2 ] . RegBegin = option . modbus . yc3Begin ;
ycframes [ 2 ] . RegCount = option . modbus . yc3Count ;
}
if ( option . modbus . yc4Enable )
{
ycframes [ 3 ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ 3 ] . FuncCode = option . modbus . yc4FuncCode ;
ycframes [ 3 ] . RegBegin = option . modbus . yc4Begin ;
ycframes [ 3 ] . RegCount = option . modbus . yc4Count ;
}
if ( option . modbus . ym1Enable )
{
ymframes [ 0 ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ 0 ] . FuncCode = option . modbus . ym1FuncCode ;
ymframes [ 0 ] . RegBegin = option . modbus . ym1Begin ;
ymframes [ 0 ] . RegCount = option . modbus . ym1Count ;
}
if ( option . modbus . ym2Enable )
{
ymframes [ 1 ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ 1 ] . FuncCode = option . modbus . ym2FuncCode ;
ymframes [ 1 ] . RegBegin = option . modbus . ym2Begin ;
ymframes [ 1 ] . RegCount = option . modbus . ym2Count ;
}
//按寄存器排序
pItem - > AddFrames ( ycframes , ymframes , yxframes ) ;
continue ;
}
}
{
int yccount , ymcount , yxcount ;
yccount = GetUnitYCCount ( uid ) ;
ymcount = GetUnitYMCount ( uid ) ;
yxcount = GetUnitYXCount ( uid ) ;
STRUCT_PARAM * ycparam = NULL , * ymparam = NULL , * yxparam = NULL ;
if ( yccount ) ycparam = new STRUCT_PARAM [ yccount ] ;
if ( ymcount ) ymparam = new STRUCT_PARAM [ ymcount ] ;
if ( yxcount ) yxparam = new STRUCT_PARAM [ yxcount ] ;
if ( ycparam )
{
memset ( ycparam , 0 , sizeof ( STRUCT_PARAM ) * yccount ) ;
for ( n = 0 ; n < yccount ; n + + )
{
memcpy ( ycparam [ n ] . param , GetUnitYCParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
//按功能码排序
sort1 ( ycparam , yccount ) ;
//按寄存器地址排序
sort2 ( ycparam , yccount ) ;
//组帧
for ( n = 0 ; n < yccount ; n + + )
{
WORD addr = MAKEWORD ( ycparam [ n ] . param [ 1 ] , ycparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( ycframes [ j ] . FuncCode = = 0 )
{
ycframes [ j ] . FrameType = MODBUSP_READ_YC1 ;
ycframes [ j ] . FuncCode = ycparam [ n ] . param [ 0 ] ;
ycframes [ j ] . RegBegin = addr ;
ycframes [ j ] . RegCount = ycparam [ n ] . param [ 3 ] ;
break ;
}
if ( ycframes [ j ] . FuncCode = = ycparam [ n ] . param [ 0 ] )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + ycframes [ j ] . RegBegin )
{
int len = addr - ycframes [ j ] . RegBegin ;
if ( len )
{
ycframes [ j ] . RegCount = len + ycparam [ n ] . param [ 3 ] ;
}
else
{
vLog ( LOG_DEBUG , " 遥测测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
2024-11-27 11:56:30 +08:00
delete [ ] ycparam ;
2024-07-08 10:27:17 +08:00
}
if ( ymparam )
{
memset ( ymparam , 0 , sizeof ( STRUCT_PARAM ) * ymcount ) ;
for ( n = 0 ; n < ymcount ; n + + )
{
memcpy ( ymparam [ n ] . param , GetUnitYMParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
sort1 ( ymparam , ymcount ) ;
sort2 ( ymparam , ymcount ) ;
//组帧
for ( n = 0 ; n < ymcount ; n + + )
{
WORD addr = MAKEWORD ( ymparam [ n ] . param [ 1 ] , ymparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( ymframes [ j ] . FuncCode = = 0 )
{
ymframes [ j ] . FrameType = MODBUSP_READ_YM1 ;
ymframes [ j ] . FuncCode = ymparam [ n ] . param [ 0 ] ;
ymframes [ j ] . RegBegin = addr ;
ymframes [ j ] . RegCount = ymparam [ n ] . param [ 3 ] ;
break ;
}
if ( ymframes [ j ] . FuncCode = = ymparam [ n ] . param [ 0 ] )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + ymframes [ j ] . RegBegin )
{
int len = addr - ymframes [ j ] . RegBegin ;
if ( len )
{
ymframes [ j ] . RegCount = len + ymparam [ n ] . param [ 3 ] ;
}
else
{
vLog ( LOG_DEBUG , " 遥脉测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
2024-11-27 11:56:30 +08:00
delete [ ] ymparam ;
2024-07-08 10:27:17 +08:00
}
if ( yxparam )
{
memset ( yxparam , 0 , sizeof ( STRUCT_PARAM ) * yxcount ) ;
for ( n = 0 ; n < yxcount ; n + + )
{
memcpy ( yxparam [ n ] . param , GetUnitYXParamByPoint ( uid , n ) , sizeof ( STRUCT_PARAM ) ) ;
}
sort1 ( yxparam , yxcount ) ;
sort2 ( yxparam , yxcount ) ;
//组帧
for ( n = 0 ; n < yxcount ; n + + )
{
WORD addr = MAKEWORD ( yxparam [ n ] . param [ 1 ] , yxparam [ n ] . param [ 2 ] ) ;
if ( addr > = 65535 ) continue ;
for ( j = 0 ; j < MODBUS_RTU_AUTOMATIC_FRAME ; j + + )
{
if ( yxframes [ j ] . FuncCode = = 0 )
{
yxframes [ j ] . FrameType = MODBUSP_READ_YX1 ;
yxframes [ j ] . FuncCode = yxparam [ n ] . param [ 0 ] ;
yxframes [ j ] . RegBegin = addr ;
yxframes [ j ] . RegCount = 1 ;
break ;
}
if ( yxframes [ j ] . FuncCode = = yxparam [ n ] . param [ 0 ] )
{
int len = addr - yxframes [ j ] . RegBegin ;
if ( len )
{
if ( yxframes [ j ] . FuncCode = = MODBUSC_F01 | | yxframes [ j ] . FuncCode = = MODBUSC_F02 )
{
if ( addr < = MODBUS_MAX_BITMAP_REGISTER_NUM + yxframes [ j ] . RegBegin )
{
yxframes [ j ] . RegCount = len + 1 ;
break ;
}
}
else if ( yxframes [ j ] . FuncCode = = MODBUSC_F03 | | yxframes [ j ] . FuncCode = = MODBUSC_F04 )
{
if ( addr < = MODBUS_MAX_WORD_REGISTER_NUM + yxframes [ j ] . RegBegin )
{
yxframes [ j ] . RegCount = len + 1 ;
break ;
}
}
}
else
{
if ( yxframes [ j ] . FuncCode = = MODBUSC_F01 | | yxframes [ j ] . FuncCode = = MODBUSC_F02 )
{
vLog ( LOG_DEBUG , " 遥信测点配置了相同的功能码和寄存器地址 \n " ) ;
}
break ;
}
}
}
}
2024-11-27 11:56:30 +08:00
delete [ ] yxparam ;
2024-07-08 10:27:17 +08:00
}
//按寄存器排序
pItem - > AddFrames ( ycframes , ymframes , yxframes ) ;
}
}
}
BOOLEAN CHostModbusRtuProcess : : OnPreCreate ( int id )
{
if ( ! CPortProcess : : OnPreCreate ( id ) ) return FALSE ;
m_nTimeout = GetTimeout ( ) ;
calc1 ( ) ;
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : Run ( void )
{
int count ;
BOOLEAN bFailed ;
WORD checkSum ;
BYTE buffer [ 512 ] ;
if ( ! CPortProcess : : Run ( ) ) return FALSE ;
//////////////////////////////////////////////////
// process recv data //
//////////////////////////////////////////////////
if ( m_nNeedCount < 2 ) m_nNeedCount = 2 ;
if ( GetDataCount ( ) > = m_nNeedCount )
{
if ( ! GetData ( buffer , m_nNeedCount ) )
{
vLog ( LOG_ERROR , " %s GetData() ERROR! \n " , __FILE__ ) ;
}
FeedDog ( ) ;
bFailed = FALSE ;
if ( m_nState = = MODBUSS_CTRL )
{
if ( ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F01 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F02 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F03 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F04 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F05 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F06 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F07 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F08 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F11 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F12 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F15 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F16 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F17 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F20 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F21 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F22 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F23 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F24 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F43 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F26 ) ) {
bFailed = TRUE ;
}
else if ( ( buffer [ 1 ] & 0x80 ) = = 0x80 )
{
m_nNeedCount = ( 4 + 1 ) ; //1个地址 1个功能码 2个CRC 1个错误码
m_nState = MODBUSS_INFO ;
}
else {
switch ( buffer [ 1 ] )
{ //根据功能码获取需要数据长度
case MODBUSC_F01 :
case MODBUSC_F02 :
case MODBUSC_F03 :
case MODBUSC_F04 :
m_nNeedCount = ( buffer [ 2 ] + 4 + 1 ) ; //1个地址 1个功能码 2个CRC 1个长度
break ;
case MODBUSC_F05 :
case MODBUSC_F06 :
case MODBUSC_F15 :
case MODBUSC_F16 :
m_nNeedCount = ( 4 + 2 + 2 ) ; //1个地址 1个功能码 2个CRC 2个寄存器地址 2个寄存器值
break ;
case MODBUSC_F07 :
case MODBUSC_F08 :
case MODBUSC_F11 :
case MODBUSC_F12 :
case MODBUSC_F17 :
break ;
case MODBUSC_F20 :
case MODBUSC_F21 :
m_nNeedCount = ( buffer [ 2 ] + 4 + 1 ) ; //1个地址 1个功能码 2个CRC 1个长度
break ;
case MODBUSC_F22 :
m_nNeedCount = ( 4 + 2 + 2 + 2 ) ; //1个地址 1个功能码 2个CRC 2个参考地址 2个And_Mask 2个Or_Mask
break ;
case MODBUSC_F23 :
m_nNeedCount = ( buffer [ 2 ] + 4 + 1 ) ; //1个地址 1个功能码 2个CRC 1个长度
break ;
case MODBUSC_F24 :
break ;
case MODBUSC_F43 :
m_nNeedCount = ( 4 + 9 ) ;
break ;
case MODBUSC_F26 :
m_nNeedCount = ( buffer [ 2 ] + 4 + 1 ) ; //1个地址 1个功能码 2个CRC 1个长度
break ;
}
if ( m_nNeedCount > 255 )
{
vLog ( LOG_ERROR , " data received error. m_nNeedCount is: %d too long for the buf. \r \n " , m_nNeedCount ) ;
bFailed = TRUE ;
}
else {
m_nState = MODBUSS_INFO ;
}
}
}
else if ( m_nState = = MODBUSS_INFO )
{
if ( ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F01 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F02 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F03 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F04 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F05 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F06 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F07 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F08 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F11 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F12 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F15 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F16 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F17 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F20 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F21 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F22 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F23 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F24 ) & &
( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F43 ) & & ( ( buffer [ 1 ] & 0x7f ) ! = MODBUSC_F26 ) )
{
bFailed = TRUE ;
}
else
{
checkSum = buffer [ m_nNeedCount - 2 ] ;
checkSum < < = 8 ;
checkSum & = 0xff00 ;
checkSum | = buffer [ m_nNeedCount - 1 ] ;
if ( checkSum ! = GetCRC16 ( buffer , m_nNeedCount - 2 ) )
{
bFailed = TRUE ;
}
else
{
DropData ( m_nNeedCount ) ;
if ( ( buffer [ 1 ] & 0x80 ) = = 0x80 )
{
m_nCurFrame = 0 ;
}
//process data
else
{
if ( OnReceiveData ( buffer , buffer [ 2 ] ) )
{
m_nCurFrame = 0 ;
}
}
DisplayRxData ( buffer , m_nNeedCount , TRUE ) ;
m_nState = MODBUSS_SYNC ;
}
}
}
else
{
if ( ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F01 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F02 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F03 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F04 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F05 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F06 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F07 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F08 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F11 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F12 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F15 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F16 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F17 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F20 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F21 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F22 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F23 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F24 ) | |
( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F43 ) | | ( ( buffer [ 1 ] & 0x7f ) = = MODBUSC_F26 ) )
{
m_nNeedCount = 3 ;
m_nState = MODBUSS_CTRL ;
}
else
{
m_nNeedCount = 2 ;
bFailed = TRUE ;
}
}
if ( bFailed )
{
DropData ( 1 ) ;
DisplayRxData ( buffer , 1 , FALSE ) ;
m_nNeedCount = 2 ;
m_nState = MODBUSS_SYNC ;
}
}
//////////////////////////////////////////////////
// process recv data //
//////////////////////////////////////////////////
//process polling command
int uid ;
CHostModbusRtuProcessItem * pItem = ( CHostModbusRtuProcessItem * ) GetCurItem ( ) ;
if ( NULL = = pItem ) return TRUE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return TRUE ;
if ( GetSpace ( ) = = MAX_PORT_BUFFER_SIZE & & ( m_nCurFrame = = 0 ) & & m_nNeedSend )
{
count = 0 ;
if ( GetYKFrame ( pItem , buffer , count , m_nCurFrame ) )
{ //insert yk command
}
else if ( GetYTFrame ( pItem , buffer , count , m_nCurFrame ) )
{ //insert yt command
}
else if ( pItem - > m_nFramePoll & MODBUSP_SET_TIME_FRAME )
{
pItem - > m_nFramePoll & = ~ MODBUSP_SET_TIME_FRAME ;
if ( GetSetTimeFrame ( pItem , buffer , count ) )
{
m_nCurFrame = 0 ;
}
}
else if ( pItem - > m_nFramePoll & MODBUSP_GET_DATA_FRAME )
{
pItem - > m_nFramePoll & = ~ MODBUSP_GET_DATA_FRAME ;
if ( GetReadDataFrame ( pItem , buffer , count ) )
{
m_nCurFrame = m_nFrameType ;
}
}
if ( count > = 2 )
{
checkSum = GetCRC16 ( buffer , count ) ;
buffer [ count ] = ( checkSum > > 8 ) & 0x00ff ;
buffer [ count + 1 ] = checkSum & 0x00ff ;
//发送前清除接收缓冲区所有数据
int tmplen = GetDataCount ( ) ;
if ( tmplen > 0 )
{
BYTE * tmpbuf = new BYTE [ tmplen + 1 ] ;
memset ( tmpbuf , 0 , ( tmplen + 1 ) ) ;
GetData ( tmpbuf , tmplen ) ;
DropData ( tmplen ) ;
DisplayRxData ( tmpbuf , tmplen , FALSE ) ;
2024-11-27 11:56:30 +08:00
delete [ ] tmpbuf ;
2024-07-08 10:27:17 +08:00
tmpbuf = NULL ;
}
if ( WriteData ( buffer , count + 2 ) )
{
DisplayTxData ( buffer , count + 2 , TRUE ) ;
}
m_nSendPoint = system32 . ticks ; //0;
m_nNeedCount = 2 ;
m_nState = MODBUSS_SYNC ;
m_nNeedSend = FALSE ;
FeedDog ( ) ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : OnTimer ( void )
{
int uid ;
CHostModbusRtuProcessItem * pItem ;
if ( ! CPortProcess : : OnTimer ( ) ) return FALSE ;
m_nCount + + ;
if ( m_nCurFrame ! = 0 )
{
if ( m_nSendPoint & & ( m_nSendPoint + m_nTimeout ) < = system32 . ticks )
{ //0.5 second command time out
//超时清除接收缓冲区所有数据
int tmplen = GetDataCount ( ) ;
if ( tmplen > 0 )
{
BYTE * tmpbuf = new BYTE [ tmplen + 1 ] ;
memset ( tmpbuf , 0 , ( tmplen + 1 ) ) ;
GetData ( tmpbuf , tmplen ) ;
DropData ( tmplen ) ;
DisplayRxData ( tmpbuf , tmplen , FALSE ) ;
2024-11-27 11:56:30 +08:00
delete [ ] tmpbuf ;
2024-07-08 10:27:17 +08:00
tmpbuf = NULL ;
}
m_nNeedCount = 2 ;
m_nState = MODBUSS_SYNC ;
m_nSendPoint = 0 ;
m_nCurFrame = 0 ;
}
}
if ( m_nCurFrame = = 0 & & ( m_nCount % PollGap ( ) ) = = 0 )
{
pItem = ( CHostModbusRtuProcessItem * ) GetNextItem ( ) ;
if ( pItem = = NULL ) return TRUE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return TRUE ;
m_nNeedSend = TRUE ;
struModbusExtFrame * frame = pItem - > GetNextFrame ( ) ;
if ( frame ! = NULL )
{
m_nFrameType = frame - > FrameType ;
m_nCurFuncCode = frame - > FuncCode ;
m_nCurBeginReg = frame - > RegBegin ;
m_nCurRegCount = frame - > RegCount ;
pItem - > m_nFramePoll | = MODBUSP_GET_DATA_FRAME ;
return TRUE ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : GetYKFrame ( CHostModbusRtuProcessItem * pItem , BYTE * pBuf , int & count , DWORD & frame )
{
int uid ;
BYTE result ;
BYTE * pData ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( NULL = = pBuf ) return FALSE ;
pData = pBuf ;
if ( ! GetUnitYK ( uid , m_nYKOrder , m_bYKValue , m_nYKState , result ) ) return FALSE ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is %s result is %s. \n " , uid , m_nYKOrder , ( m_bYKValue ? " ClOSE " : " TRIP " ) , val_to_str ( m_nYKState , yk_state , " STATE = %d " ) , val_to_str ( result , yk_result , " RESULT = %d " ) ) ;
BYTE * m_param ;
BYTE nFun ; //功能码
BOOLEAN nNeedSelect ; //遥控需要选择
WORD nReg = 0xffff , nVal = 0 ;
WORD nCloseSelReg , nCloseExecReg , nCloseEscReg , nCloseValue ; //合闸命令参数
WORD nOpenSelReg , nOpenExecReg , nOpenEscReg , nOpenValue ; //分闸命令参数
m_param = GetUnitYKParamByPoint ( uid , m_nYKOrder ) ;
if ( NULL = = m_param )
{
vLog ( LOG_ERROR , " get yk param error. \n " ) ;
return FALSE ;
}
nFun = m_param [ 0 ] ; //功能码占一个字节
nNeedSelect = m_param [ 1 ] ; //遥控是否需要选择
nCloseSelReg = MAKEWORD ( m_param [ 4 ] , m_param [ 5 ] ) ; //选择合寄存器
nCloseExecReg = MAKEWORD ( m_param [ 6 ] , m_param [ 7 ] ) ; //执行合寄存器
nCloseEscReg = MAKEWORD ( m_param [ 8 ] , m_param [ 9 ] ) ; //撤销合寄存器
nCloseValue = MAKEWORD ( m_param [ 10 ] , m_param [ 11 ] ) ; //合
nOpenSelReg = MAKEWORD ( m_param [ 12 ] , m_param [ 13 ] ) ; //选择分寄存器
nOpenExecReg = MAKEWORD ( m_param [ 14 ] , m_param [ 15 ] ) ; //执行分寄存器
nOpenEscReg = MAKEWORD ( m_param [ 16 ] , m_param [ 17 ] ) ; //撤销分寄存器
nOpenValue = MAKEWORD ( m_param [ 18 ] , m_param [ 19 ] ) ; //分
if ( m_nYKState = = YKS_SELREQ )
{ //遥控选择
if ( m_bYKValue )
{
nReg = nCloseSelReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenSelReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效,遥控无须选择
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
else
{
frame = MODBUSP_YK_SELECT ;
}
}
else if ( m_nYKState = = YKS_EXEREQ )
{ //遥控执行
if ( m_bYKValue )
{
nReg = nCloseExecReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenExecReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg )
{
vLog ( LOG_ERROR , " 该设备遥控执行寄存器配置错误。 \n " ) ;
return FALSE ;
}
frame = MODBUSP_YK_EXECUTE ;
}
else if ( m_nYKState = = YKS_ABRREQ )
{ //遥控撤销
if ( m_bYKValue )
{
nReg = nCloseEscReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenEscReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
frame = MODBUSP_YK_CANCEL ;
}
else if ( ( m_nYKState = = YKS_SELING | | m_nYKState = = YKS_SELED ) & & result = = YKR_OVER )
{ //遥控撤销
if ( m_bYKValue )
{
nReg = nCloseEscReg ;
nVal = nCloseValue ;
}
else
{
nReg = nOpenEscReg ;
nVal = nOpenValue ;
}
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return FALSE ;
}
frame = MODBUSP_YK_CANCEL ;
}
//modify by assouan for clean;
pData [ 0 ] = pItem - > m_physicsAddress ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
if ( nFun = = MODBUSC_F05 | | nFun = = MODBUSC_F06 )
{
pData [ 4 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 5 ] = nVal & 0x00ff ;
count = 6 ;
}
else if ( nFun = = MODBUSC_F15 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x01 ;
pData [ 6 ] = 0x01 ;
pData [ 7 ] = ( BYTE ) LOBYTE ( nVal ) ;
count = 8 ;
}
else if ( nFun = = MODBUSC_F16 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x01 ;
pData [ 6 ] = 0x02 ;
pData [ 7 ] = ( nVal > > 8 ) & 0x00ff ;
pData [ 8 ] = nVal & 0x00ff ;
count = 9 ;
}
else
{
vLog ( LOG_ERROR , " 该设备遥控功能码配置错误,不可能为:%d. \n " , nFun ) ;
return FALSE ;
}
return TRUE ;
}
//////////////////////////////////////////////////////////////////////////
// yt start //
//////////////////////////////////////////////////////////////////////////
BOOLEAN CHostModbusRtuProcess : : GetYTFrame ( CHostModbusRtuProcessItem * pItem , BYTE * pBuf , int & count , DWORD & frame )
{
int uid ;
BYTE result ;
BYTE * pData ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( NULL = = pBuf ) return FALSE ;
pData = pBuf ;
if ( ! GetUnitYT ( uid , m_nYTOrder , m_dwYTValue , m_nYTState , result ) )
{
return FALSE ;
}
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is %s result is %s. \n " , uid , m_nYTOrder , m_dwYTValue , val_to_str ( m_nYTState , yt_state , " STATE = %d " ) , val_to_str ( result , yt_result , " RESULT = %d " ) ) ;
BYTE * m_param ;
BYTE nFun ; //功能码
BYTE nSetType ; //设置方式 0单寄存器, 1双寄存器
BOOLEAN nNeedSelect ; //遥设需要选择
WORD nReg = 0xffff ;
WORD nSelReg , nExecReg , nEscReg ; //合闸命令参数
m_param = GetUnitYTParamByPoint ( uid , m_nYTOrder ) ;
if ( NULL = = m_param ) return FALSE ;
nSetType = m_param [ 0 ] ; //0 16位整型值;1 32位整型值;2 32位浮点数值;
nFun = m_param [ 1 ] ; //功能码占一个字节
nNeedSelect = m_param [ 2 ] ; //遥控是否需要选择
nSelReg = MAKEWORD ( m_param [ 4 ] , m_param [ 5 ] ) ; //选择寄存器
nExecReg = MAKEWORD ( m_param [ 6 ] , m_param [ 7 ] ) ; //执行寄存器
nEscReg = MAKEWORD ( m_param [ 8 ] , m_param [ 9 ] ) ; //撤销寄存器
if ( m_nYTState = = YTS_SELREQ )
{ //遥设选择
nReg = nSelReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效,遥设无须选择
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
else
{
frame = MODBUSP_YT_SELECT ;
}
}
else if ( m_nYTState = = YTS_EXEREQ )
{ //遥设执行
nReg = nExecReg ;
if ( 0xffff = = nReg ) return FALSE ;
frame = MODBUSP_YT_EXECUTE ;
}
else if ( m_nYTState = = YTS_ABRREQ )
{ //遥设撤销
nReg = nEscReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
frame = MODBUSP_YT_CANCEL ;
}
else if ( ( m_nYTState = = YTS_SELING | | m_nYTState = = YTS_SELED ) & & result = = YTR_OVER )
{ //遥设撤销
nReg = nEscReg ;
if ( 0xffff = = nReg | | ! nNeedSelect )
{ //寄存器无效
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return FALSE ;
}
frame = MODBUSP_YT_CANCEL ;
}
//modify by assouan for clean;
pData [ 0 ] = pItem - > m_physicsAddress ;
pData [ 1 ] = nFun ;
pData [ 2 ] = ( nReg > > 8 ) & 0x00ff ;
pData [ 3 ] = nReg & 0x00ff ;
if ( nFun = = MODBUSC_F06 )
{
pData [ 4 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 5 ] = m_dwYTValue & 0x00ff ;
count = 6 ;
}
else if ( nFun = = MODBUSC_F16 )
{
if ( nSetType = = 0 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x01 ;
pData [ 6 ] = 0x02 ;
pData [ 7 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 8 ] = m_dwYTValue & 0x00ff ;
count = 9 ;
}
else if ( nSetType = = 1 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x02 ;
pData [ 6 ] = 0x04 ;
pData [ 7 ] = ( m_dwYTValue > > 24 ) & 0x00ff ;
pData [ 8 ] = ( m_dwYTValue > > 16 ) & 0x00ff ;
pData [ 9 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 10 ] = m_dwYTValue & 0x00ff ;
count = 11 ;
}
else if ( nSetType = = 2 )
{
pData [ 4 ] = 0x00 ;
pData [ 5 ] = 0x02 ;
pData [ 6 ] = 0x04 ;
pData [ 7 ] = ( m_dwYTValue > > 8 ) & 0x00ff ;
pData [ 8 ] = m_dwYTValue & 0x00ff ;
pData [ 9 ] = ( m_dwYTValue > > 24 ) & 0x00ff ;
pData [ 10 ] = ( m_dwYTValue > > 16 ) & 0x00ff ;
count = 11 ;
}
}
else return FALSE ;
return TRUE ;
}
//////////////////////////////////////////////////////////////////////////
// yt end //
//////////////////////////////////////////////////////////////////////////
BOOLEAN CHostModbusRtuProcess : : GetSetTimeFrame ( CHostModbusRtuProcessItem * pItem , BYTE * /*pData*/ , int & count )
{
if ( NULL = = pItem ) return FALSE ;
count = 0 ;
return FALSE ;
}
BOOLEAN CHostModbusRtuProcess : : GetReadDataFrame ( CHostModbusRtuProcessItem * pItem , BYTE * pData , int & count )
{
if ( NULL = = pItem ) return FALSE ;
if ( m_nFrameType = = 0 ) return FALSE ;
if ( m_nCurFuncCode = = 0 ) return FALSE ;
pData [ 0 ] = pItem - > m_physicsAddress ;
pData [ 1 ] = ( BYTE ) m_nCurFuncCode ;
pData [ 2 ] = ( m_nCurBeginReg > > 8 ) & 0x00ff ;
pData [ 3 ] = m_nCurBeginReg & 0x00ff ;
pData [ 4 ] = ( m_nCurRegCount > > 8 ) & 0x00ff ;
pData [ 5 ] = m_nCurRegCount & 0x00ff ;
count = 6 ;
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : OnReceiveData ( BYTE * pData , int count )
{
int uid ;
CHostModbusRtuProcessItem * pItem ;
uid = GetUnitByAddr ( pData , 1 ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
int order = GetOrderByUnitID ( uid ) ;
if ( order < 0 | | order > = PROCESS_UNIT_NUM ) return FALSE ;
pItem = ( CHostModbusRtuProcessItem * ) GetItem ( order ) ;
if ( NULL = = pItem ) return FALSE ;
UnitFeedDog ( uid ) ;
if ( m_nCurFrame = = MODBUSP_READ_YX1 )
{
return OnReceiveYXData ( pItem , & pData [ 3 ] , count ) ;
}
else if ( m_nCurFrame = = MODBUSP_READ_YC1 )
{
return OnReceiveYCData ( pItem , & pData [ 3 ] , count ) ;
}
else if ( m_nCurFrame = = MODBUSP_READ_YM1 )
{
return OnReceiveYMData ( pItem , & pData [ 3 ] , count ) ;
}
else if ( m_nCurFrame = = MODBUSP_READ_SOE )
{
return TRUE ;
}
else if ( MODBUSP_YK_EXECUTE = = m_nCurFrame )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_EXEED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YK_SELECT = = m_nCurFrame )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YK_CANCEL = = m_nCurFrame )
{
SetUnitYK ( uid , m_nYKOrder , m_bYKValue , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , m_nYKOrder , ( m_bYKValue ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( MODBUSP_YT_EXECUTE = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_EXEED , YTR_SUCC ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
else if ( MODBUSP_YT_SELECT = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
else if ( MODBUSP_YT_CANCEL = = m_nCurFrame )
{
SetUnitYT ( uid , m_nYTOrder , m_dwYTValue , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , m_nYTOrder , m_dwYTValue ) ;
return TRUE ;
}
return FALSE ;
}
BOOLEAN CHostModbusRtuProcess : : OnReceiveYXData ( CHostModbusRtuProcessItem * pItem , BYTE * pData , int count )
{
int uid ;
int i , j ;
int point ;
BYTE param [ 4 ] ;
WORD reg ;
BOOLEAN yxVal ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
reg = m_nCurBeginReg ;
param [ 0 ] = m_nCurFuncCode ;
if ( MODBUSC_F03 = = m_nCurFuncCode | | MODBUSC_F04 = = m_nCurFuncCode )
{ //03功能码读取Holdings
WORD nValue ;
WORD nTemp = 0x0001 ;
for ( i = 0 ; i < count ; i + = 2 )
{
nValue = ( pData [ i ] < < 8 ) | pData [ i + 1 ] ;
nTemp = 0x0001 ;
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
reg + + ;
for ( j = 0 ; j < 16 ; j + + )
{
param [ 3 ] = j ;
point = GetUnitYXPointByParam ( uid , param , 4 ) ;
if ( point > = 0 )
{
yxVal = SPI_OFF ;
if ( ( nValue ) & nTemp )
{
yxVal = SPI_ON ;
}
SetUnitYX ( uid , point , yxVal ) ;
}
nTemp < < = 1 ;
}
}
}
else if ( MODBUSC_F01 = = m_nCurFuncCode | | MODBUSC_F02 = = m_nCurFuncCode )
{ //01 02功能码读取Coils和Status
BYTE * nValue = pData ;
BYTE nTemp = 0x01 ;
for ( i = 0 ; i < count ; i + + )
{
nTemp = 0x01 ;
for ( j = 0 ; j < 8 ; j + + )
{
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
reg + + ;
point = GetUnitYXPointByParam ( uid , param , 3 ) ;
if ( point > = 0 )
{
yxVal = SPI_OFF ;
if ( ( * nValue ) & nTemp )
{
yxVal = SPI_ON ;
}
SetUnitYX ( uid , point , yxVal ) ;
}
nTemp < < = 1 ;
}
nValue + + ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : OnReceiveYCData ( CHostModbusRtuProcessItem * pItem , BYTE * pData , int count )
{
int uid ;
int i ;
BYTE * pBuf ;
BYTE * pParam ;
BYTE param [ 8 ] ;
DWORD nValue = 0 ;
LONG bin_value ;
float f_val ;
int point ;
WORD reg ;
BYTE reg_count , value_type , sign_mark ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
pBuf = pData ;
reg = m_nCurBeginReg ;
param [ 0 ] = m_nCurFuncCode ;
for ( i = 0 ; i < count ; )
{
param [ 1 ] = LOBYTE ( reg ) ;
param [ 2 ] = HIBYTE ( reg ) ;
point = GetUnitYCPointByParam ( uid , param , 3 ) ;
if ( point > = 0 )
{ //获得合法点号
pParam = GetUnitYCParamByPoint ( uid , point ) ;
if ( pParam ! = NULL )
{
reg_count = pParam [ 3 ] ;
value_type = pParam [ 4 ] ;
sign_mark = pParam [ 5 ] ;
if ( ( 1 = = reg_count ) & & ( 2 = = value_type ) )
{ //16位归一化值
if ( 2 = = value_type )
{
if ( sign_mark = = 0 ) nValue = ( DWORD ) ( WORD ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
else nValue = ( DWORD ) ( short ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 8 = = value_type )
{
if ( sign_mark = = 0 ) nValue = ( DWORD ) ( WORD ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
else nValue = ( DWORD ) ( short ) ( ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
nValue = bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( WORD ) ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
pBuf + = 2 ; i + = 2 ; reg + + ;
}
else if ( 2 = = reg_count )
{ //32位测量值
if ( 0 = = value_type )
{ //浮点数,高位在第一个寄存器
nValue = ( DWORD ) ( pBuf [ 0 ] < < 24 | pBuf [ 1 ] < < 16 | pBuf [ 2 ] < < 8 | pBuf [ 3 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
//nValue = (DWORD)(f_val * 1000);
}
else if ( 1 = = value_type )
{
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
//nValue = (DWORD)(f_val * 1000);
}
else if ( 3 = = value_type )
{ //归一化值,高位在第一个寄存器
nValue = ( DWORD ) ( pBuf [ 0 ] < < 24 | pBuf [ 1 ] < < 16 | pBuf [ 2 ] < < 8 | pBuf [ 3 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 4 = = value_type )
{ //归一化值,高位在第二个寄存器
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
SetUnitYC ( uid , point , ( LONG ) nValue ) ;
}
else if ( 5 = = value_type )
{
nValue = ( DWORD ) ( pBuf [ 3 ] < < 24 | pBuf [ 2 ] < < 16 | pBuf [ 1 ] < < 8 | pBuf [ 0 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYC ( uid , point , f_val ) ;
}
else if ( 6 = = value_type )
{ //32位bcd数据高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
bin_value = ( LONG ) bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYC ( uid , point , bin_value ) ;
}
else if ( 7 = = value_type )
{ //32位bcd数据高位在第二个寄存器
nValue = ( DWORD ) ( pBuf [ 2 ] < < 24 | pBuf [ 3 ] < < 16 | pBuf [ 0 ] < < 8 | pBuf [ 1 ] ) ;
bin_value = ( LONG ) bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYC ( uid , point , bin_value ) ;
}
pBuf + = 4 ; i + = 4 ; reg + = 2 ;
}
}
}
else
{
pBuf + = 2 ; i + = 2 ; reg + + ;
}
}
return TRUE ;
}
BOOLEAN CHostModbusRtuProcess : : OnReceiveYMData ( CHostModbusRtuProcessItem * pItem , BYTE * pData , int count )
{
int i ;
int point ;
int uid ;
BYTE * pBuf ;
BYTE * pParam ;
BYTE nParam [ 4 ] ;
BYTE value_type ;
WORD reg ;
DWORD nValue = 0 ;
float f_val ;
DWORD dw [ 2 ] ; //双精度转换中间变量
double d_val ;
DWORD bin_value ;
if ( pItem = = NULL ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 ) return FALSE ;
pBuf = pData ;
reg = m_nCurBeginReg ;
nParam [ 0 ] = m_nCurFuncCode ;
for ( i = 0 ; i < count ; )
{
nParam [ 1 ] = LOBYTE ( reg ) ;
nParam [ 2 ] = HIBYTE ( reg ) ;
point = GetUnitYMPointByParam ( uid , nParam , 3 ) ;
if ( point > = 0 )
{ //获得有效点号
pParam = GetUnitYMParamByPoint ( uid , point ) ;
if ( NULL ! = pParam )
{ //获得有效参数
value_type = pParam [ 4 ] ;
if ( 0 = = value_type )
{ //16位无符号整型
nValue = ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 2 ; i + = 2 ; reg + + ;
}
else if ( 1 = = value_type )
{ //32位无符号整型高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 2 = = value_type )
{ //32位整型高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 3 = = value_type )
{ //32位无符号整型高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 4 = = value_type )
{ //32位整型高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
SetUnitYM ( uid , point , nValue ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 5 = = value_type )
{ //32位浮点数高位在第一个寄存器
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( f_val * 10 ) ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 6 = = value_type )
{ //32位浮点数高位在第二个寄存器
nValue = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( f_val * 10 ) ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 7 = = value_type )
{ //64位浮点数高位在第一个寄存器
dw [ 1 ] = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
dw [ 0 ] = ( DWORD ) ( ( pBuf [ 6 ] < < 24 ) | ( pBuf [ 7 ] < < 16 ) | ( pBuf [ 4 ] < < 8 ) | pBuf [ 5 ] ) ;
memcpy ( & d_val , dw , 8 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( d_val ) ) ;
pBuf + = 8 ; reg + = 4 ; i + = 8 ;
}
else if ( 8 = = value_type )
{
dw [ 0 ] = ( DWORD ) ( ( pBuf [ 2 ] < < 24 ) | ( pBuf [ 3 ] < < 16 ) | ( pBuf [ 0 ] < < 8 ) | pBuf [ 1 ] ) ;
dw [ 1 ] = ( DWORD ) ( ( pBuf [ 6 ] < < 24 ) | ( pBuf [ 7 ] < < 16 ) | ( pBuf [ 4 ] < < 8 ) | pBuf [ 5 ] ) ;
memcpy ( & d_val , dw , 8 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( d_val ) ) ;
pBuf + = 8 ; reg + = 4 ; i + = 8 ;
}
else if ( 9 = = value_type )
{
nValue = ( DWORD ) ( ( pBuf [ 3 ] < < 24 ) | ( pBuf [ 2 ] < < 16 ) | ( pBuf [ 1 ] < < 8 ) | pBuf [ 0 ] ) ;
memcpy ( & f_val , & nValue , 4 ) ;
SetUnitYM ( uid , point , ( DWORD ) ( f_val * 10 ) ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else if ( 10 = = value_type )
{ //32位bcd数据
nValue = ( DWORD ) ( ( pBuf [ 0 ] < < 24 ) | ( pBuf [ 1 ] < < 16 ) | ( pBuf [ 2 ] < < 8 ) | pBuf [ 3 ] ) ;
bin_value = bcd_to_int ( ( const BYTE * ) & nValue , sizeof ( DWORD ) ) ;
SetUnitYM ( uid , point , bin_value ) ;
pBuf + = 4 ; reg + = 2 ; i + = 4 ;
}
else
{ //无配置
pBuf + = 2 ; reg + + ; i + = 2 ;
}
}
}
else
{
pBuf + = 2 ; i + = 2 ; reg + + ;
}
}
return TRUE ;
}