#include "StdAfx.h" #include ".\serialfactory.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 引用全局对象; extern CRITICAL_SECTION g_cs_vt; /************************************************************************/ /* 函数:构造函数; 测试结果-> 内存泄漏:无 使用正常:正常 */ /************************************************************************/ CSerialFactory::CSerialFactory( ) { InitializeCriticalSection( &g_cs_vt ); } /************************************************************************/ /* 函数:析构函数; 测试结果-> 内存泄漏:无 使用正常:正常 */ /************************************************************************/ CSerialFactory::~CSerialFactory(void) { list::iterator it; for( it = m_listComm.begin(); it != m_listComm.end(); ) { CSerialProcess *pComm = (*it).pComm; if ( pComm ) { delete pComm; pComm = NULL; } m_listComm.erase( it++ ); } DeleteCriticalSection( &g_cs_vt ); } /************************************************************************/ /* 函数:查找串口是否在容器中; 参数: iCommPort: 要查找的串口号; 测试结果-> 内存泄漏:无 使用正常:正常 */ /************************************************************************/ const CSerialProcess *CSerialFactory::FindComm(const int &iCommPort) { list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if( tagComm.iCommPort == iCommPort && tagComm.pComm != NULL ) return tagComm.pComm; } return NULL; } /************************************************************************/ /* 函数:打开串口中; 参数: iCommPort 串口号; iRate 波特率; iDataBit 数据位; iStopBit 停止位; iParity 校验码; iRespTime 响应时间; iInterval 采集频率; 测试结果-> 内存泄漏:无 使用正常:正常 */ /************************************************************************/ BOOL CSerialFactory::OpenSerialPort( const int &iCommPort, const int &iRate, const int &iDataBit, const int &iStopBit, const int &iParity, const int &iRespTime, const int &iInterval) { if( FindComm( iCommPort ) == NULL ) { COM_STRUCT tagComm; tagComm.iCommPort = iCommPort; tagComm.pComm = new CSerialProcess(); if( !tagComm.pComm->OpenComm( iCommPort,iRate, iDataBit, iStopBit, iParity,iRespTime, iInterval) ) { delete tagComm.pComm; tagComm.pComm = NULL; return FALSE; } else { m_listComm.insert(m_listComm.end(), tagComm); } } return TRUE; } /************************************************************************/ /* 函数:关闭串口; 参数: iCommPort: 要关闭的串口号; 当 =-1 时,表示关闭所有串口; 测试结果-> 内存泄漏:无 使用正常:正常 注意: 先erase容器元素后,再对容器元素进行delete; */ /************************************************************************/ BOOL CSerialFactory::CloseSerialPort( const int &iCommPort ) { list::iterator it; COM_STRUCT tagComm; if ( iCommPort == -1) { for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it); it = m_listComm.erase(it); if (tagComm.pComm) { delete tagComm.pComm; tagComm.pComm = NULL; } } } else { for( it = m_listComm.begin(); it != m_listComm.end(); it++) { tagComm = *(it); if ( iCommPort == tagComm.iCommPort ) { m_listComm.erase(it); if (tagComm.pComm) { delete tagComm.pComm; tagComm.pComm = NULL; } break; } } } return FALSE; } /************************************************************************/ /* 函数:启动串口线程循环采集; 1.在串口打开后,且串口插入命令完成; 2.可以在这里实现在线程运行前某些命令的发送 如卡乐,先请求数据强制转换命令,然后才正常循环发送请求; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ int CSerialFactory::AutoCollect( const int &iCommPort ) { // 1.先判断有无特殊命令; // 2.处理完毕特殊命令,进行常规采集; list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) { tagComm.pComm->AutoCollect(); break; } } return 0; } /************************************************************************/ /* 函数:停止采集; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::StopCollect(const int &iCommPort) { list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) { tagComm.pComm->StopCollect(); break; } } } /************************************************************************/ /* 函数:移除设备命令; 参数: iCommPort: 串口; iAddr: 串口地址; 已完善 1.如果删除了一个设备的发送命令,当该串口只有该设备时, 那么这个设备也要从list中删除, 同时,如果该设备串口已经打开,也要从关闭串口释放资源; 测试结果-> 内存泄漏:无 使用正常:完善 */ /************************************************************************/ void CSerialFactory::RemoveDeivce(const int &iCommPort, const int &iAddr) { COM_STRUCT tagComm; list::iterator it,it_cur; int nCount = 0;//用来获取有多少个设备在该串口; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) { LOG4C((LOG_NOTICE,"开始删除 %d串口地址%d命令",iCommPort,iAddr)); tagComm.pComm->RemoveDeivce(iAddr); *it_cur = tagComm; nCount++; break; } } if ( nCount == 1 ) { CSerialProcess *pComm = (*it_cur).pComm; if ( pComm ) { delete pComm; pComm = NULL; } m_listComm.erase(it_cur); } } /************************************************************************/ /* 函数:获取指定串口所有设备命令总数; 参数: iCommPort: 要获取的串口; 测试结果-> 内存泄漏:无 使用正常:正常 */ /************************************************************************/ int CSerialFactory::GetCommandsCount(const int &iCommPort) { list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) return tagComm.pComm->GetCommandsCount(); } return -1; } /************************************************************************/ /* 函数:主机做为下位机,自动接收串口数据; 参数: iCommPort: 要接收数据的串口; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::AutoScatter(const int &iCommPort) { } /************************************************************************/ /* 函数:主机做为下位机,停止自动接收串口数据; 参数: iCommPort: 要接收数据的串口; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::StopScatter(const int &iCommPort) { } /************************************************************************/ /* 函数:对指定串口指定地址的设备发送设置/请求命令; 参数: iCommPort: 指定的串口; iAddr 指定的地址; szCmd 发送命令串; iLen 命令串的长度; iRequestType 命令的类型,设置/请求数据; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::SendRequest( const int &iCommPort, const int &iAddr, BYTE *szCmd,const int &iLen, const int &iRequestType ) { list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) { if ( iRequestType == 0) { // 发送 设置命令; tagComm.pComm->SetCommand(szCmd,iLen,iAddr); } else { // 发送请求读取命令; } break; } } } /************************************************************************/ /* 函数:读取串口的数据,与SendRequest配合使用; 参数: iCommPort: 指定的串口; iAddr 指定的地址; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::ReadRespone( const int &iCommPort, const int &iAddr ) { } /************************************************************************/ /* 函数:对指定串口地址添加设备命令; 参数: iCommPort: 指定串口; iAddr 指定地址; szCommand 命令串; iLen 命令串长度; szMark 命令串的特征码; szCheck 命令串的校验方式; bRecv 是否对该命令串返回的数据保存; iSNum 命令串的发送顺序; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::InserCommand( const int &iCommPort, const int &iAddr, BYTE *szCommand, const int &iLen, const char *szMark, const char *szCheck, bool bRecv , const int &iSNum ) { list::iterator it; COM_STRUCT tagComm; for( it = m_listComm.begin(); it != m_listComm.end(); ) { tagComm = *(it++); if ( tagComm.iCommPort == iCommPort) { #if USE_INSERT_AUTORAISE tagComm.pComm->RaiseSize(); // 使该串口的容器大小自增; #endif tagComm.pComm->InsertCommand(szCommand,iLen,iAddr,szMark,szCheck,iSNum,bRecv); break; } } } /************************************************************************/ /* 函数:删除指定串口地址指定的命令串; 参数: iCommPort: 指定的串口; iAddr 指定的地址; szCommand 指定的命令串; iLen 命令串长度; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::DeleteRequestCommannd( const int &iCommPort,const int &iAddr, BYTE *szCommand, const int &iLen ) { } /************************************************************************/ /* 函数:获取指定配置信息的变量值; 参数: iCommPort: 指定的串口; iAddr 指定地址; szMark 指定特征码; iIndex 指定索引; iCutLen 指定长度; iSBit 指定起始位; iEBit 指定终止位; szValue 返回的值; iConvertType 指定的数据转换类型; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::GetAnalogValue( const int &iCommPort, const int &iAddr, char *szMark, const int &iIndex, const int &iCutLen, const int &iSBit, const int &iEBit, char *szValue, const int &iConvertType) { // 1.根据参数,从数据池中取出对应的数据串; // 2.根据参数,从数据串中取出对应的字节内容; // 3.根据参数,进行字节内容 数据类型转换; // 4.返回最终分析结果; } /************************************************************************/ /* 函数:获取指定配置信息的变量值; 参数: iCommPort: 指定的串口; iAddr 指定地址; szMark 指定特征码; iIndex 指定索引; iCutLen 指定长度; iSBit 指定起始位; iEBit 指定终止位; szValue 返回的值; iConvertType 指定的数据转换类型; 测试结果-> 内存泄漏:无 使用正常:待完善 */ /************************************************************************/ void CSerialFactory::SetAnalogValue( const int &iCommPort, const int &iAddr, char *szMark, const int &iIndex, const int &iCutLen, const int &iSBit, const int &iEBit, char *szSetValue, const int &iConvertType) { // 1.根据参数,分析最终发送的设置命令; // 2.调用CCommProcess::SetCommand(...)函数,进行设置发送; }