Project

General

Profile

Feature #3017 » ModbusEx_LnS.cpp

yufeng wu, 06/09/2023 05:48 PM

 
1

    
2
#if defined(WIN32)
3
#include    <io.h>
4
// #include "stdafx.h"
5
#endif
6
#include    <limits.h>
7
#include    <sys/stat.h>
8
#include	<sys/timeb.h>
9
#include	<time.h>
10

    
11
#include "ModbusEx_LnS.h"
12
#include "se_log.h"
13
#include "daq/daq_utl.h"
14

    
15

    
16
extern CRdbTable DEF_DCDLL  RDB_Chan;
17

    
18
sint32 CModbusExLnS::GetNowSecond(unsigned short *mmt)
19
{
20
	CSeTime     SE_T;
21
	TCriterionTime tmptime;//sint32
22
	SE_T.GetNow(&tmptime, mmt);
23
	return (sint32)tmptime;
24
}
25

    
26
unsigned int CRC_16(unsigned char * pSendBuf, int len)//CRC??????
27
{ 
28
    unsigned short wCrc = 0xFFFF;
29
    for(int i=0; i<len;i++)
30
    {
31
        wCrc ^= pSendBuf[i];
32
        for(int j=0; j<8; j++)
33
        {
34
            if(wCrc & 1)
35
            {
36
                wCrc >>= 1; 
37
                wCrc ^= 0xA001; 
38
            }
39
            else
40
                wCrc >>= 1; 
41
        }
42
    }
43
    return wCrc;
44
}
45

    
46

    
47
CModbusExLnS::CModbusExLnS()
48
{
49
// #ifdef LOG_WIN
50
//     m_logger = new Logger("ModbusExLnS", "ModbusExLnS.log");
51
// //     m_logger->WriteLineSeparator("Create a new class instance. ", 2);
52
// #endif
53

    
54
    m_bExitMe = false;
55
	
56
    m_b_InitBuff = 0;
57
    m_bufValueHasReady = 0;
58
    m_bufYC = NULL;
59
    m_bufYX = NULL;
60

    
61
    m_TxDataMaxLen = 1042;
62
    m_FrameObjNum_Max = 512;
63
    m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock;
64

    
65
    resetIniParam(&m_iniConfig);	
66
}
67

    
68
CModbusExLnS::~CModbusExLnS()
69
{
70
    if (m_iniConfig.rtuConfArray != NULL)
71
    {
72
        delete [] m_iniConfig.rtuConfArray;
73
    }
74

    
75
	m_bExitMe = true;
76
    if (m_bufYX != NULL)
77
        delete [] m_bufYX;
78
    if (m_bufYC != NULL)
79
        delete [] m_bufYC;
80
	if (m_hThreadGetData!=NULL)
81
		SE_EndThread(m_hThreadGetData);
82
/*#ifdef LOG_WIN
83
    delete m_logger;
84
#endif
85
*/}
86
sint32  CModbusExLnS::MsgProc(sint32 msg){
87
	if (msg == DEF_MSG_COMMDOWN)
88
	{
89
		m_State = 0;
90
	}
91
	return 1;
92
}
93
void CModbusExLnS::Init( S_PROTOCOLCFG * pcfg )
94
{
95
// #ifdef LOG_WIN
96
// 	m_logger->WriteFmtStrWithTime_L3("[Init] : ");
97
// #endif
98
	m_hThreadGetData = NULL;
99
	m_State = 0;
100
	PRawCtrl    = pcfg->PRawCtrl;
101
	pRxBuf      = pcfg->pRxBuf;
102
	pTxBuf      = pcfg->pTxBuf;
103
	pCmdMem     = pcfg->pCmdMem;
104
	pRtu        = pcfg->pRtu;
105
	pLink       = pcfg->pLink;
106
	pTable      = pcfg->pTable;
107
	pZfDataCtrl = pcfg->pZfDataCtrl;
108

    
109
	sint32 buflen = pRxBuf->GetReadableSize();   
110
	pRxBuf->Move(buflen);
111
	buflen = pTxBuf->GetReadableSize();
112
	pTxBuf->Move(buflen);
113
	m_LastSendTime = GetNowSecond(&mm_LastSendTime);
114
/*#ifdef LOG_WIN
115
    char logfilename[32] = {0};
116
    sprintf(logfilename, "S_rtu%d_chan%d.log", pLink->GetRtuNo(), pLink->GetChanNo());
117
    m_logger = new Logger("ModbusExLnS", logfilename);
118
    m_logger->WriteLineSeparator("Create a new class instance. ", 2);
119
#endif
120
*/
121
    
122
	readIni();
123

    
124
    initBuffer();
125

    
126
    initStation();
127

    
128
	m_hThreadGetData = SE_CreateThread( (PTHREAD_FUNC_DEF)GetData, (void *)this);
129

    
130
}
131

    
132
void CModbusExLnS::initStation()
133
{
134
// #ifdef LOG_WIN
135
// 	m_logger->WriteFmtStrWithTime_L3("[initStation] : ");
136
// #endif
137

    
138
    m_flagSendType = 3;
139
    m_nSendFrameNo = 0;
140
    m_nSendSeqNo = 0;
141

    
142
    m_nYXFrameCount = 0; 
143
    m_nYCFrameCount = 0; 
144

    
145
    pLink->SetCommStatus(CMST_NORMAL);
146
}
147

    
148
void CModbusExLnS::readIni()
149
{
150
// #ifdef LOG_WIN
151
// 	m_logger->WriteFmtStrWithTime_L3("[readIni] : ");
152
// #endif
153

    
154
    char *home = getenv("SEROOT");
155
    if (NULL == home)
156
    {
157
        PrintLog(LOG_ERROR, "????????SEROOTδ????");
158
        return;
159
    }
160
    char filename[256] = {0};
161
#if defined(__unix)
162
    sprintf(filename, "%s%s%d%s", home, "/cfg/ModbusExLns_rtu",pLink->GetRtuNo(),".ini");
163
#else
164
    sprintf(filename, "%s%s%d%s", home, "\\cfg\\ModbusExLns_rtu",pLink->GetRtuNo(),".ini");
165
#endif
166
    
167
    CReadConf readconf;
168
	char sSection[6+1];
169
	sint32 rtu_no = 0;
170
    uint32 zfRtu_start = 0;
171
    uint32 zfRtu_count = 0;
172

    
173
	m_AIfactor = readconf.ReadLong("GENERAL", "AIfactor", filename, "10");
174
	int nTotalRtuNum = readconf.ReadLong("GENERAL", "rtuCount", filename, "1");
175
	for (sint32 rtu_i=0; rtu_i<nTotalRtuNum; rtu_i++)
176
	{
177
        rtu_no = 0;
178
		memset(sSection, 0, sizeof(char)*7);
179
        sprintf(sSection, "RTU_%d", rtu_i+1);
180
        zfRtu_start = readconf.ReadLong(sSection, "zfRtuIndexStart", filename, "0");
181
        zfRtu_count = readconf.ReadLong(sSection, "zfRtuCount", filename, "0");
182
		rtu_no = readconf.ReadLong(sSection, "rtuNo", filename, "0");
183
		if (rtu_no == pLink->GetRtuNo())
184
			break;
185
	}
186
	PrintLog(LOG_INFORMATION, "[readIni] : local rtu no %d, zf rtu number %d", rtu_no, zfRtu_count);
187
//    m_logger->WriteFmtStrWithTime_L3("[readIni] : local rtu no %d, zf rtu number %d", rtu_no, zfRtu_count);
188
    if (rtu_no <= 0)
189
    {
190
        PrintLog(LOG_ERROR, "RTUδ????");
191
        return;
192
    }
193
    if (zfRtu_count <= 0)
194
    {
195
        PrintLog(LOG_ERROR, "??ת????RTU??????????");
196
        return;
197
    }
198
	m_iniConfig.totalRtus = zfRtu_count;
199

    
200
    m_iniConfig.bufType = (uint8)readconf.ReadLong("GENERAL", "buffType", filename, "0");
201

    
202
    
203
    m_iniConfig.rtuConfArray = new IniRtuParam[zfRtu_count];
204
    for (uint32 zfrtu_i=0; zfrtu_i<zfRtu_count; zfrtu_i++)
205
    {
206
        memset(sSection, 0, sizeof(char)*7);
207
        sprintf(sSection, "RTU%d", zfRtu_start + zfrtu_i);
208
        LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + zfrtu_i;
209
		
210
        pRtuPara->rtuNo = readconf.ReadLong(sSection, "rtuNo", filename, "0");
211
        pRtuPara->totalYX = readconf.ReadLong(sSection, "yx", filename, "0");
212
        pRtuPara->totalYC = readconf.ReadLong(sSection, "yc", filename, "0");
213
        
214
        pRtuPara->totalYxBlock = (pRtuPara->totalYX + DINumberPerBlock - 1) / DINumberPerBlock;
215
    }
216

    
217
    setFrameProperty(m_iniConfig.bufType);
218
}
219

    
220
// 
221
sint32	CModbusExLnS::RxProc()
222
{
223
    if ( (m_flagSendType & 0x3) == 0)
224
        m_flagSendType = 0x3;
225

    
226
#if 1
227
    sint32 count = RDB_Chan.GetRcdCount();
228
    if( count>DEF_DCV_MAX_CHANNUM ) 
229
        count = DEF_DCV_MAX_CHANNUM;
230
	S_RDB_Chan * pChan = (S_RDB_Chan * )RDB_Chan.GetRcdAddr(0);
231
    sint32 chanNo = pLink->GetChanNo();
232
    for (int i=0; i<count; i++)
233
    {
234
        if (pChan[i].ChanNo == chanNo)
235
        {
236
            pChan[i].State = EDEV_UP_STATE;
237
            break;
238
        }
239
    }
240
#endif
241

    
242
    pLink->RegisterFrm( FRAME_RX_SUC );
243
//     pLink->SetCommStatus(CMST_NORMAL);
244
    return 1;
245
}
246

    
247
// 
248
sint32 CModbusExLnS::TxProc()
249
{
250
// 	m_logger->WriteFmtStrWithTime_L3("[TxProc] : ");
251
	m_State = 1;
252
	if (m_b_InitBuff == 0)
253
    {
254
		if (NULL != m_bufYX)
255
		{
256
			delete [] m_bufYX;
257
			m_bufYX = NULL;
258
		}
259
		PrintLog(LOG_INFORMATION, "[TxProc] : m_iniConfig.yxBytes = %d, m_iniConfig.ycBytes = %d", m_iniConfig.totalBytesYx, m_iniConfig.totalBytesYc);	
260
/*#ifdef LOG_WIN
261
        m_logger->WriteFmtStrWithTime_L3("[TxProc] : m_iniConfig.yxBytes = %d, m_iniConfig.ycBytes = %d", m_iniConfig.totalBytesYx, m_iniConfig.totalBytesYc);
262
#endif
263
*/
264
		if (m_iniConfig.totalBytesYx > 0)
265
			m_bufYX = new uint8[m_iniConfig.totalBytesYx];
266
		if (NULL == m_bufYX)
267
			return 0;
268
		memset(m_bufYX, 0, m_iniConfig.totalBytesYx);
269

    
270
		if (m_iniConfig.totalBytesYc > 0)
271
			m_bufYC = new uint8[m_iniConfig.totalBytesYc];
272
		if (NULL == m_bufYC)
273
			return 0;
274
		memset(m_bufYC, 0, m_iniConfig.totalBytesYc);
275

    
276
        m_b_InitBuff = 1;
277
        while (TRUE) {
278
            if (m_bufValueHasReady == 1)
279
                break;
280
            if (m_bExitMe)
281
                return 1;
282
            SeSleep(10);
283
        }
284
    }
285
    else
286
    {
287
		if (NULL == m_bufYX)
288
			return 0;
289
		if (NULL == m_bufYC)
290
			return 0;
291
    }
292

    
293
//     m_logger->WriteFmtStrWithTime_L3("[TxProc] : send data ...");
294
	ushort CurMMS = 0;
295
	sint32 CurTime = GetNowSecond(&CurMMS);
296
	uint16 m_TxInterval = pLink->GetKwhScanInterval();
297
	if (m_TxInterval < 10)m_TxInterval = 50;
298
	if (((CurTime - m_LastSendTime) * 1000 + CurMMS - mm_LastSendTime) < m_TxInterval)return 0;
299
    if ( (m_flagSendType & 0x1) == 0x1)
300
    {
301
		if (procSendDI() == 1){
302
			m_LastSendTime = GetNowSecond(&mm_LastSendTime);
303
			return 1;
304
		}
305
    }
306
    
307
    if ( (m_flagSendType & 0x2) == 0x2)
308
    {
309
		if (procSendAI() == 1){
310
			m_LastSendTime = GetNowSecond(&mm_LastSendTime);
311
			return 1;
312
		}
313
    }
314

    
315
	return 1;
316
}
317

    
318

    
319
void CModbusExLnS::appToLink(uint8 nDataType)
320
{
321
    BYTE * p = m_sendData.databuf;
322
    int len = m_sendData.trailP - m_sendData.headP;
323

    
324
    unsigned int crcValue = CRC_16(p, len);
325
    *m_sendData.trailP++ = crcValue % 0x100;
326
    *m_sendData.trailP++ = crcValue / 0x100;
327

    
328
    len = m_sendData.trailP - m_sendData.headP;
329
       
330
/*#ifdef LOG_WIN
331
    if (m_logger->IfLogData())
332
    {
333
        if (nDataType == 1)
334
            m_logger->WriteFmtStrWithTime_L3(_T("???ͱ??? (?ֽ??? %d) : DI??%d֡"), len, m_nYXFrameCount);
335
        else if (nDataType == 3)
336
            m_logger->WriteFmtStrWithTime_L3(_T("???ͱ??? (?ֽ??? %d) : AI??%d֡"), len, m_nYCFrameCount);
337
		
338
        TCHAR strLog[MaxCodeLen] = {0};
339
        uint32 real_len = MaxCodeLen - TimeHead;
340
        
341
        uint32 code_line = 1;
342
        _tcscpy(strLog, "\n0001: ");
343
        
344
        int code_index;
345
        for (code_index=0; code_index<len; code_index++)
346
        {
347
            if ( _tcslen(strLog) >= real_len-1) {
348
                m_logger->WriteFmtStrWithTime_L3(strLog);
349
                memset(strLog, 0, sizeof(TCHAR)*MaxCodeLen);
350
                _stprintf(strLog, _T("\n%04d: "), ++code_line);
351
            }
352
            
353
            TCHAR tmpStr[12] = {0};
354
            if ( (code_index+1)/32 > 0 && (code_index+1)%32 == 0) {
355
                if ( (code_index+1) % (MaxLine*MaxLineCodeNum) == 0 )
356
                    _stprintf(tmpStr, _T("%02X  \n"), *(p+code_index));
357
                else
358
                    _stprintf(tmpStr, _T("%02X  \n%04d: "), *(p+code_index), ++code_line);
359
            }
360
            else
361
                _stprintf(tmpStr, _T("%02X  "), *(p+code_index));
362
            
363
            _tcscat(strLog, tmpStr);
364
        }
365
        m_logger->WriteFmtStrWithTime_L3(strLog);
366
    }
367
#endif
368
*/
369
//     pLink->RegisterFrmCode(RAW_CODEDIR_DOWN, (char *)p, len);
370
    pTxBuf->Write(p, len);
371
//     pLink->SetCommStatus(CMST_NORMAL);
372

    
373
    pLink->RegisterFrm( FRAME_TX_SUC );
374

    
375
    return;
376
}
377

    
378
// index base 0
379
// ??ͬ??RTU????ͬһ??֡???ͣ?ÿ??֡????????
380
sint32 CModbusExLnS::procSendDI()
381
{
382
    if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray)
383
    {
384
        PrintLog(LOG_ERROR, "RTUδ????");
385
        m_flagSendType &= 0xFE;
386
        m_nSendFrameNo = 0;
387
        return 0;
388
    }
389

    
390

    
391
//#ifdef LOG_WIN
392
    if (m_nSendFrameNo == 0) {
393
        m_timeBeginYX = GetNowSecond(&mm_LastSendTime);//GetTickCount();
394
    }
395
//#endif
396

    
397
    // save DI into buffer
398
    uint8 *buf = new uint8[m_TxDataMaxLen];
399
    if (NULL == buf)
400
        return 0;
401
    uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2;
402
    uint8 * dataSrc = m_bufYX + nPreCopied;
403
    uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx ) ? (m_iniConfig.totalBytesYx - nPreCopied) : (m_FrameObjNum_Max * 2);
404
    memcpy(buf, dataSrc, nCopySize);
405

    
406
    // DATA_HEAD
407
    DATA_HEAD dataHead;
408
    dataHead.HeadLo = 0xEB;
409
    dataHead.HeadHi = 0x90;
410
    dataHead.SysID = FixSysID_Ans;
411
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
412
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
413
    
414
    uint16 framelen = nCopySize + 8;
415
    dataHead.LenLo = framelen % 256;
416
    dataHead.LenHi = framelen / 256;
417
    
418
    bool bFinishedCycle = false;
419
    if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYx )
420
        bFinishedCycle = true;
421
    if (bFinishedCycle)
422
        dataHead.FollowupFlag = 0;
423
    else
424
        dataHead.FollowupFlag = 1;
425
    
426
    // DATA_BODY_HEAD
427
    DATA_BODY_HEAD dataBodyHead;    
428
    dataBodyHead.DataType = ReqTypeID_DI;
429
    
430
    uint32 nMaxCount = nCopySize * 8;
431
    dataBodyHead.DataCountLB = nMaxCount & 0xFF;
432
    dataBodyHead.DataCountMB = (nMaxCount >> 8) & 0xFF;
433
    dataBodyHead.DataCountHB = (nMaxCount >> 16) & 0xFF;
434
    
435
    dataBodyHead.DataStAddrLB = nPreCopied & 0xFF;
436
    dataBodyHead.DataStAddrMB = (nPreCopied >> 8) & 0xFF;
437
    dataBodyHead.DataStAddrHB = (nPreCopied >> 16) & 0xFF;
438

    
439
    //
440
    uint8 *ptr = m_sendData.databuf;
441
    m_sendData.headP = m_sendData.trailP = ptr;
442
    
443
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
444
    ptr += DataHeadLen;
445

    
446
    memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen);
447
    ptr += DataBodyHeadLen;
448
    
449
    memcpy(ptr, (BYTE *)buf, nCopySize);
450
    ptr += nCopySize;
451
    m_sendData.trailP = ptr;
452
//	PrintLog(LOG_INFORMATION, "????DI??Ӧ֡");
453
    appToLink(1);
454
    
455
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
456
    
457
//#ifdef LOG_WIN
458
    m_nYXFrameCount++;
459
//#endif
460

    
461
    delete [] buf;
462

    
463
    if (bFinishedCycle)
464
    {
465
        m_flagSendType &= 0xFE;
466
        m_nSendFrameNo = 0;
467
//#ifdef LOG_WIN
468
        DWORD curTick = GetNowSecond(&mm_LastSendTime);//GetTickCount();
469
        DWORD spendTick = GetNowSecond(&mm_LastSendTime)- m_timeBeginYX;;//GetTickCount() 
470
		PrintLog(LOG_INFORMATION, "[procSendDI] : ң?? ??????ϣ???ʱ: %d(s), ????֡??: %d", spendTick, m_nYXFrameCount);
471
//        m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYXFrameCount);
472
        m_nYXFrameCount = 0;        
473
//#endif
474
    }
475
    else
476
        m_nSendFrameNo++;
477

    
478
    return 1;
479
}
480
/* // ??ͬ??RTU?ڲ?ͬ֡
481
sint32 CModbusExLnS::procSendDI()
482
{
483
    if (NULL == m_bufYX || NULL == m_iniConfig.rtuConfArray)
484
    {
485
        PrintLog(LOG_ERROR, "RTUδ????");
486
        m_flagSendType &= 0xFE;
487
        m_nSendFrameNo = 0;
488
        return 0;
489
    }
490

    
491
    // get start RTU
492
    uint32 nRtuNo = 0;    
493
    uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU)
494
    uint32 nTotalFramesRTU = 0; // total frames of current RTU
495
    uint32 nDI_byte_start = 0; // start address of current frame (:= 0~0xFFFFFF)
496
    LPIniRtuParam p_zfRtu = NULL;
497
    while ( nRtuNo < m_iniConfig.totalRtus)
498
    {
499
        p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo;
500
        nTotalFramesRTU = (p_zfRtu->totalYxBlock + MaxObjPerFrame_DI - 1) / MaxObjPerFrame_DI;
501
        if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0
502
            break;
503
        nCalcFrames += nTotalFramesRTU;
504
        nDI_byte_start += (p_zfRtu->totalYxBlock * 2);
505
        nRtuNo++;
506
    }
507
    if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu)
508
    {
509
        PrintLog(LOG_ERROR, "RTU?????????????????????ļ?????ǰRTU %d", nRtuNo+1);
510
        m_flagSendType &= 0xFE;
511
        m_nSendFrameNo = 0;
512
        return 0;
513
    }
514
    
515
    uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU
516
    nDI_byte_start += (MaxObjPerFrame_DI * 2 * nRtuFrameNo);
517
    uint32 nRtuPointStart = (MaxObjPerFrame_DI * DINumberPerBlock) * nRtuFrameNo; // get from which DI start
518
    
519
#ifdef LOG_WIN
520
    if (m_nSendFrameNo == 0) {
521
        m_timeBeginYX = GetNowSecond(&mm_LastSendTime);//GetTickCount();
522
    }
523
#endif
524

    
525
    // re-calculate max DI
526
    uint32 nRetPoint = p_zfRtu->totalYX - nRtuPointStart;
527
    uint32 nMaxPoint = (MaxObjPerFrame_DI * DINumberPerBlock); // max DI of current frame
528
    nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint;
529
  
530
    // save DI into buffer
531
    uint8 buf[1024] = {0};
532
    uint32 nCopySize = (nMaxPoint + 7) / 8;
533
    uint8 *dataSrc = m_bufYX + nDI_byte_start;
534
    memcpy(buf, dataSrc, nCopySize);
535

    
536
    // DATA_HEAD
537
    DATA_HEAD dataHead;
538
    dataHead.HeadLo = 0xEB;
539
    dataHead.HeadHi = 0x90;
540
    dataHead.SysID = FixSysID_Ans;
541
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
542
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
543

    
544
    uint16 nBlock = (nMaxPoint+DINumberPerBlock-1) / DINumberPerBlock;
545
    uint16 framelen = nBlock * 2 + 8;
546
    dataHead.LenLo = framelen % 256;
547
    dataHead.LenHi = framelen / 256;
548

    
549
    bool bFinishedCycle = false;
550
//     if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) )
551
//         bFinishedCycle = true;
552
//     m_logger->WriteFmtStrWithTime_L3("[procSendDI] : nDI_byte_start = %d, nCopySize = %d, m_iniConfig.totalBytesYx = %d",
553
//          nDI_byte_start, nCopySize, m_iniConfig.totalBytesYx);
554
    if ( (nDI_byte_start + (nMaxPoint+15)/16*2) >= m_iniConfig.totalBytesYx)
555
        bFinishedCycle = true;
556
    if (bFinishedCycle)
557
        dataHead.FollowupFlag = 0;
558
    else
559
        dataHead.FollowupFlag = 1;
560

    
561
    dataHead.DataType = ReqTypeID_DI;
562
   
563
    //
564
    uint8 *ptr = m_sendData.databuf;
565
    m_sendData.headP = m_sendData.trailP = ptr;
566
    
567
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
568
    ptr += DataHeadLen;
569
    
570
    uint32 nMaxCount = nMaxPoint;
571
    *ptr++ = nMaxCount & 0xFF;
572
    *ptr++ = (nMaxCount >> 8) & 0xFF;
573
    *ptr++ = (nMaxCount >> 16) & 0xFF;
574
    
575
    *ptr++ = nDI_byte_start & 0xFF;
576
    *ptr++ = (nDI_byte_start >> 8) & 0xFF;
577
    *ptr++ = (nDI_byte_start >> 16) & 0xFF;
578

    
579
    memcpy(ptr, (BYTE *)buf, nBlock*2);
580
    ptr += nBlock * 2;
581
    m_sendData.trailP = ptr;
582

    
583
    appToLink(1);
584

    
585
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
586

    
587
#ifdef LOG_WIN
588
    m_nYXFrameCount++;
589
#endif
590

    
591
    if (bFinishedCycle)
592
    {
593
        m_flagSendType &= 0xFE;
594
        m_nSendFrameNo = 0;
595
#ifdef LOG_WIN
596
        DWORD curTick = GetNowSecond(&mm_LastSendTime);//GetTickCount();
597
        DWORD spendTick = GetNowSecond(&mm_LastSendTime);//GetTickCount() - m_timeBeginYX;
598
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendDI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYXFrameCount);
599
        m_nYXFrameCount = 0;        
600
#endif
601
    }
602
    else
603
        m_nSendFrameNo++;
604

    
605
    return 1;
606
}
607
*/
608

    
609
// ??ͬ??RTU????ͬһ??֡???ͣ?ÿ??֡????????
610
sint32 CModbusExLnS::procSendAI()
611
{
612
    if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray)
613
    {
614
        PrintLog(LOG_ERROR, "RTUδ????");
615
        m_flagSendType &= 0xFD;
616
        m_nSendFrameNo = 0;
617
        return 0;
618
    }
619

    
620
//#ifdef LOG_WIN
621
    if (m_nSendFrameNo == 0) {
622
        m_timeBeginYC = GetNowSecond(&mm_LastSendTime);//GetTickCount();
623
    }
624
//#endif
625

    
626

    
627
    // save AI into buffer
628
    uint8 *buf = new uint8[m_TxDataMaxLen];
629
    if (NULL == buf)
630
        return 0;
631
    uint32 nPreCopied = m_nSendFrameNo * m_FrameObjNum_Max * 2;
632
    uint8 * dataSrc = m_bufYC + nPreCopied;
633
    uint32 nCopySize = ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc ) ? (m_iniConfig.totalBytesYc - nPreCopied) : (m_FrameObjNum_Max * 2);
634
    memcpy(buf, dataSrc, nCopySize);
635

    
636

    
637
    // DATA_HEAD
638
    DATA_HEAD dataHead;
639
    dataHead.HeadLo = 0xEB;
640
    dataHead.HeadHi = 0x90;
641
    dataHead.SysID = FixSysID_Ans;
642
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
643
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
644
    
645
    uint16 framelen = nCopySize + 8;
646
    dataHead.LenLo = framelen % 256;
647
    dataHead.LenHi = framelen / 256;
648
    
649
    bool bFinishedCycle = false;
650
    if ( (uint32)(m_nSendFrameNo + 1) >= m_iniConfig.totalFramesYc )
651
        bFinishedCycle = true;
652
    if (bFinishedCycle)
653
        dataHead.FollowupFlag = 0;
654
    else
655
        dataHead.FollowupFlag = 1;
656
    
657

    
658
    // DATA_BODY_HEAD
659
    DATA_BODY_HEAD dataBodyHead;    
660
    dataBodyHead.DataType = ReqTypeID_AI;
661
    
662
    uint32 nMaxPoint = nCopySize / 2;
663
    dataBodyHead.DataCountLB = nMaxPoint & 0xFF;
664
    dataBodyHead.DataCountMB = (nMaxPoint >> 8) & 0xFF;
665
    dataBodyHead.DataCountHB = (nMaxPoint >> 16) & 0xFF;
666
    
667
    uint32 nInfoAddrStart = nPreCopied / 2;
668
    dataBodyHead.DataStAddrLB = nInfoAddrStart & 0xFF;
669
    dataBodyHead.DataStAddrMB = (nInfoAddrStart >> 8) & 0xFF;
670
    dataBodyHead.DataStAddrHB = (nInfoAddrStart >> 16) & 0xFF;
671
    
672
    uint8 *ptr = m_sendData.databuf;
673
    m_sendData.headP = m_sendData.trailP = ptr;
674
    
675
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
676
    ptr += DataHeadLen;
677
    
678
    memcpy(ptr, (BYTE *)&dataBodyHead, DataBodyHeadLen);
679
    ptr += DataBodyHeadLen;
680
    
681
    memcpy(ptr, (BYTE *)buf, nMaxPoint*2);
682
    ptr += nCopySize;
683
    m_sendData.trailP = ptr;
684
    
685
//    PrintLog(LOG_INFORMATION, "????AI??Ӧ֡");
686
    appToLink(3);
687
    
688
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
689
    
690
//#ifdef LOG_WIN
691
    m_nYCFrameCount++;
692
//#endif
693

    
694
    delete [] buf;
695
    
696
    if (bFinishedCycle)
697
    {
698
        m_flagSendType &= 0xFD;
699
        m_nSendFrameNo = 0;
700
//#ifdef LOG_WIN
701
        DWORD curTick = GetNowSecond(&mm_LastSendTime);//GetTickCount();
702
        DWORD spendTick = curTick - m_timeBeginYC;
703
		PrintLog(LOG_INFORMATION, "[procSendAI] : ң?? ??????ϣ???ʱ: %d(s), ????֡??: %d", spendTick, m_nYCFrameCount);
704
//        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYCFrameCount);
705
        m_nYCFrameCount = 0;
706
        
707
        spendTick = curTick - m_timeBeginYX;
708
		PrintLog(LOG_INFORMATION, "[procSendAI] : ------>>> ???????? ??????ϣ???ʱ: %d(s) <<<------", spendTick);
709
//        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> ???????? ??????ϣ???ʱ: %us(%ums) <<<------"), spendTick/1000, spendTick);
710
        m_timeBeginYX = m_timeBeginYC = 0;
711
//#endif
712
    }
713
    else
714
        m_nSendFrameNo++;
715
    
716
    return 1;
717
}
718
/* // ??ͬ??RTU?ڲ?ͬ֡
719
sint32 CModbusExLnS::procSendAI()
720
{
721
    if (NULL == m_bufYC || NULL == m_iniConfig.rtuConfArray)
722
    {
723
        PrintLog(LOG_ERROR, "RTUδ????");
724
        m_flagSendType &= 0xFD;
725
        m_nSendFrameNo = 0;
726
        return 0;
727
    }
728

    
729
    // get start RTU
730
    uint32 nRtuNo = 0;    
731
    uint32 nCalcFrames = 0; // total frames have been sent (not include current RTU)
732
    uint32 nTotalFramesRTU = 0; // total frames of current RTU
733
    uint32 nInfoAddrStart = 0; // start address of current frame (:= 0~0xFFFFFF)
734
    LPIniRtuParam p_zfRtu = NULL;
735
    while (nRtuNo < m_iniConfig.totalRtus)
736
    {
737
        p_zfRtu = m_iniConfig.rtuConfArray + nRtuNo;
738
        nTotalFramesRTU = p_zfRtu->totalYcFrame;
739
        if (m_nSendFrameNo < nCalcFrames + nTotalFramesRTU)//SendFrameNo : index base from 0
740
            break;
741
        nCalcFrames += nTotalFramesRTU;
742
        nInfoAddrStart += p_zfRtu->totalYC;
743
        nRtuNo++;
744
    }
745
    if (nRtuNo >= m_iniConfig.totalRtus || NULL == p_zfRtu)
746
    {
747
        PrintLog(LOG_ERROR, "AI?㳬?????????????ļ?????ǰRTU %d", nRtuNo+1);
748
        m_flagSendType &= 0xFD;
749
        m_nSendFrameNo = 0;
750
        return 0;
751
    }    
752
    
753
    uint32 nRtuFrameNo = m_nSendFrameNo - nCalcFrames; // get frame number which has been sent in current RTU
754
    nInfoAddrStart += MaxObjPerFrame_AI * nRtuFrameNo;
755
    uint32 nMaxPoint = MaxObjPerFrame_AI; // max DI of current frame
756
    uint32 nRtuPointStart = nMaxPoint * nRtuFrameNo; // get from which DI start
757
    
758
#ifdef LOG_WIN
759
    if (m_nSendFrameNo == 0) {
760
        m_timeBeginYC = GetNowSecond(&mm_LastSendTime);//GetTickCount();
761
    }
762
#endif
763

    
764
    // re-calculate max DI
765
    uint32 nRetPoint = p_zfRtu->totalYC - nRtuPointStart;
766
    nMaxPoint = nRetPoint < nMaxPoint ? nRetPoint : nMaxPoint;
767
  
768
    // save AI into buffer
769
    uint8 buf[1024] = {0};
770
    uint32 nCopySize = nMaxPoint * 2;
771
    uint8 * dataSrc = m_bufYC + nInfoAddrStart * 2;
772
    memcpy(buf, dataSrc, nCopySize);
773

    
774
    // DATA_HEAD
775
    DATA_HEAD dataHead;
776
    dataHead.HeadLo = 0xEB;
777
    dataHead.HeadHi = 0x90;
778
    dataHead.SysID = FixSysID_Ans;
779
    dataHead.PacketNoLo = m_nSendSeqNo % 256;
780
    dataHead.PacketNoHi = m_nSendSeqNo / 256;
781

    
782
    uint16 framelen = nMaxPoint * 2 + 8;
783
    dataHead.LenLo = framelen % 256;
784
    dataHead.LenHi = framelen / 256;
785

    
786
    bool bFinishedCycle = false;
787
//     m_logger->WriteFmtStrWithTime_L3("[procSendAI] : m_iniConfig.totalRtus = %d, nRtuNo = %d, nRtuFrameNo = %d, nTotalFramesRTU = %d",
788
//         m_iniConfig.totalRtus, nRtuNo, nRtuFrameNo, nTotalFramesRTU);
789
//     if ( (nRtuNo >= m_iniConfig.totalRtus-1) && (nRtuFrameNo >= nTotalFramesRTU-1) )
790
//         bFinishedCycle = true;
791
    if ( (nInfoAddrStart*2 + nCopySize) >= m_iniConfig.totalBytesYc)
792
        bFinishedCycle = true;
793
    if (bFinishedCycle)
794
        dataHead.FollowupFlag = 0;
795
    else
796
        dataHead.FollowupFlag = 1;
797

    
798
    dataHead.DataType = ReqTypeID_AI;
799
   
800
    //
801
    uint8 *ptr = m_sendData.databuf;
802
    m_sendData.headP = m_sendData.trailP = ptr;
803
    
804
    memcpy(ptr, (BYTE *)&dataHead, DataHeadLen);
805
    ptr += DataHeadLen;
806
    
807
    *ptr++ = nMaxPoint & 0xFF;
808
    *ptr++ = (nMaxPoint >> 8) & 0xFF;
809
    *ptr++ = (nMaxPoint >> 16) & 0xFF;
810
    
811
    *ptr++ = nInfoAddrStart & 0xFF;
812
    *ptr++ = (nInfoAddrStart >> 8) & 0xFF;
813
    *ptr++ = (nInfoAddrStart >> 16) & 0xFF;
814

    
815
    memcpy(ptr, (BYTE *)buf, nMaxPoint*2);
816
    ptr += nMaxPoint * 2;
817
    m_sendData.trailP = ptr;
818

    
819
    PrintLog(LOG_INFORMATION, "????DI??Ӧ֡");
820
    appToLink(3);
821

    
822
    m_nSendSeqNo = (m_nSendSeqNo + 1) % 0xFFFF;
823

    
824
#ifdef LOG_WIN
825
    m_nYCFrameCount++;
826
#endif
827

    
828
    if (bFinishedCycle)
829
    {
830
        m_flagSendType &= 0xFD;
831
        m_nSendFrameNo = 0;
832
#ifdef LOG_WIN
833
        DWORD curTick = GetNowSecond(&mm_LastSendTime);//GetTickCount();
834
        DWORD spendTick = curTick - m_timeBeginYC;
835
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ң?? ??????ϣ???ʱ: %us(%ums), ????֡??: %d"), spendTick/1000, spendTick, m_nYCFrameCount);
836
        m_nYCFrameCount = 0;
837
        
838
        spendTick = curTick - m_timeBeginYX;
839
        m_logger->WriteFmtStrWithTime_L3(_T("[procSendAI] : ------>>> ???????? ??????ϣ???ʱ: %us(%ums) <<<------"), spendTick/1000, spendTick);
840
        m_timeBeginYX = m_timeBeginYC = 0;
841
#endif
842
    }
843
    else
844
        m_nSendFrameNo++;
845

    
846
    return 1;
847
}
848
*/
849

    
850
void CModbusExLnS::resetIniParam(LPIniConfig pParam)
851
{
852
	memset(pParam, 0, sizeof(IniConfig));
853
}
854

    
855
void CModbusExLnS::initBuffer()
856
{
857
	if (NULL == m_iniConfig.rtuConfArray)
858
		return;
859

    
860
	for (uint32 zfrtu_i=0; zfrtu_i<m_iniConfig.totalRtus; zfrtu_i++)
861
	{
862
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + zfrtu_i;
863
//         m_logger->WriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 1= %d, pRtuPara->totalYxBlock = %d", m_iniConfig.yxBytes, pRtuPara->totalYxBlock);
864
		m_iniConfig.totalBytesYx += pRtuPara->totalYxBlock * 2;
865
//         m_logger->WriteFmtStrWithTime_L3("[initBuffer] : m_iniConfig.yxBytes 2= %d", m_iniConfig.yxBytes);
866
		m_iniConfig.totalBytesYc += pRtuPara->totalYC * 2;
867
	}
868

    
869
    uint32 nMaxBytesPerFrame = m_FrameObjNum_Max * 2;
870
    m_iniConfig.totalFramesYx = (m_iniConfig.totalBytesYx + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame;
871
    m_iniConfig.totalFramesYc = (m_iniConfig.totalBytesYc + nMaxBytesPerFrame - 1) / nMaxBytesPerFrame;
872
}
873

    
874
sint32 CModbusExLnS::procWriteBuffer_DI()
875
{
876
    if (m_bufYX == NULL)
877
        return 0;
878
	
879
	uint32 yx_startNo_inBuff = 0;
880
	for (uint32 rtu_i=0; rtu_i<m_iniConfig.totalRtus; rtu_i++)
881
	{
882
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + rtu_i;
883
//		PrintLog(LOG_INFORMATION, "rtu%d,totalYX=%d,yx_startNo=%d", rtu_i + 1, pRtuPara->totalYX, yx_startNo_inBuff);//test
884
		uint32 byteIndex, bitIndex;
885
		for (uint16 yx_i = 0; yx_i<pRtuPara->totalYX; yx_i++)
886
		{
887
			uint8 btVal = 0;
888
			PRawCtrl->GetAYx(pRtuPara->rtuNo, yx_i, &btVal);
889
			byteIndex = yx_i / DINumberPerBlock * 2 + yx_i%DINumberPerBlock / 8 + yx_startNo_inBuff;
890
			bitIndex = yx_i % 8;
891
			if (btVal == 1) {
892
				*(m_bufYX+byteIndex) |= (1 << bitIndex);
893
			}
894
			else {
895
				*(m_bufYX+byteIndex) &= ~(1 << bitIndex);
896
			}
897
		}
898
		yx_startNo_inBuff += pRtuPara->totalYxBlock * 2;
899
	}
900

    
901
    return 1;
902
}
903

    
904
sint32 CModbusExLnS::procWriteBuffer_AI()
905
{
906
    if (m_bufYC == NULL)
907
        return 0;
908

    
909
	uint32 yc_startNo_inBuff = 0;
910
	for (uint32 rtu_i=0; rtu_i<m_iniConfig.totalRtus; rtu_i++)
911
	{
912
		LPIniRtuParam pRtuPara = m_iniConfig.rtuConfArray + rtu_i;
913

    
914
		uint32 byteIndex;
915
		for (uint16 yc_i=0; yc_i<pRtuPara->totalYC; yc_i++)
916
		{
917
			float32 fVal = 0.0f;
918
			PRawCtrl->GetAYc(pRtuPara->rtuNo, yc_i, &fVal);
919

    
920
			byteIndex = (yc_startNo_inBuff + yc_i) * 2;
921
			*(m_bufYC+byteIndex) = ((sint32)(fVal*m_AIfactor)) % 256;//?Ŵ?10??
922
			*(m_bufYC+byteIndex+1) = ((sint32)(fVal*m_AIfactor)) / 256; //?Ŵ?10??
923
		}
924

    
925
        yc_startNo_inBuff += pRtuPara->totalYC;
926
	}
927
	
928
    return 1;
929
}
930

    
931
void CModbusExLnS::GetData(void * pClass)
932
{
933
    if (NULL == pClass)
934
        return;
935
    CModbusExLnS * pThis = (CModbusExLnS *)pClass;
936
	uint16 m_GetInterval = 0;
937
	
938
    while (TRUE) {
939
        if (pThis->m_b_InitBuff == 1)
940
            break;
941
        if (pThis->m_bExitMe)
942
            return;
943
        SeSleep(200);
944
    }
945
    
946
	while (TRUE)
947
	{
948
		if (pThis->m_bExitMe)
949
			break;
950
		if (pThis->m_State > 0){
951
		pThis->procWriteBuffer_DI();
952
		pThis->procWriteBuffer_AI();
953
		}
954
//         pThis->m_logger->WriteFmtStrWithTime_L3("[GetData] : call procWriteBuffer_AI");
955

    
956
        if (pThis->m_bufValueHasReady == 0)
957
            pThis->m_bufValueHasReady = 1;
958
		m_GetInterval = pThis->pLink->GetAllDataScanInterval();
959
		if (m_GetInterval < 10)	m_GetInterval = 500;
960
		SeSleep(m_GetInterval);
961
    }
962
}
963

    
964
void CModbusExLnS::setFrameProperty(uint8 bufType)
965
{
966
    if (bufType <= 0 || bufType > 6)
967
        return;
968
    
969
    uint32 nDataBuffLen = (uint32)(1 << bufType) * 1024;
970
    
971
    m_TxDataMaxLen = nDataBuffLen + sizeof(DATA_HEAD) + sizeof(DATA_BODY_HEAD) + 2;
972
    m_FrameObjNum_Max = nDataBuffLen / 2;
973
    m_FrameDINum_Max = m_FrameObjNum_Max * DINumberPerBlock;
974
}
975

    
976

    
977

    
978

    
979

    
980

    
981

    
982
////////////////////////////////////////////////////////////////
983
#if defined(WIN32)
984
		extern "C" __declspec(dllexport) 
985
#else 
986
	extern "C"
987
#endif
988
CProtocol	*CreateProtocol(char *defpara)
989
{
990
	return (CProtocol*)(new CModbusExLnS());
991
}
(1-1/7)