实例化工程模板

conctrl.h

#pragma once
#include "EMIOCtrl.h"
#include "LumDataCtrl.h"
#include "LEDCtrl.h"
#include "AD9518Ctrl.h"
#include "BramCtrl.h"
#include "FPGAComCtrl.h"
#include "TempVoltSampleCtrl.h"
#include "MotorCtrl.h"
#include "LaserCtrl.h"
#include "ProberCtrl.h"
class CDeviceComCtrl
{
public:
	// 析构函数
	~CDeviceComCtrl();
	// 第一阶段初始化
	int iOneStageInit();
	// 第二阶段初始化
	int iTwoStageInit();
	// 获取单例指针
	static CDeviceComCtrl * GetInstance();
public:
	//开始采集
	int iStartCapture();
	//开始行扫描
	int iStartRowScan(int  iScanInnerRow);
	//停止采集
	int iStopCapture();
	// 设置行起始结束位置
	int iSetScanRowRange(int  iScanInnerRowLowerLimit, int iScanInnerRowUpperLimit);
	// 探头使用次数加1
	int iProberUsedTimeAndOne();
	// 写探头信息
	int iWriteProberInfo(const stProberInfo &proberInfo);
	// 读探头信息
	int iReadProberInfo(stProberInfo & proberInfo);
	// 关闭激光器
	int iTurnOffLaser();
	// 打开激光器
	int iTurnOnLaser();
	// 设置激光功率
	int iSetLaserPower(int iLaserPower);
	// 获取激光器信息
	int iGetLaserInfo(stLaserInfo & laserInfo);
	// 打开LED灯
	int iTurnOnLED();
	// 关闭LED灯
	int iTurnOffLED();
	// 采集亮度数据
	int iSampleLumData(unsigned char * &lumData, int &iDataLen);
	// 设置电机位置
	int iSetMotorPos(int iPos);
	// 获取电机当前位置
	int iGetCurMotorPos();
	// 设置电机限制范围
	int iSetMotorPosRange(int iMotorPosLowerLimit, int iMotorPosUpperLimit);
	// 设置X振镜电压
	int iSetXMirrorControlVoltage(int  iXMirrorControlVoltage);
	// 设置Y振镜电压
	int iSetYMirrorControlVoltage(int  iYMirrorControlVoltage);
	// 设置PMT电压
	int iSetPMTControlVoltage(int iPMTControlVoltage);
	// 设置行偏移值
	int iSetYMirrorOffset(int iYMirrorOffset);
	// 设置扫描类型
	int iSetScanType(int  iScanDirectionType);
	// 设置X振镜行列偏移
	int iSetXMirrorOffset(int  iXMirrorOffset);
	// 设置X振镜偶数行列偏移
	int iSetXMirrorEvenOffset(int iXMirrorEvenOffset);
	// 设置奇数行列偏移
	int iSetXMirrorOddOffset(int iXMirrorOddOffset);
	// 设置畸变校正参数
	int iSetCorrectionParam(const stCorrectionParam & correctionParam);
	// 设置行对齐算法参数
	int iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam);
	// 设置亮度数据类型
	int iSetLumDataType(int iLumDataType);
	// 获取Fluorite版本信息
	int iGetFluoriteVer(string & sVer);
	// 获取Fluorite定制版本信息
	int iGetFluoriteCustomVer(string& sVer);
	// 开启扫描
	int iStartCapture(int  iScanRowLowerLimit, int  iScanRowUpperLimit);
	// 等待线程退出
	void wait();
	// 退出线程
	void ExitThread();
protected:
	// 停止扫描
	int iStopCapture(int  iScanRowLowerLimit, int  iScanRowUpperLimit);
private:
	// 构造函数
	CDeviceComCtrl();
private:
	// 单例指针
	static CDeviceComCtrl * m_pInst;
private:
	// FPGA器件控制
	CFPGAComCtrl * m_pFPGAComCtrl;
	// 电机控制
	CMotorCtrl * m_pMotorCtrl;
	// 激光器控制
	CLaserCtrl * m_pLaserCtrl;
	// 探头控制
	CProberCtrl * m_pProberCtrl;
	// 核心温度和电压采集控制
	CTempVoltSampleCtrl * m_pTempVoltSampleCtrl;
	// AD9518控制
	CAD9518Ctrl * m_pAD9518Ctrl;
	// LED灯控制
	CLEDCtrl * m_pLEDCtrl;
	// Bram接口
	CBramCtrl * m_pBramCtrl;
    // EMIO控制
	CEMIOCtrl * m_pEMIOCtrl;
	// 亮度数据采集控制
	CLumDataCtrl * m_pLumDataCtrl;
};

conctrl.cpp

#include "Log.h"
#include "SettingParamMng.h"
#include "DeviceComCtrl.h"
#include "SysConfigMng.h"
#include "DeviceStatusMng.h"
#include "LaserCtrlBios488.h"

// 单例指针
CDeviceComCtrl * CDeviceComCtrl::m_pInst = nullptr;

// 构造函数
CDeviceComCtrl::CDeviceComCtrl()
{
	// FPGA器件控制
	m_pFPGAComCtrl = nullptr;
	// 电机控制
	m_pMotorCtrl = nullptr;
	// 激光器控制
	m_pLaserCtrl = nullptr;
	// 探头控制
	m_pProberCtrl = nullptr;
	// 核心温度和电压采集控制
	m_pTempVoltSampleCtrl = nullptr;
	// EMIO控制
	m_pEMIOCtrl = nullptr;
	// 亮度数据采集控制
	m_pLumDataCtrl = nullptr;
	// AD9518控制
	m_pAD9518Ctrl = nullptr;
	// LED灯控制
	m_pLEDCtrl = nullptr;
	// Bram接口
	m_pBramCtrl = nullptr;
	return;
}

// 析构函数
CDeviceComCtrl::~CDeviceComCtrl()
{
	if (nullptr != m_pProberCtrl)
	{
		delete m_pProberCtrl;
		m_pProberCtrl = nullptr;
	}

	if (nullptr != m_pLaserCtrl)
	{
		delete m_pLaserCtrl;
		m_pLaserCtrl = nullptr;
	}

	if (nullptr != m_pMotorCtrl)
	{
		delete m_pMotorCtrl;
		m_pMotorCtrl = nullptr;
	}

	if (nullptr != m_pAD9518Ctrl)
	{
		delete m_pAD9518Ctrl;
		m_pAD9518Ctrl = nullptr;
	}

	if (nullptr != m_pTempVoltSampleCtrl)
	{
		delete m_pTempVoltSampleCtrl;
		m_pTempVoltSampleCtrl = nullptr;
	}

	if (nullptr != m_pLEDCtrl)
	{
		delete m_pLEDCtrl;
		m_pLEDCtrl = nullptr;
	}

	if (nullptr != m_pFPGAComCtrl)
	{
		delete m_pFPGAComCtrl;
		m_pFPGAComCtrl = nullptr;
	}

	if (nullptr != m_pBramCtrl)
	{
		delete m_pBramCtrl;
		m_pBramCtrl = nullptr;
	}

	if (nullptr != m_pEMIOCtrl)
	{
		delete m_pEMIOCtrl;
		m_pEMIOCtrl = nullptr;
	}

	if (nullptr != m_pLumDataCtrl)
	{
		delete m_pLumDataCtrl;
		m_pLumDataCtrl = nullptr;
	}
	return;
}
// 第一阶段初始化
int CDeviceComCtrl::iOneStageInit()
{
	stDeviceComCtrlConfig deviceComCtrlConfig = CSysConfigMng::GetInstance()->GetDeviceComCtrlConfig();
	m_pEMIOCtrl = new CEMIOCtrl();
	m_pBramCtrl = new CBramCtrl(deviceComCtrlConfig.m_sBramDriverFile);
	m_pAD9518Ctrl = new CAD9518Ctrl(deviceComCtrlConfig.m_emioConfig.m_AD9518SPICSEMIO.m_iEMIOCode, m_pEMIOCtrl, deviceComCtrlConfig.m_sAD9518SPIDriverFile);
	m_pTempVoltSampleCtrl = new CTempVoltSampleCtrl();
	m_pLumDataCtrl = new CLumDataCtrl(deviceComCtrlConfig.m_sDMADriverFile);
	m_pLEDCtrl = new CLEDCtrl(deviceComCtrlConfig.m_emioConfig.m_LEDEnableEMIO.m_iEMIOCode, m_pEMIOCtrl);
	m_pFPGAComCtrl = new CFPGAComCtrl(m_pBramCtrl);
	m_pMotorCtrl = new CMotorCtrl(m_pBramCtrl, deviceComCtrlConfig.m_emioConfig.m_motorMoveEnableEMIO.m_iEMIOCode, m_pEMIOCtrl);
	if (EXIT_FAILURE == m_pEMIOCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pBramCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pAD9518Ctrl->iInitialize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pTempVoltSampleCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pLumDataCtrl->iInitilize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pFPGAComCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pMotorCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}



// 第二阶段初始化
int CDeviceComCtrl::iTwoStageInit()
{
	// 获取激光器和探头配置信息
	stDeviceComCtrlConfig deviceComCtrlConfig = CSysConfigMng::GetInstance()->GetDeviceComCtrlConfig();
	//激光器自适应
	
	CLaserCtrl *m_pLaserCtrl;
	 m_pLaserCtrl = new CLaserCtrlBios488(deviceComCtrlConfig.m_laserUartConfigInfo, deviceComCtrlConfig.m_emioConfig.m_UartSendEnableEMIO.m_iEMIOCode, deviceComCtrlConfig.m_emioConfig.m_UartRecvEnableEMIO.m_iEMIOCode, m_pEMIOCtrl, this);
	 // 初始化激光器
	 if (EXIT_FAILURE == m_pLaserCtrl->iInitialize())
	 {
		 return EXIT_FAILURE;
	 }
	 int iWaveLen;
	m_pLaserCtrl->iGetLaserWaveLength(iWaveLen);          //获取激光器波长
	if (iWaveLen != 488)
	{
		delete m_pLaserCtrl;
		printf(" iInitialize erro in Bios488 \n");
		m_pLaserCtrl = new CLaserCtrl(deviceComCtrlConfig.m_laserUartConfigInfo, deviceComCtrlConfig.m_emioConfig.m_UartSendEnableEMIO.m_iEMIOCode\
			, deviceComCtrlConfig.m_emioConfig.m_UartRecvEnableEMIO.m_iEMIOCode, m_pEMIOCtrl, this);
		// 初始化激光器
		if (EXIT_FAILURE == m_pLaserCtrl->iInitialize())
		{
			return EXIT_FAILURE;
		}
	}


	//m_pLaserCtrl = new CLaserCtrl(deviceComCtrlConfig.m_laserUartConfigInfo, deviceComCtrlConfig.m_emioConfig.m_UartSendEnableEMIO.m_iEMIOCode\
	//	, deviceComCtrlConfig.m_emioConfig.m_UartRecvEnableEMIO.m_iEMIOCode, m_pEMIOCtrl, this);
	m_pProberCtrl = new CProberCtrl(deviceComCtrlConfig.m_proberUartConfigInfo, deviceComCtrlConfig.m_emioConfig.m_ProberLockingFlagEMIO.m_iEMIOCode\
		, m_pEMIOCtrl, this);
	// 初始化探头
	if (EXIT_FAILURE == m_pProberCtrl->iInitialize())
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}


// 获取单例指针
CDeviceComCtrl * CDeviceComCtrl::GetInstance()
{
	if (nullptr == m_pInst)
	{
		m_pInst = new CDeviceComCtrl;
	}
	return m_pInst;
}


//开始采集
int CDeviceComCtrl::iStartCapture()
{
	stIntTypeRange scanRowRange = CSettingParamMng::GetInstance()->GetScanRowRange();
	if (EXIT_FAILURE == iStartCapture(scanRowRange.m_iLowerLimit, scanRowRange.m_iUpperLimit))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}


//开始行扫描
int CDeviceComCtrl::iStartRowScan(int iScanInnerRow)
{
	if (EXIT_FAILURE == iSetScanRowRange(iScanInnerRow, iScanInnerRow))
	{
		return EXIT_FAILURE;
	}

	// 打开LED灯
	iTurnOnLED();

	// 打开激光器
	iTurnOnLaser();

	int iPower;
	m_pLaserCtrl->iGetLaserPower(iPower);
	int iMaxLaserPower = CSettingParamMng::GetInstance()->iGetLaserMaxPower();
	int iPowerPercent = iPower * 100 / iMaxLaserPower;
	iPowerPercent = iPowerPercent > 100 ? 100 : iPowerPercent;
	if (0 == iPowerPercent)
	{
		ostringstream os;
		os << "StartRowScan turn on Laser faild, LaserPower[" << iPower << "]" << endl;;
	}
	stStateMsg stateMsg;
	stateMsg.m_enComType = enDeviceComType_Scanner;
	stateMsg.m_deviceStateCode.m_iCode = STATE_EMIT;
	stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperOr;
	stateMsg.m_deviceErrorCode.m_iCode = 0;
	stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
	stateMsg.m_comStateCode.m_iCode = SCANNER_LINE;
	stateMsg.m_comStateCode.m_enCodeOperType = enCodeOperCopy;
	stateMsg.m_comErrorcode.m_iCode = 0;
	stateMsg.m_comErrorcode.m_enCodeOperType = enCodeOperOr;
	CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
	CDeviceStatusMng::GetInstance()->iSetMessage("Working...", 0);
	return EXIT_SUCCESS;
}

//停止采集
int CDeviceComCtrl::iStopCapture()
{
	stIntTypeRange scanRowRange = CSettingParamMng::GetInstance()->GetScanRowRange();
	if (EXIT_FAILURE == iStopCapture(scanRowRange.m_iLowerLimit, scanRowRange.m_iUpperLimit))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 设置行起始结束位置
int CDeviceComCtrl::iSetScanRowRange(int  iScanInnerRowLowerLimit, int iScanInnerRowUpperLimit)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == m_pFPGAComCtrl->iSetScanRowRange(iScanInnerRowLowerLimit, iScanInnerRowUpperLimit))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 探头使用次数加1
int CDeviceComCtrl::iProberUsedTimeAndOne()
{
	if (nullptr == m_pProberCtrl)
	{
		ostringstream os;
		os << "ProberCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pProberCtrl->iProberUsedTimeAndOne();
}
// 写探头信息
int CDeviceComCtrl::iWriteProberInfo(const stProberInfo &proberInfo)
{
	if (nullptr == m_pProberCtrl)
	{
		ostringstream os;
		os << "ProberCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pProberCtrl->iWriteProberInfo(proberInfo);
}
// 读探头信息
int CDeviceComCtrl::iReadProberInfo(stProberInfo & proberInfo)
{
	if (nullptr == m_pProberCtrl)
	{
		ostringstream os;
		os << "ProberCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pProberCtrl->iReadProberInfo(proberInfo);
}

// 关闭激光器
int CDeviceComCtrl::iTurnOffLaser()
{
	if (nullptr == m_pLaserCtrl)
	{
		ostringstream os;
		os << "LaserCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLaserCtrl->iTurnOffLaser();
}
// 打开激光器
int CDeviceComCtrl::iTurnOnLaser()
{
	if (nullptr == m_pLaserCtrl)
	{
		ostringstream os;
		os << "LaserCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLaserCtrl->iTurnOnLaser();
}
// 设置激光功率
int CDeviceComCtrl::iSetLaserPower(int iLaserPower)
{
	if (nullptr == m_pLaserCtrl)
	{
		ostringstream os;
		os << "LaserCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLaserCtrl->iSetLaserPower(iLaserPower);
}
// 获取激光器信息
int CDeviceComCtrl::iGetLaserInfo(stLaserInfo & laserInfo)
{
	if (nullptr == m_pLaserCtrl)
	{
		ostringstream os;
		os << "LaserCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLaserCtrl->iGetLaserInfo(laserInfo);
}

// 打开LED灯
int CDeviceComCtrl::iTurnOnLED()
{
	if (nullptr == m_pLEDCtrl)
	{
		ostringstream os;
		os << "LEDCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLEDCtrl->iTurnOn();
}
// 关闭LED灯
int CDeviceComCtrl::iTurnOffLED()
{
	if (nullptr == m_pLEDCtrl)
	{
		ostringstream os;
		os << "LEDCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLEDCtrl->iTurnOff();
}

// 采集亮度数据
int CDeviceComCtrl::iSampleLumData(unsigned char *&lumData, int &iDataLen)
{
	if (nullptr == m_pLumDataCtrl)
	{
		ostringstream os;
		os << "LumDataCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pLumDataCtrl->iSampleLumData(lumData, iDataLen);
}
// 设置电机位置
int CDeviceComCtrl::iSetMotorPos(int iPos)
{
	if (nullptr == m_pMotorCtrl)
	{
		ostringstream os;
		os << "MotorCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pMotorCtrl->iSetMotorPos(iPos);
}


// 获取电机当前位置
int CDeviceComCtrl::iGetCurMotorPos()
{
	if (nullptr == m_pMotorCtrl)
	{
		ostringstream os;
		os << "MotorCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pMotorCtrl->iGetMotorPos();
}

// 设置电机限制范围
int CDeviceComCtrl::iSetMotorPosRange(int iMotorPosLowerLimit, int iMotorPosUpperLimit)
{
	if (nullptr == m_pMotorCtrl)
	{
		ostringstream os;
		os << "MotorCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pMotorCtrl->iSetMotorPosRange(iMotorPosLowerLimit, iMotorPosUpperLimit);
}

// 设置X振镜电压
int CDeviceComCtrl::iSetXMirrorControlVoltage(int  iXMirrorControlVoltage)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetXMirrorControlVoltage(iXMirrorControlVoltage);
}
// 设置Y振镜电压
int CDeviceComCtrl::iSetYMirrorControlVoltage(int  iYMirrorControlVoltage)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetYMirrorControlVoltage(iYMirrorControlVoltage);
}
// 设置PMT电压
int CDeviceComCtrl::iSetPMTControlVoltage(int iPMTControlVoltage)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetPMTControlVoltage(iPMTControlVoltage);
}
// 设置行偏移值
int CDeviceComCtrl::iSetYMirrorOffset(int iYMirrorOffset)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetYMirrorOffset(iYMirrorOffset);
}

// 设置扫描类型
int CDeviceComCtrl::iSetScanType(int  iScanDirectionType)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetScanType(iScanDirectionType);
}
// 设置X振镜行列偏移
int CDeviceComCtrl::iSetXMirrorOffset(int  iXMirrorOffset)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetXMirrorOffset(iXMirrorOffset);
}
// 设置X振镜偶数行列偏移
int CDeviceComCtrl::iSetXMirrorEvenOffset(int iXMirrorEvenOffset)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetXMirrorEvenOffset(iXMirrorEvenOffset);
}
// 设置奇数行列偏移
int CDeviceComCtrl::iSetXMirrorOddOffset(int iXMirrorOddOffset)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetXMirrorOddOffset(iXMirrorOddOffset);
}
// 设置畸变校正参数
int CDeviceComCtrl::iSetCorrectionParam(const stCorrectionParam & correctionParam)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetCorrectionParam(correctionParam);
}
// 设置行对齐算法参数
int CDeviceComCtrl::iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetLineAlignAlgParam(lineAlignAlgParam);
}

// 设置亮度数据类型
int CDeviceComCtrl::iSetLumDataType(int iLumDataType)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iSetLumDataType(iLumDataType);
}

// 获取Fluorite版本信息
int CDeviceComCtrl::iGetFluoriteVer(string & sVer)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iGetFluoriteVer(sVer);
}
// 获取Fluorite定制版本信息
int CDeviceComCtrl::iGetFluoriteCustomVer(string& sVer)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return m_pFPGAComCtrl->iGetFluoriteCustomVer(sVer);
}


// 开启扫描
int CDeviceComCtrl::iStartCapture(int  iScanRowLowerLimit, int  iScanRowUpperLimit)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_pFPGAComCtrl->iStartCapture(iScanRowLowerLimit, iScanRowUpperLimit))
	{
		return EXIT_FAILURE;
	}
	// 打开LED灯
	iTurnOnLED();

	// 打开激光器
	iTurnOnLaser();

	int iPower;
	m_pLaserCtrl->iGetLaserPower(iPower);
	int iMaxLaserPower = CSettingParamMng::GetInstance()->iGetLaserMaxPower();
	int iPowerPercent = iPower * 100 / iMaxLaserPower;
	iPowerPercent = iPowerPercent > 100 ? 100 : iPowerPercent;
	if (0 == iPowerPercent)
	{
		ostringstream os;
		os << "startCapture turn on Laser faild, LaserPower[" << iPower << "]" << endl;;
	}
	stStateMsg stateMsg;
	stateMsg.m_enComType = enDeviceComType_Scanner;
	stateMsg.m_deviceStateCode.m_iCode = STATE_EMIT;
	stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperOr;
	stateMsg.m_deviceErrorCode.m_iCode = 0;
	stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
	stateMsg.m_comStateCode.m_iCode = SCANNER_WORKING;
	stateMsg.m_comStateCode.m_enCodeOperType = enCodeOperCopy;
	stateMsg.m_comErrorcode.m_iCode = 0;
	stateMsg.m_comErrorcode.m_enCodeOperType = enCodeOperOr;
	CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
	CDeviceStatusMng::GetInstance()->iSetScanRowRange(iScanRowLowerLimit, iScanRowUpperLimit);
	CDeviceStatusMng::GetInstance()->iSetMessage("Working...", 0);
	return EXIT_SUCCESS;
}

// 停止扫描
int CDeviceComCtrl::iStopCapture(int  iScanRowLowerLimit, int  iScanRowUpperLimit)
{
	if (nullptr == m_pFPGAComCtrl)
	{
		ostringstream os;
		os << "FPGAComCtrl can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == m_pFPGAComCtrl->iStopCapture(iScanRowLowerLimit, iScanRowUpperLimit))
	{
		return EXIT_FAILURE;
	}
	// 关闭激光器
	iTurnOffLaser();
	// 关闭LED灯
	iTurnOffLED();

	stStateMsg stateMsg;
	stateMsg.m_enComType = enDeviceComType_Scanner;
	stateMsg.m_deviceStateCode.m_iCode = ~STATE_EMIT;
	stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperAnd;
	stateMsg.m_deviceErrorCode.m_iCode = 0;
	stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
	stateMsg.m_comStateCode.m_iCode = SCANNER_STOP;
	stateMsg.m_comStateCode.m_enCodeOperType = enCodeOperCopy;
	stateMsg.m_comErrorcode.m_iCode = 0;
	stateMsg.m_comErrorcode.m_enCodeOperType = enCodeOperOr;
	CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
	CDeviceStatusMng::GetInstance()->iSetScanRowRange(iScanRowLowerLimit, iScanRowUpperLimit);
	CDeviceStatusMng::GetInstance()->iSetMessage("System Ready...", 0);
	return EXIT_SUCCESS;
}


// 等待线程退出
void CDeviceComCtrl::wait()
{
	if (nullptr != m_pProberCtrl)
	{
		m_pProberCtrl->wait();
	}

	if (nullptr != m_pLaserCtrl)
	{
		m_pLaserCtrl->wait();
	}

	if (nullptr != m_pMotorCtrl)
	{
		m_pMotorCtrl->wait();
	}

	if (nullptr != m_pFPGAComCtrl)
	{
		m_pFPGAComCtrl->wait();
	}

	if (nullptr != m_pTempVoltSampleCtrl)
	{
		m_pTempVoltSampleCtrl->wait();
	}
	return;
}



// 退出线程
void CDeviceComCtrl::ExitThread()
{
	if (nullptr != m_pProberCtrl)
	{
		m_pProberCtrl->SetExitFlag(true);
	}

	if (nullptr != m_pLaserCtrl)
	{
		m_pLaserCtrl->SetExitFlag(true);
	}

	if (nullptr != m_pMotorCtrl)
	{
		m_pMotorCtrl->SetExitFlag(true);
	}

	if (nullptr != m_pFPGAComCtrl)
	{
		m_pFPGAComCtrl->SetExitFlag(true);
	}

	if (nullptr != m_pTempVoltSampleCtrl)
	{
		m_pTempVoltSampleCtrl->SetExitFlag(true);
	}
	return;
}

Log.h

#pragma once
#include <sstream>
#include <string>
#include <map>
#include <set>
#include <mutex>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <atlfile.h>
#endif
#include <time.h>
#include <sys/stat.h>
#include "SysConfigInfo.h"

using namespace std;

// 日志文件大小最大限制
const int    cniLogFileSizeMax = 20*1024*1024;
// 日志文件大小最小限制
const int    cniLogFileSizeMin = 20 * 1024;

// 日志最小个数
const int cniLogFileNumMin = 1;
// 日志文件最大个数
const int cniLogFileNumMax = 50;

// 检查日志内容是否达到日志文件限制的时间间隔
const int    cniCheckBreakSecs = 30;

// 文件名路径长度限制
const int    cniFilePathMax    = 512;

//日志等级
typedef enum enum_log_level
{
    Log_Debug   = 1,            //调试信息
    Log_Info    = 2,            //一般信息
    Log_Msg     = 3,            //消息
    Log_Alert   = 4,            //告警
    Log_Error   = 5,            //错误
    Log_Fatal   = 6,            //致命
}enLogLevel;

// 日志管理类声明
class CLog
{
public:
    // 析构函数
    ~CLog(void);

    // 初始化
    int iInitialize(const int& iLogLvel, const int& iLogFileNum, const long& lLogFileSize, const string& sFileName = cnsDefaultLogFileName);
    
    // 单联模式对象创建或获取
    static CLog * GetInstance();

    // 释放单联模式对象
    static void ReleaseInstance();

	// 判断日志等级
	inline bool bLogOK(const int & iMsgLevel)
	{
		return (iMsgLevel >= m_iLogLevel);
	}

    // 写日志
    void WriteLog(const char * sFunName,  int iLineNum, const string& sLog, const int& iLevel = 1);

	// 设置上位软件名
	inline void SetUpperSoftwareInfo(const string &sUpperSoftwareInfo)
	{
		{
			lock_guard<mutex>guard(m_mtxUpperSoftwareInfo);
			m_sUpperSoftwareInfo = sUpperSoftwareInfo;
		}
		return;
	}

	inline string sGetUpperSoftwareInfo()
	{
		string sUpperSoftwareInfo;
		{
			lock_guard<mutex>guard(m_mtxUpperSoftwareInfo);
			sUpperSoftwareInfo = m_sUpperSoftwareInfo;
		}
		return sUpperSoftwareInfo;
	}

private:
    // 打开日志文件
    void OpenLogFile();

    // 检查日志文件限制
    bool bCheckAndDealLogFile();

	// 设置日志参数
	void SetLogParam(const int& iLogLvel, const int& iLogFileNum, const long& lLogFileSize, const string& sFileName = cnsDefaultLogFileName);

	// 获取日志信息特征
	string sGetLogFileNameKeyword(const string & sFileName);

	// 获取日志文件的日期信息
	int iGetLogDate(time_t &tDate, const string & sFileName);

	// 从日志文件名获取日期信息
	string sGetDateFromFileName(const string & sFileName);
private:
    // 单例对象指针
    static CLog * m_pInst;

    // 构造函数
    CLog(const string& sFileName=cnsDefaultLogFileName);

    // 日志锁
#ifdef _WIN32
    HANDLE                  m_mtx;
#else
    pthread_mutex_t         m_mtx;
#endif

    // 日志文件句柄
    FILE                    *m_fp;

    // 日志文件名
    string                  m_sLogFileName;

    // 日志文件数量最大值
    int                     m_iLogFileNum;

    // 日志输出等级
    int                     m_iLogLevel;

    // 日志文件大小的阈值
    long                    m_lLogFileSize;
	
	// 上位机机名称
	string                  m_sUpperSoftwareInfo; // 上位机软件信息

	// 上位机名称互斥量
	mutex                   m_mtxUpperSoftwareInfo; // 上位机软件信息

	// 历史日志文件
	map<time_t, string>             m_dictHistoryLogFileName; // 历史文件名
};

Log.cpp

#include <stdlib.h>
#include <stdio.h>
#include "Log.h"
#include "UtilFun.h"
#include "FileOper.h"
#include "CommonUtil.h"

// 静态成员指针初始化
CLog * CLog::m_pInst = NULL;


// 日志等级与描述映射关系表类型
typedef map<int, string> LogLevel2DescDict;

// 日志等级与描述映射关系表 
LogLevel2DescDict cnDictLogLevel2Desc = { {Log_Debug,"Debug"}, {Log_Info,"Info"}, {Log_Msg, "Msg"}\
, {Log_Alert, "Alert"}, {Log_Error, "Error"}, {Log_Fatal, "Fatal"} };

// 日志文件名分割符
const string cnsFileNameSplitSeperator = "_";

/*************************************************
  Function:        CLog
  Description:     构造函数
  Input:
	  sFileName: 日志文件名
  Output:          无
  Return:          无
  Others:          无
*************************************************/
CLog::CLog(const string& sFileName)
	:m_sLogFileName(sFileName)
{
	m_iLogFileNum = cniLogFileNumMax;
	m_fp = NULL;
	m_lLogFileSize = cniLogFileSizeMax;
	m_iLogLevel = Log_Debug;
	m_sUpperSoftwareInfo.clear();
#ifdef _WIN32
	m_mtx = CreateMutex(NULL, FALSE, NULL);
#else
	m_mtx = PTHREAD_MUTEX_INITIALIZER;
#endif
	return;
}

/*************************************************
  Function:        iInitialize
  Description:     初始化函数
  Input:           无
  Output:          无
  Return:
	  0: 成功;
	  1:  失败
  Others:          无
*************************************************/
int CLog::iInitialize(const int& iLogLvel, const int& iLogFileNum, const long& lLogFileSize, const string& sFileName)
{
	SetLogParam(iLogLvel, iLogFileNum, lLogFileSize, sFileName);
	string sFileNameKeyword = sGetLogFileNameKeyword(sFileName);
	vector<string> seqHistoryLogFileName;
	FileOper::GetInstance()->iGetFileFromFolder(seqHistoryLogFileName, sFileNameKeyword);
	for (auto iter = seqHistoryLogFileName.begin(); iter != seqHistoryLogFileName.end(); iter++)
	{
		time_t tDate;
		if (EXIT_SUCCESS == iGetLogDate(tDate, *iter))
		{
			m_dictHistoryLogFileName[tDate] = *iter;
		}
	}
	return EXIT_SUCCESS;
}

/*************************************************
  Function:       ~CLog
  Description:    析构函数
  Input:          无
  Output:         无
  Return:         无
  Others:         无
*************************************************/
CLog::~CLog(void)
{
	if (m_fp)
	{
		fclose(m_fp);
		m_fp = NULL;
	}
	return;
}

/*************************************************
  Function:       GetInstance
  Description:    创建或获取单联对象指针
  Input:          无
  Output:         无
  Return:         单联对象指针
  Others:         无
*************************************************/
CLog * CLog::GetInstance()
{
	if (NULL == m_pInst)// 判断对象指针为空
	{
		// 创建指针对象
		m_pInst = new CLog();
	}/* end if (NULL == m_pInst)*/

	// 对象指针不为空
	return m_pInst;
}

/*************************************************
  Function:       ReleaseInstance
  Description:    释放单联对象指针
  Input:          无
  Output:         无
  Return:         无
  Others:         无
*************************************************/
void CLog::ReleaseInstance()
{
	if (NULL != m_pInst)// 单联对象指针存在
	{
		delete m_pInst;
		m_pInst = NULL;
	}/*end if (NULL != m_pInst)*/

	// 单联对象指针不存在
	return;
}


/*************************************************
  Function:       WriteLog
  Description:    写日志
  Input:
	  sFunName: 调用函数名
	  iLineNum: 代码行号
	  sLog:日志表述信息
	  iLevel:日志等级
  Output:         无
  Return:         单联对象指针
  Others:         无
*************************************************/
void CLog::WriteLog(const char * sFunName, int iLineNum, const string& sLog, const int& iLevel)
{
	// 日志等级判断
	if (iLevel < m_iLogLevel)
	{
		return;
	}
	
	// 获取当前时间
#ifdef _WIN32
	static time_t           stcCmpTime;
	time_t                  tCurTime;
	WaitForSingleObject(m_mtx, INFINITE);
	time(&tCurTime);
#else
	static time_t stcCmpTime;
	time_t  tCurTime;
	pthread_mutex_lock(&m_mtx);
	time(&tCurTime);
#endif

	// 检查日志信息是否达到间隔
	if ((tCurTime - stcCmpTime) > cniCheckBreakSecs)
	{
		// 检查日志信息是否达到阈值
		bCheckAndDealLogFile();
		stcCmpTime = tCurTime;
	}
	if (m_fp == NULL)
	{
		OpenLogFile();
	}
	if (m_fp == NULL)
	{
#ifdef _WIN32
		ReleaseMutex(m_mtx);
#else
		pthread_mutex_unlock(&m_mtx);
#endif
		return;
	}
	try
	{
		// 将秒时间转换为字符描述时间 
		struct timeval tvTime;
		gettimeofday(&tvTime, NULL);
		time_t tDate = tvTime.tv_sec;
		time_t tMsTime = tvTime.tv_usec / 1000;
		string sDate = CUtilFun::sIntDate2StrDate(tDate);
		sDate = sDate + "." + to_string(tMsTime);
		string sLogHead;
		{
			ostringstream os;
			string sUpperSoftwareInfo = sGetUpperSoftwareInfo();
			if (sUpperSoftwareInfo.empty())
			{
				os << sDate << "[" << sFunName << ":" << iLineNum << "] " << cnDictLogLevel2Desc[iLevel] << ":";
			}
			else
			{
				os << sDate << "[" << sUpperSoftwareInfo << "][" << sFunName << ":" << iLineNum << "] " << cnDictLogLevel2Desc[iLevel] << ":";
			}
			sLogHead = os.str();
		}
		// 记录日志时间
		fwrite(sLogHead.c_str(), 1, sLogHead.length(), m_fp);

		// 记录日志内容
		fwrite(sLog.c_str(), 1, sLog.size(), m_fp);

		// 关闭日志文件
		if (m_fp)
		{
			fclose(m_fp);
			m_fp = NULL;
		}
	}
	catch (...)
	{
		//ignore
	}
#ifdef _WIN32
	ReleaseMutex(m_mtx);
#else
	pthread_mutex_unlock(&m_mtx);
#endif
	return;
}

/*************************************************
  Function:       OpenLogFile
  Description:    打开日志文件
  Input:          无
  Output:         无
  Return:         单联对象指针
  Others:         无
*************************************************/
void CLog::OpenLogFile()
{
	if (m_fp)
	{
		fclose(m_fp);
		m_fp = NULL;
	}
#ifdef _WIN32
	errno_t iErr = fopen_s(&m_fp, m_sLogFileName.c_str(), "a+");
	if (0 != iErr)
	{
		m_fp = NULL;
	}
#else
	m_fp = fopen(m_sLogFileName.c_str(), "a+");
#endif
	return;
}

/*************************************************
  Function:       SetLogParam
  Description:    设置日志参数
  Input:
	 iLogLvel: 打印的日志等级
	 iLogFileNum: 日志文件最大个数
	 lLogFileSize: 单个日志文件最大字节数
	 sFileName:    日志文件名
  Output:         无
  Return:         无
  Others:         无
*************************************************/
void CLog::SetLogParam(const int& iLogLvel, const int& iLogFileNum, const long& lLogFileSize, const string& sFileName)
{
	// 设置日志等级
	m_iLogLevel = iLogLvel;

	// 设置日志文件数
	if (cniLogFileNumMin > iLogFileNum)
	{
		m_iLogFileNum = cniLogFileNumMin;
	}
	else if (cniLogFileNumMax < iLogFileNum)
	{
		m_iLogFileNum = cniLogFileNumMax;
	}
	else
	{
		m_iLogFileNum = iLogFileNum;
	}

	// 设置日志文件大小限制
	if (cniLogFileSizeMin > lLogFileSize)
	{
		m_lLogFileSize = cniLogFileSizeMin;
	}
	else if (lLogFileSize > cniLogFileSizeMax)
	{
		m_lLogFileSize = cniLogFileSizeMax;
	}
	else
	{
		m_lLogFileSize = lLogFileSize;
	}

	// 设置日志文件名
	if (!sFileName.empty())
	{
		m_sLogFileName = sFileName;
	}
	return;
}


// 获取日志信息特征
string CLog::sGetLogFileNameKeyword(const string & sFileName)
{
	string sFileNameWithoutSuffix;
	string sFileNameSuffix;
	FileOper::GetInstance()->iGetFileNameInfo(sFileNameWithoutSuffix, sFileNameSuffix, sFileName);
	string sKeyword = sFileNameWithoutSuffix + cnsFileNameSplitSeperator;
	return sKeyword;
}

/*************************************************
  Function:       SetLogParam
  Description:    检查日志文件限制
  Input:          无
  Output:         无
  Return:         无
  Others:         无
*************************************************/
bool CLog::bCheckAndDealLogFile()
{
	// 用于保存文件信息
	struct stat fileStat;
	memset(&fileStat, 0, sizeof(struct stat));

	// 获取指定文件名的的文件信息
	stat(m_sLogFileName.c_str(), &fileStat);

	//以字节为单位的文件长度
	long lFileSize = fileStat.st_size;

	// 如果文件超出配置大小则创建一个新的日志文件
	if (lFileSize >= m_lLogFileSize)
	{
		try
		{
			if (m_iLogFileNum > 1)
			{
				time_t tNow = time(NULL);
				string sHistoryLogFileName;
				if (!m_dictHistoryLogFileName.empty())
				{
					auto iter = m_dictHistoryLogFileName.crbegin();
					if (tNow < iter->first)
					{
						tNow = iter->first + 60;
					}
				}

				// 获取日志文件名与后缀
				string sLogFileNameWithoutSuffix;
				string sLogFileNameSuffix;
				FileOper::GetInstance()->iGetFileNameInfo(sLogFileNameWithoutSuffix, sLogFileNameSuffix, m_sLogFileName);
				sHistoryLogFileName = sLogFileNameWithoutSuffix + cnsFileNameSplitSeperator + CUtilFun::sIntDate2StrDateExt(tNow) + "." + sLogFileNameSuffix;
				if (m_iLogFileNum <= (m_dictHistoryLogFileName.size() + 1))
				{
					auto iter = m_dictHistoryLogFileName.begin();
					if (FileOper::GetInstance()->bRemoveFile(iter->second))
					{
						m_dictHistoryLogFileName.erase(iter);
					}
					else
					{
						perror(": \nError occurred while deleting the log file");
					}
				}

				// 日志文件重命名
				if (FileOper::GetInstance()->bRenameFile(sHistoryLogFileName, m_sLogFileName))
				{
					m_dictHistoryLogFileName[tNow] = sHistoryLogFileName;
				}
				else
				{
					perror(": \nError occurred while rename the log file");
				}
			}
			else
			{
				if (!FileOper::GetInstance()->bRemoveFile(m_sLogFileName))
				{
					perror(": \nError occurred while deleting the log file");
				}
			}
		}
		catch (...)
		{
			// 忽略错误
			;
		}
		return true;
	}
	return false;
}


// 获取日志文件的日期信息
int CLog::iGetLogDate(time_t &tDate, const string & sFileName)
{
	string sDateStr = sGetDateFromFileName(sFileName);
	if (sDateStr.empty())
	{
		return EXIT_FAILURE;
	}
	else
	{
		tDate = CUtilFun::tStrDate2IntDateExt(sDateStr);
	}
	return EXIT_SUCCESS;
}

// 从日志文件名获取日期信息
string CLog::sGetDateFromFileName(const string & sFileName)
{
	string sDateStr = "";
	size_t nPos = sFileName.find_first_of(cnsFileNameSplitSeperator);
	if (string::npos != nPos)
	{
		sDateStr = sFileName.substr(nPos + 1);
	}
	return sDateStr;
}

main.c

// Tremolite.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <csignal>
#include <iomanip>
#include "Log.h"
#include "SysConfigMng.h"
#include "DataCommInt.h"
#include "BeatHeart.h"
#include "CommandRecv.h"
#include "CommandProc.h"
#include "CommandResponse.h"
#include "DeviceStatusReport.h"
#include "LumDataReport.h"
#include "DeviceParamMng.h"
#include "DeviceStatusMng.h"
#include "DeviceComCtrl.h"
#include "SettingParamMng.h"
#include "LumDataSample.h"
#include "MemAccHandle.h"
#include "SystemStatus.h"
using namespace std;

int main()
{
	// 屏蔽SIGPIPE
	struct sigaction sa;
	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, 0);
	// 获取系统启动状态
	{
		CMemAccHandle memAccHandle;
		if (EXIT_FAILURE == memAccHandle.iInitialize())
		{
			ostringstream os;
			os << "failed to initialze MemAccHandle" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		}
		else
		{
			CSystemStatus systemStatus(&memAccHandle);
			if (EXIT_FAILURE == systemStatus.iInitialize())
			{
				ostringstream os;
				os << "failed to initialze SystemStatus" << endl;
				CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			}
			else
			{
				unsigned int uiSystemStatus = 0;
				if (EXIT_FAILURE == systemStatus.iGetRebootStatus(uiSystemStatus))
				{
					ostringstream os;
					os << "failed to get RebootStatus" << endl;
					CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
				}
				else
				{
					ostringstream os;
					os << "RebootStatus:0x" << hex << setw(8) << setfill('0') << uiSystemStatus << endl;
					CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
				}
			}
		}
	}
	
	// 初始化系统配置模块
	if (EXIT_FAILURE == CSysConfigMng::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize SysConfigMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize SysConfigMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	
	// 初始化日志模块
	stLogConfig logConfig = CSysConfigMng::GetInstance()->GetLogConfig();
	CLog::GetInstance()->iInitialize(logConfig.m_iLogLevel, logConfig.m_iLogMaxFileNum, logConfig.m_iLogFileMaxSize, logConfig.m_sLogFileName);

	
	

	// 初始化命令接收模块
	if (EXIT_FAILURE == CCommandRecv::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize CommandRecv" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize BeatHeart" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化上位机下位机通信协议接口
	if (EXIT_FAILURE == CDataCommInt::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize DataCommInt" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize DataCommInt" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化状态上报模块
	if (EXIT_FAILURE == CDeviceStatusReport::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize DeviceStatusReport" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize DeviceStatusReport" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化设备状态模块
	if (EXIT_FAILURE == CDeviceStatusMng::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize DeviceStatusMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize DeviceStatusMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化设备参数管理模块
	if (EXIT_FAILURE == CDeviceParamMng::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize DeviceParamMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize DeviceParamMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	
	// 设备模块第1阶段初始化
	if (EXIT_FAILURE == CDeviceComCtrl::GetInstance()->iOneStageInit())
	{
		ostringstream os;
		os << "failed to initialize one stage" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed  to initialize one stage" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化设备参数设置模块
	if (EXIT_FAILURE == CSettingParamMng::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize SettingParamMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize SettingParamMng" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 灯板闪烁三次
	for (uint8_t p = 0; p < 3; p++)
	{
		CDeviceComCtrl::GetInstance()->iTurnOnLED(); 
		usleep(400000);
		CDeviceComCtrl::GetInstance()->iTurnOffLED();
		usleep(400000);
	}

	// 初始化亮度数据上报模块
	if (EXIT_FAILURE == CLumDataReport::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize LumDataReport" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize LumDataReport" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 亮度数据采样模块初始化
	if (EXIT_FAILURE == CLumDataSample::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize LumDataSample" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize LumDataSample" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化心跳模块
	if (EXIT_FAILURE == CBeatHeart::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize BeatHeart" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialize BeatHeart" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	// 设备第2阶段初始化
	if (EXIT_FAILURE == CDeviceComCtrl::GetInstance()->iTwoStageInit())
	{
		ostringstream os;
		os << "failed to initialze tow stage" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << "succeed to initialze two stage" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化命令处理模块
	if (EXIT_FAILURE == CCommandProc::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize CommandProc" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << " succeed to initialize CommandProc" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 初始化命令响应模块
	if (EXIT_FAILURE == CCommandResponse::GetInstance()->iInitialize())
	{
		ostringstream os;
		os << "failed to initialize CommandResponse" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	else
	{
		ostringstream os;
		os << " succeed to initialize CommandResponse" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	CBeatHeart::GetInstance()->wait();
	CCommandResponse::GetInstance()->wait();
	CDeviceStatusMng::GetInstance()->wait();
	CLumDataReport::GetInstance()->wait();
	CLumDataSample::GetInstance()->wait();
	CDataCommInt::GetInstance()->wait();
	CDeviceComCtrl::GetInstance()->wait();
	delete CCommandResponse::GetInstance();
	delete CCommandProc::GetInstance();
	delete CDeviceComCtrl::GetInstance();
	delete CSettingParamMng::GetInstance();
	delete CDeviceParamMng::GetInstance();
	delete CDeviceStatusReport::GetInstance();
	delete CBeatHeart::GetInstance();
	delete CLumDataReport::GetInstance();
	delete CLumDataSample::GetInstance();
	delete CDataCommInt::GetInstance();
	delete CCommandRecv::GetInstance();
	delete CDeviceStatusMng::GetInstance();
	delete CLog::GetInstance();
	delete CSysConfigMng::GetInstance();
	return EXIT_SUCCESS;
}

DataCommInt.h

//
//  版权      : 版权所有 (C) 精微视达科技有限公司
//  文件名    : DataCommInt.h
//  作者      : 
//  版本      : V1.0
//  日期      : 2023-06-09
//  描述      : 
//              本文件用于上位机下位机通信定义。
//  其它      : 无
///
#pragma once
#include "ZMQSender.h"
#include "ZMQReceiver.h"
#include "ThriftRequestClient.h"
#include "ThriftResponseClient.h"
#include "ThriftServer.h"
#include "ThriftStructCodec.h"

class CDataCommInt
{
public:
	// 析构函数
	~CDataCommInt();
public:
	static CDataCommInt * GetInstance();
public:
	// 初始化
	int iInitialize();
	// 发送告警信息
	int iSendWarrning(const MsgRequest& msgRequire);
	// 发送心跳消息
	int iBeatHeart(const MsgRequest& msgRequire);
	// 发送状态信息
	int iSendStatus(const MsgRequest& msgRequire);
	// 响应消息
	int iResponseMsg(const MsgResponse& msgReponse);
	// 发送请求消息
	int iSendRequireMsg(ReturnMsg & returnMsg, const MsgRequest & msgRequest);
	// 发送亮度数据
	int iSendLumData(unsigned char * ucData, int iDataLen);
	// 取接收数据
	int iFetchRecvData(string & sRecvData);
	// 判断是否有接收数据
	bool bHadRecvData();
	// 等待线程退出
	void wait();
	// 退出线程
	void ExitThread();
	// 编码
	template<class T>
	int iEncode(string &sBinary, const T &tructInfo)
	{
		return m_structCodec.iEncode(sBinary, tructInfo);
	}

	// 解码
	template<class T>
	int iDecode(T & tructInfo, const string & sBinary)
	{
		return m_structCodec.iDecode(tructInfo, sBinary);
	}
private:
	// ZMQ发送器
	CZMQSender *m_pZMQSender;

	// ZMQ接收器
	CZMQReceiver * m_pZMQReceiver;

	// Thrfit发送消息客户端
	CThriftRequestClient * m_pRequestClient;   

	// Thrift接收消息客户端
	CThriftResponseClient * m_pResponseClient;

	// Thrift请求消息服务端
	CThriftServer * m_pRequestServer; 

	// Thrift响应消息服务端
	CThriftServer * m_pResponseServer;

	// Thrift结构体编解码
	CThriftStructCodec m_structCodec;
private:
	// 构造函数
	CDataCommInt();

	static CDataCommInt * m_pInst;
};

DataCommInt.cpp

#include "DataCommInt.h"
#include "ThriftRequestClientFactory.h"
#include "ThriftResponseClientFactory.h"
#include "ThriftServerFactory.h"
#include "ZMQReceiverFactory.h"
#include "ZMQSenderFactory.h"
#include "SysConfigMng.h"
CDataCommInt * CDataCommInt::m_pInst = nullptr;


// 构造函数
CDataCommInt::CDataCommInt()
{
	m_pZMQSender = nullptr;
	m_pZMQReceiver = nullptr;
	m_pRequestClient = nullptr;
	m_pResponseClient = nullptr;
	m_pRequestServer = nullptr;
	m_pResponseServer = nullptr;
	return;
}

// 析构函数
CDataCommInt::~CDataCommInt()
{
	if (nullptr != m_pZMQSender)
	{
		delete m_pZMQSender;
		m_pZMQSender = nullptr;
	}
	if (nullptr != m_pZMQReceiver)
	{
		delete m_pZMQReceiver;
		m_pZMQReceiver = nullptr;
	}
	if (nullptr != m_pRequestClient)
	{
		delete m_pRequestClient;
		m_pRequestClient = nullptr;
	}
	if (nullptr != m_pResponseClient)
	{
		delete m_pResponseClient;
		m_pResponseClient = nullptr;
	}
	if (nullptr != m_pRequestServer)
	{
		delete m_pRequestServer;
		m_pRequestServer = nullptr;
	}
	if (nullptr != m_pResponseServer)
	{
		delete m_pResponseServer;
		m_pResponseServer = nullptr;
	}

	if (nullptr == CThriftRequestClientFactory::GetInstance())
	{
		delete CThriftRequestClientFactory::GetInstance();
	}

	if (nullptr == CThriftResponseClientFactory::GetInstance())
	{
		delete CThriftResponseClientFactory::GetInstance();
	}

	if (nullptr == CThriftServerFactory::GetInstance())
	{
		delete CThriftServerFactory::GetInstance();
	}

	if (nullptr == CZMQReceiverFactory::GetInstance())
	{
		delete CZMQReceiverFactory::GetInstance();
	}

	if (nullptr == CZMQSenderFactory::GetInstance())
	{
		delete CZMQSenderFactory::GetInstance();
	}
	return;
}

CDataCommInt * CDataCommInt::GetInstance()
{
	if (nullptr == m_pInst)
	{
		m_pInst = new CDataCommInt();
	}
	return m_pInst;
}

// 初始化
int CDataCommInt::iInitialize()
{
	ostringstream os;
	os << "CDataCommInt Initialize begin" << endl;
	CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	stDataCommIntConfig dataCommIntConfig = CSysConfigMng::GetInstance()->GetDataCommIntConfig();

	// 初始化ZMQSender
	m_pZMQSender = CZMQSenderFactory::GetInstance()->CreateZMQSender(dataCommIntConfig.m_sendLumDataCommIntConfig.m_sServerIP \
		, dataCommIntConfig.m_sendLumDataCommIntConfig.m_iListenPort);
	if (nullptr == m_pZMQSender)
	{
		os.str("");
		os << "failed to malloc memory for ZMQSender" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	// 初始化ThriftResponseClient
	m_pResponseClient = CThriftResponseClientFactory::GetInstance()->CreateThriftResponseClient(\
		dataCommIntConfig.m_sendCmdCommIntConfig.m_iProtocolType\
		, dataCommIntConfig.m_sendCmdCommIntConfig.m_commCommonConfig.m_sServerIP\
		, dataCommIntConfig.m_sendCmdCommIntConfig.m_commCommonConfig.m_iListenPort\
		, dataCommIntConfig.m_sendCmdCommIntConfig.m_sslCertificateConfig.m_sSSLPubCertificate\
		, dataCommIntConfig.m_sendCmdCommIntConfig.m_sslCertificateConfig.m_sSSLPriCertificate\
		, dataCommIntConfig.m_sendCmdCommIntConfig.m_sslCertificateConfig.m_sSSLTrustedCertificate);
	if (nullptr == m_pResponseClient)
	{
		os.str("");
		os << "failed to malloc memory for ThriftResponseClient" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	// 初始化RequestServer
	m_pRequestServer = CThriftServerFactory::GetInstance()->CreateThriftServer(0\
		, dataCommIntConfig.m_recvCmdCommIntConfig.m_iProtocolType\
		, dataCommIntConfig.m_recvCmdCommIntConfig.m_commCommonConfig.m_iListenPort\
		, dataCommIntConfig.m_recvCmdCommIntConfig.m_sslCertificateConfig.m_sSSLPubCertificate\
		, dataCommIntConfig.m_recvCmdCommIntConfig.m_sslCertificateConfig.m_sSSLPriCertificate);
	if (nullptr == m_pRequestServer)
	{
		os.str("");
		os << "failed to malloc memory for RequestServer" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	os.str("");
	os << "CDataCommInt Initialize end" << endl;
	CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	return EXIT_SUCCESS;
}

// 发送告警信息
int CDataCommInt::iSendWarrning(const MsgRequest& msgRequire)
{
	if (nullptr != m_pResponseClient)
	{
		return m_pResponseClient->iSendWarnning(msgRequire);
	}
	else
	{
		ostringstream os;
		os << "ResponseClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}

// 发送心跳消息
int CDataCommInt::iBeatHeart(const MsgRequest& msgRequire)
{
	if (nullptr != m_pResponseClient)
	{
		return m_pResponseClient->iBeatHeart(msgRequire);
	}
	else
	{
		ostringstream os;
		os << "ResponseClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}


// 发送状态信息
int CDataCommInt::iSendStatus(const MsgRequest& msgRequire)
{
	if (nullptr != m_pResponseClient)
	{
		return m_pResponseClient->iSendStatus(msgRequire);
	}
	else
	{
		ostringstream os;
		os << "ResponseClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}
// 响应消息
int CDataCommInt::iResponseMsg(const MsgResponse& msgReponse)
{
	if (nullptr != m_pResponseClient)
	{
		return m_pResponseClient->iResponseMsg(msgReponse);
	}
	else
	{
		ostringstream os;
		os << "ResponseClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}
// 发送请求消息
int CDataCommInt::iSendRequireMsg(ReturnMsg & returnMsg, const MsgRequest & msgRequest)
{
	if (nullptr != m_pRequestClient)
	{
		return m_pRequestClient->iRequireMsg(returnMsg, msgRequest);
	}
	else
	{
		ostringstream os;
		os << "RequestClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}
// 发送亮度数据
int CDataCommInt::iSendLumData(unsigned char * ucData, int iDataLen)
{
	if (nullptr != m_pZMQSender)
	{
		return m_pZMQSender->iSendData(ucData, iDataLen);
	}
	else
	{
		ostringstream os;
		os << "RequestClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}
// 取接收数据
int CDataCommInt::iFetchRecvData(string & sRecvData)
{
	if (nullptr != m_pZMQReceiver)
	{
		return m_pZMQReceiver->iFetchRecvData(sRecvData);
	}
	else
	{
		ostringstream os;
		os << "RequestClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}
// 判断是否有接收数据
bool CDataCommInt::bHadRecvData()
{
	if (nullptr != m_pZMQReceiver)
	{
		return m_pZMQReceiver->bHadRecvData();
	}
	else
	{
		ostringstream os;
		os << "RequestClientPtr can't be empty" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
}


// 等待线程退出
void CDataCommInt::wait()
{
	if (nullptr != m_pZMQReceiver)
	{
		m_pZMQReceiver->wait();
	}

	if (nullptr != m_pRequestServer)
	{
		m_pRequestServer->wait();
	}

	if (nullptr != m_pResponseServer)
	{
		m_pResponseServer->wait();
	}
	return;
}



// 退出线程
void CDataCommInt::ExitThread()
{
	if (nullptr != m_pZMQReceiver)
	{
		m_pZMQReceiver->SetExitFlag(true);
	}

	if (nullptr != m_pRequestServer)
	{
		m_pRequestServer->SetExitFlag(true);
	}

	if (nullptr != m_pResponseServer)
	{
		m_pResponseServer->SetExitFlag(true);
	}
	return;
}

ZMQsender.h

#include <string>
using namespace std;

class CZMQSender
{
public:
	// 构造函数
	CZMQSender(const string &sHost, int iPort);

	// 构造函数
	~CZMQSender();
public:
	virtual int iSendData(unsigned char * ucData, int iDataLen) = 0;
public:
	// 设置主机IP
	inline void SetHost(const string &sHost)
	{
		m_sHost = sHost;
		return;
	}
	
	// 获取主机IP
	inline string sGetHost() const
	{
		return m_sHost;
	}

	// 设置监听端口
	inline void SetPort(int iPort)
	{
		m_iPort = iPort;
	}

	// 获取监听端口
	inline int iGetPort() const
	{
		return m_iPort;
	}

	// 设置最后连接时间
	inline void SetLastTime(time_t tLastTime)
	{
		m_tLastTime = tLastTime;
		return;
	}

	// 获取最后连接时间
	inline time_t tGetLastTime() const
	{
		return m_tLastTime;
	}
protected:
	// 初始化发送器
	virtual void InitSender() = 0;

	// 关闭发送器
	virtual void CloseSend() = 0;

	// 发送器重连
	virtual void Reconnect() = 0;
private:
	// 最后连接时间
	time_t m_tLastTime;

	// 主机IP
	string m_sHost;

	// 监听端口
	int m_iPort;
};

#include "ZMQSender.h"

// 构造函数
CZMQSender::CZMQSender(const string &sHost, int iPort)
{
	m_sHost = sHost;
	m_iPort = iPort;
	return;
}

// 构造函数
CZMQSender::~CZMQSender()
{
	return;
}

ZMQReceiver.h

#pragma once
#include <mutex>
#include <vector>
#include <stdlib.h>
#include "ThreadProc.h"
using namespace std;

class CZMQReceiver: public CThreadProc
{
public:
	// 构造函数
	CZMQReceiver(const string & sHost, int iPort);

	// 析构函数
	~CZMQReceiver() noexcept;
public:
	// 服务
	virtual int src(int id) override;
public:
	// 接收队列是否有数据
	inline bool bHadRecvData()
	{
		bool bHasData = false;
		{
			lock_guard<mutex>guard(m_mtxAccessRecvData);
			if (!m_seqRecvData.empty())
			{
				bHasData = true;
			}
		}
		return bHasData;
	}

	// 从队列中取数据
	inline int iFetchRecvData(string & sRecvData)
	{
		int iRet = EXIT_FAILURE;
		{
			lock_guard<mutex>guard(m_mtxAccessRecvData);
			if (!m_seqRecvData.empty())
			{
				 auto iter = m_seqRecvData.begin();
				 sRecvData = *iter;
				 m_seqRecvData.erase(iter);
				 iRet = EXIT_SUCCESS;
			}
		}
		return iRet;
	}
public:
	inline void SetPort(int iPort)
	{
		m_iPort = iPort;
		return;
	}
	inline int iGetPort()const
	{
		return m_iPort;
	}
	inline void SetHost(const string & sHost)
	{
		m_sHost = sHost;
		return;
	}
	inline string sGetHost() const
	{
		return m_sHost;
	}

	// 设置最后连接时间
	inline void SetLastTime(time_t tLastTime)
	{
		m_tLastTime = tLastTime;
		return;
	}

	// 获取最后连接时间
	inline time_t tGetLastTime() const
	{
		return m_tLastTime;
	}

protected:
	// 初始化接收器
	virtual void InitReceiver() = 0;

	// 接收发送器
	virtual void CloseReceiver() = 0;

	// 接收器重连
	virtual void Reconnect() = 0;

	// 接收数据
	virtual void RecvData(string & sRecvData) = 0;

	// 接收数据线程
	void RecvDataThread();
private:
	// 监听端口
	int m_iPort;

	// 主机IP
	string m_sHost;

	// 接收数据队列
	vector<string> m_seqRecvData;

	// 接收数据互斥锁
	mutex m_mtxAccessRecvData;

	// 最后连接时间
	time_t m_tLastTime;
};

#include <stdlib.h>
#include "ZMQReceiver.h"

// 构造函数
CZMQReceiver::CZMQReceiver(const string & sHost, int iPort)
	:CThreadProc(1)
{
	m_sHost = sHost;
	m_iPort = iPort;
	return;
}

// 服务
int CZMQReceiver::src(int id)
{
	if (0 == id)
	{
		RecvDataThread();
	}
	return EXIT_SUCCESS;
}

// 析构函数
CZMQReceiver::~CZMQReceiver()
{
	return;
}

// 接收数据线程
void CZMQReceiver::RecvDataThread()
{
	bool bExitFlag = bGetExitFlag();
	while (!bExitFlag)
	{
		string sRecvData;
		RecvData(sRecvData);
		{
			lock_guard<mutex>guard(m_mtxAccessRecvData);
			m_seqRecvData.push_back(sRecvData);
		}
		bExitFlag = bGetExitFlag();
	}
	return;
}

ThriftSever.h

#pragma once
#include "ThreadProc.h"
// service处理默认线程数
const int cniServerThreadNum = 10;
// 默认处理任务数,不受限制
const int cniServerTaskNum = 0;

class CThriftServer:public CThreadProc
{
public:
	// 构造函数
	CThriftServer(int iPort);

	// 析构函数
	~CThriftServer();
public:
	// 停止工作
	virtual void StopWork();

	// 设置端口号
	inline void SetPort(int iPort)
	{
		m_iPort = iPort;
		return;
	}

	// 获取端口号
	int iGetPort() const
	{
		return m_iPort;
	}

	// 线程调用
	virtual int src(int id) override;
protected:
	// 开始工作
	virtual void StartWork() = 0;

	// 初始化服务端
	virtual void InitServer() = 0;

	// 接收线程
	void RecvThread();
private:
	// 端口号
	int m_iPort;
};

#include <stdlib.h>
#include "ThriftServer.h"

// 构造函数
CThriftServer::CThriftServer(int iPort):
	CThreadProc(1)
{
	m_iPort = iPort;
	return;
}

// 析构函数
CThriftServer::~CThriftServer()
{
	StopWork();

	return;
}

// 停止工作
void CThriftServer::StopWork()
{
	return;
}

// 线程调用
int CThriftServer::src(int id)
{
	if (0 == id)
	{
		RecvThread();
	}
	return EXIT_SUCCESS;
}


// 接收线程
void CThriftServer::RecvThread()
{
	bool bExitFlag = bGetExitFlag();
	while (!bExitFlag)
	{
		StartWork();
		bExitFlag = bGetExitFlag();
		if (!bExitFlag)
		{
			StopWork();
		}
	}
	return;
}

ThriftClient.h

#pragma once
#include <string>
#include <mutex>
using namespace std;
// 链接超时时间,3s
const int cniConnectTimeout = 3000;
// 发送超时时间
const int cniSendTimeout = 5000;

class CThriftClient
{
public:
	// 构造函数
	CThriftClient(const string & sHost, int iPort);

	// 析构函数
	virtual ~CThriftClient();
public:
	// 设置主机地址
	inline void SetHost(const string & sHost)
	{
		m_sHost = sHost;
		return;
	}

	// 获取主机地址
	inline string sGetHost() const
	{
		return m_sHost;
	}

	// 设置端口号
	inline void SetPort(int iPort)
	{
		m_iPort = iPort;
		return;
	}

	// 获取端口号
	inline int iGetPort() const
	{
		return m_iPort;
	}

	// 设置最后连接时间
	inline void SetLastTime(time_t tLastTime)
	{
		m_tLastTime = tLastTime;
		return;
	}

	// 获取最后连接时间
	inline time_t tGetLastTime() const
	{
		return m_tLastTime;
	}

protected:
	// 客户端锁
	mutex m_mtxClient;
protected:
	// 初始化客户端
	virtual void InitClient() = 0;
	// 关闭客户端
	virtual void CloseClient() = 0;
	// 客户端重连
	void Reconnect();
private:
	// 服务端IP地址
	string m_sHost;
	// 服务端监听地址
	int m_iPort;
	// 客户端最后连接时间
	time_t m_tLastTime;
};

#include <time.h>
#include "ThriftClient.h"

// 异常重连间隔时间
const int cniReconnectInterval = 3;

// 构造函数
CThriftClient::CThriftClient(const string & sHost, int iPort)
{
	m_sHost = sHost;
	m_iPort = iPort;
	m_tLastTime = time(NULL);
	return;
}

// 析构函数
CThriftClient::~CThriftClient()
{
	return;
}

// 客户端重连
void CThriftClient::Reconnect()
{
	{
		lock_guard<mutex>guard(m_mtxClient);
		time_t tTimeInterval = time(NULL) - tGetLastTime();
		if (cniReconnectInterval < tTimeInterval)
		{

			CloseClient();
			InitClient();
		}
	}
	return;
}

UartCtrl.h  Uart控制基类定义

#pragma once
#include <string>
using namespace std;
class CUartCtrl
{
public:
	// 构造函数
	CUartCtrl();
	// 构造函数
	CUartCtrl(const string & sDriverFile, int iUartSpeed);
	// 析构函数
	~CUartCtrl();
	// 初始化
	int iInitialize();
public:
	// 读数据
	virtual int iRead(unsigned char * rdBuf, int iRdSize) = 0;
	// 写数据
	virtual int iWrite(unsigned char * wrBuf, int iWrSize) = 0;
protected:
	// 获取比特率
	int iGetUartSpeedMode(int & iSpeedMode);
	// 设置串口
	virtual int iSetUart(int iFlowCtrl, int iBits, int iStopBits, int iParity) = 0;
public:
	// 设置驱动文件
	inline void SetDriverFile(const string & sDriverFile)
	{
		m_sDriverFile = sDriverFile;
		return;
	}
	// 获取驱动文件
	inline string sGetDriverFile() const
	{
		return m_sDriverFile;
	}
	// 设置串口的比特率
	inline void SetUartSpeed(int iUartSpeed)
	{
		m_iUartSpeed = iUartSpeed;
		return;
	}

	// 获取串口的比特率
	inline int iGetUartSpeed() const
	{
		return m_iUartSpeed;
	}
protected:
	// 驱动文件句柄
	int m_iDriverFileHandle;
private:
	// 驱动文件
	string m_sDriverFile;
	// 串口的比特率
	int m_iUartSpeed;
};

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include "Log.h"
#include "UartCtrl.h"

// 构造函数
CUartCtrl::CUartCtrl()
{
	m_iDriverFileHandle = -1;
	return;
}

// 构造函数
CUartCtrl::CUartCtrl(const string & sDriverFile, int iUartSpeed)
{
	m_sDriverFile = sDriverFile;
	m_iUartSpeed = iUartSpeed;
	m_iDriverFileHandle = -1;
	return;
}

// 析构函数
CUartCtrl::~CUartCtrl()
{
	if (-1 != m_iDriverFileHandle)
	{
		close(m_iDriverFileHandle);
		m_iDriverFileHandle = -1;
	}
	return;
}

// 初始化
int CUartCtrl::iInitialize()
{
	m_iDriverFileHandle = open(m_sDriverFile.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
	if (-1 == m_iDriverFileHandle)
	{
		ostringstream os;
		os << "failed to open File[" << m_sDriverFile << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == iSetUart(0, 8, 1, 'N'))
	{
		ostringstream os;
		os << "failed to configure [" << m_sDriverFile << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}


// 获取比特率
int CUartCtrl::iGetUartSpeedMode(int & iSpeedMode)
{
	int iUartSpeed = iGetUartSpeed();
	unsigned int uiUartSpeedMode = 0;
	switch (iUartSpeed)
	{
	case 50:
		uiUartSpeedMode = 1;
		break;
	case 75:
		uiUartSpeedMode = 2;
		break;
	case 110:
		uiUartSpeedMode = 3;
		break;
	case 134:
		uiUartSpeedMode = 4;
		break;
	case 150:
		uiUartSpeedMode = 5;
		break;
	case 200:
		uiUartSpeedMode = 6;
		break;
	case 300:
		uiUartSpeedMode = 7;
		break;
	case 600:
		uiUartSpeedMode = 8;
		break;
	case 1200:
		uiUartSpeedMode = 9;
		break;
	case 1800:
		uiUartSpeedMode = 10;
		break;
	case 2400:
		uiUartSpeedMode = 11;
		break;
	case 4800:
		uiUartSpeedMode = 12;
		break;
	case 9600:
		uiUartSpeedMode = 13;
		break;
	case 19200:
		uiUartSpeedMode = 14;
		break;
	case 38400:
		uiUartSpeedMode = 15;
		break;
	case 57600:
		uiUartSpeedMode = 4097;
		break;
	case 115200:
		uiUartSpeedMode = 4098;
		break;
	case 230400:
		uiUartSpeedMode = 4099;
		break;
	case 460800:
		uiUartSpeedMode = 4100;
		break;
	case 500000:
		uiUartSpeedMode = 4101;
		break;
	case 576000:
		uiUartSpeedMode = 4102;
		break;
	case 921600:
		uiUartSpeedMode = 4103;
		break;
	case 1000000:
		uiUartSpeedMode = 4104;
		break;
	case 1152000:
		uiUartSpeedMode = 4105;
		break;
	case 1500000:
		uiUartSpeedMode = 4106;
		break;
	case 2000000:
		uiUartSpeedMode = 4107;
		break;
	case 2500000:
		uiUartSpeedMode = 4108;
		break;
	case 3000000:
		uiUartSpeedMode = 4109;
		break;
	case 3500000:
		uiUartSpeedMode = 4110;
		break;
	case 4000000:
		uiUartSpeedMode = 4111;
		break;
	default:
	{
		ostringstream os;
		os << "UartSpeed[" << iUartSpeed << "] No Supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}
	iSpeedMode = uiUartSpeedMode;
	return EXIT_SUCCESS;
}

Thread.h

#pragma once
#include <thread>
#include <vector>

using namespace std;

class CThreadProc
{
public:
    CThreadProc();
    
	CThreadProc(int iThreadNum);
    
	virtual ~CThreadProc();

    // 运行
    int open();

    // 服务
    virtual int src(int id) = 0;
   
    // 等待线程结束
    void wait();

    // 获取退出信号
    inline bool bGetExitFlag() const
    {
        return m_bExit;
    }
    
    // 设置线程退出信号
    inline void SetExitFlag(bool bExit)
    {
        m_bExit = bExit;
    }

    // 获取线程数
    inline int GetThreadNum() const
    {
        return m_iThreadNum;
    }

    // 设置线程数
    inline void SetThreadNum(int iThreadNum)
    {
        m_iThreadNum = iThreadNum;
        return;
	}

	// 绑定CPU核
	void BindCPU(int iCPUIndex);
private:
    bool m_bExit; // 线程退出标识
    int  m_iThreadNum; // 线程数
    vector<shared_ptr<thread>> m_seqThread; // 线程列表
};

#include <stdlib.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <sched.h>
#include "Log.h"
#include "ThreadProc.h"


CThreadProc::CThreadProc()
{
	SetExitFlag(false);
	return;
}


CThreadProc::~CThreadProc()
{
	SetExitFlag(true);
	return;
}

CThreadProc::CThreadProc(int iThreadNum)
{
    m_iThreadNum = iThreadNum;
	SetExitFlag(false);
    return;
}

// 打开线程
int CThreadProc::open()
{
    for (int i = 0; i < m_iThreadNum; i++)
    {
        shared_ptr<thread> t = make_shared<thread>(&CThreadProc::src, this, i); 
        m_seqThread.push_back(t);
    }
    return EXIT_SUCCESS;
}
   
// 等待线程结束
void CThreadProc::wait()
{
    for (int i = 0; i < m_iThreadNum; i++)
    {
         m_seqThread[i]->join();
    }
    return;
}


// 绑定CPU核
void CThreadProc::BindCPU(int iCPUIndex)
{
	int iCpuNum = sysconf(_SC_NPROCESSORS_CONF);
	if (iCPUIndex >= iCpuNum || iCPUIndex < 0)
	{
		ostringstream os;
		os << "CPUIndex[" << iCPUIndex << "] more than CPUNum[" << iCpuNum << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	cpu_set_t set;
	CPU_ZERO(&set);
	CPU_SET(iCPUIndex, &set);
	if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
	{
		ostringstream os;
		os << "failed to bind cpu0" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	return;
}

DeviceParamIO.h

#pragma once
#include "InnerDeviceInfo.h"
#include "ConfigFile.h"
class CDeviceParamIO
{
public:
	// 构造函数
	CDeviceParamIO();
	// 析构函数
	~CDeviceParamIO();
	// 初始化
	int iInitialize(const string & sConfigFile);
public:
	// 解析设备描述信息
	int iParseDeviceDesc(stDeviceDesc & deviceDesc, const string & sSec);
	// 解析设备记录信息
	int iParseDeviceRecordInfo(stDeviceRecordInfo & deviceRecordInfo, const string & sSec);
	// 解析扫描类型信息
	int iParseScanType(int iScanDirectionType, const string & sSec);
	// 解析探头清晰对焦位置
	int iParseProberClearPos(stProberClearMotorPosInfo & proberClearMotorPosInfo, const string & sSec);
	// 解析激光功率信息
	int iParseLaserPowerInfo(stLaserPowerInfo & laserPowerInfo, const string & sSec);
	// 解析电机位置信息
	int iParseMotorPosInfo(stMotorPosInfo & motor, const string & sSec);
	// 解析探头内部型号相关信息
	int iParseProberInnerCodeRelativeInfoDict(map<string, int> &dictInnerCode2proberInnerCodeRelativeInfo, const string &sSec);
	// 解析匹配的探头型号列表
	int iParseMatchedProberModelList(vector<string> & seqProberModelList, const string & sSec);
	// 解析光纤束相关信息
	int iParseFiberBundleTypeRelativeInfoDict(map<string, stFiberBundleTypeRelativeInfo> &dictFiberBundleTypeRelativeInfo, const string & sSec);
	// 解析探头型号与探头的映射配置文件
	int iParseProberModel2InnerCodeFile(string & sProberModel2InnerCodeFile, const string &Sec);
protected:
	// 解析探头内部型号相关信息
	int iParseProberInnerCodeRelativeInfo(int & proberInnerCodeRelativeInfo, const string &sProberInnerCode, const string &sSec);
	// 解析光纤束相关信息
	int iParseFiberBundleTypeRelativeInfo(stFiberBundleTypeRelativeInfo &fiberBundleTypeRelativeInfo, const string &sFiberBundleType, const string & sSec);
	// 解析畸变校正参数
	int iParseCorrrectionParam(stCorrectionParam & correctionParam, const string &sProberInnerCode, const string &sSec);
	// 解析行对齐算法参数
	int iParseLineAlignAlgParam(stLineAlignAlgParam & lineAlignAlgParam, const string &sProberInnerCode, const string &sSec);
	// 解析探头内部型号相关信息
	int iParseProberInnerCodeRelativeInfo(stProberInnerCodeRelativeInfo & proberInnerCodeRelativeInfo, const string &sSec);
	// 解析畸变校正参数
	int iParseCorrrectionParam(stCorrectionParam & correctionParam, const string &sSec);
	// 解析行对齐算法参数
	int iParseLineAlignAlgParam(stLineAlignAlgParam & lineAlignAlgParam, const string &sSec);
	// 解析清晰对焦位置
	int iParseClearMotorPos(int & iPos, const string &sProberSN, const string &sSec);
public:
	// 设置设备描述信息
	int iSetDeviceDesc(const stDeviceDesc & deviceDesc, const string & sSec);
	// 设置设备记录信息
	int iSetDeviceRecordInfo(const stDeviceRecordInfo & deviceRecordInfo, const string & sSec);
	// 设置扫描类型信息
	int iSetScanType(int iScanDirectionType, const string & sSec);
	// 设置探头清晰对焦位置
	int iSetProberClearPos(const stProberClearMotorPosInfo & proberClearMotorPosInfo, const string & sSec);
	// 设置激光功率信息
	int iSetLaserPowerInfo(const stLaserPowerInfo & laserPowerInfo, const string & sSec);
	// 设置电机位置信息
	int iSetMotorPosInfo(const stMotorPosInfo & motor, const string & sSec);
	// 设置探头内部型号相关信息
	int iSetProberInnerCodeRelativeInfoDict(const map<string, int> &dictInnerCode2proberInnerCodeRelativeInfo, const string &sSec);
	// 设置光纤束相关信息
	int iSetFiberBundleTypeRelativeInfoDict(const map<string, stFiberBundleTypeRelativeInfo> &dictFiberBundleTypeRelativeInfo, const string & sSec);
	// 设置匹配的探头型号列表
	int iSetMatchedProberModelList(vector<string> & seqProberModelList, const string & sSec);
protected:
	// 设置探头内部型号相关信息
	int iSetProberInnerCodeRelativeInfo(int proberInnerCodeRelativeInfo, const string &sProberInnerCode, const string &sSec);
	// 设置光纤束相关信息
	int iSetFiberBundleTypeRelativeInfo(const stFiberBundleTypeRelativeInfo &fiberBundleTypeRelativeInfo, const string &sFiberBundleType, const string & sSec);
	// 设置畸变校正参数
	int iSetCorrrectionParam(const stCorrectionParam & correctionParam, const string &sProberInnerCode, const string &sSec);
	// 设置行对齐算法参数
	int iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam, const string &sProberInnerCode, const string &sSec);
	// 设置探头内部型号相关信息
	int iSetProberInnerCodeRelativeInfo(const stProberInnerCodeRelativeInfo & proberInnerCodeRelativeInfo, const string &sSec);
	// 设置畸变校正参数
	int iSetCorrrectionParam(const stCorrectionParam & correctionParam, const string &sSec);
	// 设置行对齐算法参数
	int iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam, const string &sSec);
	// 设置清晰对焦位置
	int iSetClearMotorPos(int & iPos, const string &sProberSN, const string &sSec);
protected:
	// 解析序列列表
	int iParseList(vector<string> &seqOptions, const string &sValue);
	// 列表转换从字符串转换为整形
	int iChgStr2Int(vector<int> & seqOptions, const vector<string> seqStrOptions);
	// 将列表项信息转换为列表字符串
	template <class T>
	string sChgOptions2StrList(vector<T> & seqOptions)
	{
		string sStrList;
		{
			ostringstream os;
			auto iter = seqOptions.begin();
			if (iter != seqOptions.end())
			{
				os << *iter;
				iter++;
			}
			for (; iter != seqOptions.end(); iter++)
			{
				os << "," << *iter;
			}
			sStrList = os.str();
		}
		return sStrList;
	}
protected:
	// 设备参数配置文件
	CConfigFile m_configFile;
};

DeviceParamIO.cpp

#include <stdlib.h>
#include "Log.h"
#include "DeviceParamIO.h"
#include "InnerDeviceKeyInfo.h"


	// 构造函数
CDeviceParamIO::CDeviceParamIO()
{
	return;
}

// 析构函数
CDeviceParamIO::~CDeviceParamIO()
{
	return;
}

// 初始化
int CDeviceParamIO::iInitialize(const string & sConfigFile)
{
	m_configFile.SetConfigFileName(sConfigFile);
	return m_configFile.iInitialize();
}


// 解析设备描述信息
int CDeviceParamIO::iParseDeviceDesc(stDeviceDesc & deviceDesc, const string & sSec)
{
	if (EXIT_FAILURE == m_configFile.iGetValue(deviceDesc.m_sDeviceModel, cnsDeviceModel, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsDeviceModel << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_configFile.iGetValue(deviceDesc.m_sDeviceCN, cnsDeviceCN, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsDeviceCN << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_configFile.iGetValue(deviceDesc.m_iMaxRunningTime, cnsMaxRunningTime, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsMaxRunningTime << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_configFile.iGetValue(deviceDesc.m_sProductionDate, cnsProductionDate, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsProductionDate << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_configFile.iGetValue(deviceDesc.m_iDeviceType, cnsDeviceType, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsDeviceType << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << "DeviceDesc:" << deviceDesc;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}

// 解析设备记录信息
int CDeviceParamIO::iParseDeviceRecordInfo(stDeviceRecordInfo & deviceRecordInfo, const string & sSec)
{
	if (EXIT_FAILURE == m_configFile.iGetValue(deviceRecordInfo.m_iDeviceBootTime, cnsDeviceBootTime, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsDeviceBootTime << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == m_configFile.iGetValue(deviceRecordInfo.m_iProberInsertedTime, cnsDeviceInsertedTime, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsDeviceInsertedTime << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 解析扫描类型信息
int CDeviceParamIO::iParseScanType(int iScanDirectionType, const string & sSec)
{
	if (EXIT_FAILURE == m_configFile.iGetValue(iScanDirectionType, cnsScanType, sSec))
	{
		ostringstream os;
		os << "failed to set [" << cnsScanType << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 解析探头清晰对焦位置
int CDeviceParamIO::iParseProberClearPos(stProberClearMotorPosInfo & proberClearMotorPosInfo, const string & sSec)
{
	string sProberCNList;
	if (EXIT_FAILURE == m_configFile.iGetValue(sProberCNList, cnsProberSNList, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsProberSNList << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	vector<string> seqOptions;
	if (EXIT_FAILURE == iParseList(seqOptions, sProberCNList))
	{
		ostringstream os;
		os << "failed to parse Options from [" << sProberCNList << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	for (auto e : seqOptions)
	{
		int iPos;
		if (EXIT_FAILURE == iParseClearMotorPos(iPos, e, sSec))
		{
			return EXIT_FAILURE;
		}
		proberClearMotorPosInfo.m_dictProberCN2MotorPos[e] = iPos;
	}
	{
		ostringstream os;
		os << "ProberClearMotorPosInfo:" << proberClearMotorPosInfo;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}

// 解析激光功率信息
int CDeviceParamIO::iParseLaserPowerInfo(stLaserPowerInfo & laserPowerInfo, const string & sSec)
{
	if (EXIT_FAILURE == m_configFile.iGetValue(laserPowerInfo.m_iLaserMaxPower, cnsLaserMaxPower, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsLaserMaxPower << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == m_configFile.iGetValue(laserPowerInfo.m_iLaserPowerPercent, cnsLaserPowerPercent, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsLaserPowerPercent << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == m_configFile.iGetValue(laserPowerInfo.m_iLaserPowerLowerLimit, cnsLaserPowerLowerLimit, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsLaserPowerLowerLimit << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == m_configFile.iGetValue(laserPowerInfo.m_iLaserPowerUpperLimit, cnsLaserPowerUpperLimit, sSec))
	{
		ostringstream os;
		os << "failed to parse [" << cnsLaserPowerUpperLimit << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	{
		ostringstream os;
		os << "LaserPowerInfo:" << laserPowerInfo;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}
// 设置光纤束相关信息
int CDeviceParamIO::iSetFiberBundleTypeRelativeInfo(const stFiberBundleTypeRelativeInfo &fiberBundleTypeRelativeInfo, const string &sFiberBundleType, const string & sSec)
{
	string sDeviceCNKey;
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enXMirrorOffsetType))
	{
		{
			ostringstream os;
			os << cnsProbeXMirrorOffset << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iProbeXMirrorOffset, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enXMirrorEvenOffsetType))
	{
		{
			ostringstream os;
			os << cnsProbeXMirrorEvenOffset << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iProbeXMirrorEvenOffset, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enXMirrorOddOffsetType))
	{
		{
			ostringstream os;
			os << cnsProbeXMirrorOddOffset << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iProbeXMirrorOddOffset, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enYMirrorOffsetType))
	{
		{
			ostringstream os;
			os << cnsYMirrorOffset << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iYMirrorOffset, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enXMirrorControlVoltageType))
	{
		{
			ostringstream os;
			os << cnsXMirrorControlVoltage << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iXMirrorControlVoltage, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enYMirrorControlVoltageType))
	{
		{
			ostringstream os;
			os << cnsYMirrorControlVoltage << "[" << sFiberBundleType << "]";
			sDeviceCNKey = os.str();
		}
		if (EXIT_FAILURE == m_configFile.iSetValue(fiberBundleTypeRelativeInfo.m_iYMirrorControlVoltage, sDeviceCNKey, sSec))
		{
			ostringstream os;
			os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enCorrectionParamType))
	{
		if (EXIT_FAILURE == iSetCorrrectionParam(fiberBundleTypeRelativeInfo.m_correctionParam, sFiberBundleType, sSec))
		{
			return EXIT_FAILURE;
		}
	}
	

	if (fiberBundleTypeRelativeInfo.m_dictParamStatus.at(enLineAlignAlgParamType))
	{
		if (EXIT_FAILURE == iSetLineAlignAlgParam(fiberBundleTypeRelativeInfo.m_lineAlignAlgParam, sFiberBundleType, sSec))
		{
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}

// 设置畸变校正参数
int CDeviceParamIO::iSetCorrrectionParam(const stCorrectionParam & correctionParam, const string &sProberInnerCode, const string &sSec)
{
	string sDeviceCNKey;
	{
		ostringstream os;
		os << cnsCorrectionEnable << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iCorrectionEnable, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsScanCenterCol << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iScanCenterCol, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsStretchCoef << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iStretchCoef, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsScanFrequency << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iScanFrequency, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsSampleFrequency << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iSampleFrequency, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 设置行对齐算法参数
int CDeviceParamIO::iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam, const string &sProberInnerCode, const string &sSec)
{
	string sDeviceCNKey;
	{
		ostringstream os;
		os << cnsLineAlignAlgEnable << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignAlgEnable, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsLineAlignOffset << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	{
		ostringstream os;
		os << cnsLineAlignInterval << "[" << sProberInnerCode << "]";
		sDeviceCNKey = os.str();
	}
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignInterval, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}


// 设置探头内部型号相关信息
int CDeviceParamIO::iSetProberInnerCodeRelativeInfo(const stProberInnerCodeRelativeInfo & proberInnerCodeRelativeInfo, const string &sSec)
{
	string sDeviceCNKey = cnsProbeXMirrorOffset;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iProbeXMirrorOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsProbeXMirrorEvenOffset;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iProbeXMirrorEvenOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsProbeXMirrorOddOffset;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iProbeXMirrorOddOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsYMirrorOffset;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iYMirrorOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsXMirrorControlVoltage;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iXMirrorControlVoltage, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsYMirrorControlVoltage;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_iYMirrorControlVoltage, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsPMTControlVoltage;
	if (EXIT_FAILURE == m_configFile.iSetValue(proberInnerCodeRelativeInfo.m_iPMTControlVoltage, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iSetCorrrectionParam(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_correctionParam, sSec))
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iSetLineAlignAlgParam(proberInnerCodeRelativeInfo.m_fiberBundleTypeRelativeInfo.m_lineAlignAlgParam, sSec))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 设置畸变校正参数
int CDeviceParamIO::iSetCorrrectionParam(const stCorrectionParam & correctionParam, const string &sSec)
{
	string sDeviceCNKey = cnsCorrectionEnable;
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iCorrectionEnable, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsScanCenterCol;
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iScanCenterCol, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsStretchCoef;
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iStretchCoef, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsScanFrequency;
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iScanFrequency, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsSampleFrequency;
	if (EXIT_FAILURE == m_configFile.iSetValue(correctionParam.m_iSampleFrequency, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 设置行对齐算法参数
int CDeviceParamIO::iSetLineAlignAlgParam(const stLineAlignAlgParam & lineAlignAlgParam, const string &sSec)
{
	string sDeviceCNKey = cnsLineAlignAlgEnable;
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignAlgEnable, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsLineAlignOffset;
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignOffset, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sDeviceCNKey = cnsLineAlignInterval;
	if (EXIT_FAILURE == m_configFile.iSetValue(lineAlignAlgParam.m_iLineAlignInterval, sDeviceCNKey, sSec))
	{
		ostringstream os;
		os << "failed to set [" << sDeviceCNKey << "," << sSec << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

InnerDeviceInfo.h

#pragma once
#include <string>
#include <map>
#include <sstream>
#include "UtilFun.h"

using namespace std;

// 默认设备型号
const string cnsDefaultDeviceModel = "CLE-1000";
// 默认设备序列号
const string cnsDefaultDeviceCN = "M171101S";
// 默认最大运行时间
const int cniDefaultMaxRunningTime = 14400;
// 默认设备生产日期
const string cnsDefaultProductionDate = "2023-05-26";
// 默认设备启动次数
const int cniDefaultDeviceBootTime = 0;
// 默认探头插入次数
const int cniDefaultProberInsertedTime = 0;
// 默认扫描类型
const int cniDefaultScanType = 1;
// 默认为真机类型,0:表示未知;1:表示真机;2:表示Parrot模拟机
const int cniDefaultDeviceType = 1;

// 设备描述
struct stDeviceDesc
{
	// 设备型号
	string m_sDeviceModel;
	// 设备序列号
	string m_sDeviceCN;
	// 最大运行时间
	int m_iMaxRunningTime;
	// 设备生产日期
	string m_sProductionDate;
	// 设备类型
	int m_iDeviceType;

	stDeviceDesc()
	{
		m_sDeviceModel = cnsDefaultDeviceModel;
		m_sDeviceCN = cnsDefaultDeviceCN;
		m_iMaxRunningTime = cniDefaultMaxRunningTime;
		m_sProductionDate = cnsDefaultProductionDate;
		m_iDeviceType = cniDefaultDeviceType;
		return;
	}

	stDeviceDesc(const stDeviceDesc & deviceDesc)
	{
		m_sDeviceModel = deviceDesc.m_sDeviceModel;
		m_sDeviceCN = deviceDesc.m_sDeviceCN;
		m_iMaxRunningTime = deviceDesc.m_iMaxRunningTime;
		m_sProductionDate = deviceDesc.m_sProductionDate;
		m_iDeviceType = deviceDesc.m_iDeviceType;
		return;
	}

	stDeviceDesc & operator = (const stDeviceDesc & deviceDesc)
	{
		m_sDeviceModel = deviceDesc.m_sDeviceModel;
		m_sDeviceCN = deviceDesc.m_sDeviceCN;
		m_iMaxRunningTime = deviceDesc.m_iMaxRunningTime;
		m_sProductionDate = deviceDesc.m_sProductionDate;
		m_iDeviceType = deviceDesc.m_iDeviceType;
		return *this;
	}

	friend ostream & operator << (ostream & os, const stDeviceDesc & deviceDesc)
	{
		os << "DeviceModel:" << deviceDesc.m_sDeviceModel << endl;
		os << "DeviceCN:" << deviceDesc.m_sDeviceCN << endl;
		os << "MaxRunningTime:" << deviceDesc.m_iMaxRunningTime << endl;
		os << "ProductionData:" << deviceDesc.m_sProductionDate << endl;
		os << "DeviceType:" << deviceDesc.m_iDeviceType << endl;
		return os;
	}
};

// 扫描类型
struct stScanType
{
	// 扫描类型
	int m_iScanDirectionType;
	
	stScanType()
	{
		m_iScanDirectionType = cniDefaultScanType;
		return;
	}

	stScanType(const stScanType &scanType)
	{
		m_iScanDirectionType = scanType.m_iScanDirectionType;
		return;
	}

	stScanType & operator = (const stScanType &scanType)
	{
		m_iScanDirectionType = scanType.m_iScanDirectionType;
		return *this;
	}

	friend ostream & operator << (ostream & os, const stScanType & scanType)
	{
		os << "ScanType:" << scanType.m_iScanDirectionType << endl;
		return os;
	}
};

// 设备记录信息
struct stDeviceRecordInfo
{
	// 设备启动次数
	int m_iDeviceBootTime;
	// 探头插入次数
	int m_iProberInsertedTime;
	
	stDeviceRecordInfo()
	{
		m_iDeviceBootTime = cniDefaultDeviceBootTime;
		m_iProberInsertedTime = cniDefaultProberInsertedTime;
		return;
	}

	stDeviceRecordInfo(const stDeviceRecordInfo &deviceRecordInfo)
	{
		m_iDeviceBootTime = deviceRecordInfo.m_iDeviceBootTime;
		m_iProberInsertedTime = deviceRecordInfo.m_iProberInsertedTime;
		return;
	}

	stDeviceRecordInfo & operator = (const stDeviceRecordInfo &deviceRecordInfo)
	{
		m_iDeviceBootTime = deviceRecordInfo.m_iDeviceBootTime;
		m_iProberInsertedTime = deviceRecordInfo.m_iProberInsertedTime;
		return *this;
	}

	friend ostream & operator << (ostream & os, const stDeviceRecordInfo &deviceRecordInfo)
	{
		os << "DeviceBootTime:" << deviceRecordInfo.m_iDeviceBootTime << endl;
		os << "ProberInertedTime:" << deviceRecordInfo.m_iProberInsertedTime << endl;
		return os;
	}
};


//默认激光最大功率
const int cniDefaultLaserMaxPower = 50000;
// 默认激光功率百分比
const int cniDefaultLaserPowerPercent = 50;
// 默认激光功率范围下限
const int cniDefaultLaserPowerLowerLimit = 25000;
// 默认激光功率范围上限
const int cniDefaultLaserPowerUpperLimit = 50000;
// 激光器功率信息
struct stLaserPowerInfo
{
	//默认激光最大功率
	int m_iLaserMaxPower;
	// 激光功率百分比
	int m_iLaserPowerPercent;
	// 激光功率范围下限
	int m_iLaserPowerLowerLimit;
	// 激光功率范围上限
	int m_iLaserPowerUpperLimit;


	stLaserPowerInfo()
	{
		m_iLaserMaxPower = cniDefaultLaserMaxPower;
		m_iLaserPowerPercent = cniDefaultLaserPowerPercent;
		m_iLaserPowerLowerLimit = cniDefaultLaserPowerLowerLimit;
		m_iLaserPowerUpperLimit = cniDefaultLaserPowerUpperLimit;
		return;
	}

	stLaserPowerInfo(const stLaserPowerInfo & laserPowerInfo)
	{
		m_iLaserMaxPower = laserPowerInfo.m_iLaserMaxPower;
		m_iLaserPowerPercent = laserPowerInfo.m_iLaserPowerPercent;
		m_iLaserPowerLowerLimit = laserPowerInfo.m_iLaserPowerLowerLimit;
		m_iLaserPowerUpperLimit = laserPowerInfo.m_iLaserPowerUpperLimit;
		return;
	}

	stLaserPowerInfo & operator = (const stLaserPowerInfo & laserPowerInfo)
	{
		m_iLaserMaxPower = laserPowerInfo.m_iLaserMaxPower;
		m_iLaserPowerPercent = laserPowerInfo.m_iLaserPowerPercent;
		m_iLaserPowerLowerLimit = laserPowerInfo.m_iLaserPowerLowerLimit;
		m_iLaserPowerUpperLimit = laserPowerInfo.m_iLaserPowerUpperLimit;
		return *this;
	}

	friend ostream & operator << (ostream & os, const stLaserPowerInfo & laserPowerInfo)
	{
		os << "LaserMaxPower:" << laserPowerInfo.m_iLaserMaxPower << endl;
		os << "LaserPowerPercent:" << laserPowerInfo.m_iLaserPowerPercent << endl;
		os << "LaserPowerLowerLimit:" << laserPowerInfo.m_iLaserPowerLowerLimit << endl;
		os << "LaserPowerUpperLimit:" << laserPowerInfo.m_iLaserPowerUpperLimit << endl;
		return os;
	}
};

// 默认畸变校正参数使能信号
const int cniDefaultCorrectionEnable = 1;
// 默认扫描中心列
const int cniDefaultScanCenterCol = 2048;
// 横向伸缩系数
const int cniDefaultStretchCoef = 250;
// 快镜扫描频率,单位为Hz
const int cniDefaultScanFrequency = 3938;
// AD采样频率,单位为Hz
const int cniDefaultSampleFrequency = 40000000;

cmakeList.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
PROJECT(Tremolite)
 
#指定为交叉编译环境
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)

#编译器选项
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/)
add_definitions(-std=c++11)

set(CMAKE_CXX_FLAGS "-fPIC")
set(CMAKE_C_FLAGS "-fPIC")
SET(CMAKE_CXX_FLAGS_RELEASE, "")
SET(CMAKE_EXE_LINKER_FLAGS "")
SET(CMAKE_C_FLAGS_RELEASE "")

#绕过检查
SET(CMAKE_C_COMPILER_WORKS TURE)
SET(CMAKE_CXX_COMPILER_WORKS TURE)
 
#指定编译链
SET(CMAKE_C_COMPILER "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-gcc")
SET(CMAKE_CXX_COMPILER "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-g++")
SET(CMAKE_ASM_COMPILER "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-as")
SET(CMAKE_AR "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-ar")
SET(CMAKE_OBJCOPY "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-objcopy")
SET(CMAKE_OBJDUMP "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-objdump")

#交叉编译器头文件
SET(COMPILER_INC "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\arm-linux-gnueabihf\\libc\\usr\\include")
SET(COMPILER_CXX_INC "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\arm-linux-gnueabihf\\include\\c++\\6.2.1")
SET(COMPILER_CXX_INC ${COMPILER_CXX_INC} "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\arm-linux-gnueabihf\\include\\c++\\6.2.1\\arm-linux-gnueabihf")
#thrift路径
SET(THRIFT_PATH ${PROJECT_SOURCE_DIR}/binary/thrift-0.17.0)
#libZMQ路径
SET(LIBZMQ_PATH ${PROJECT_SOURCE_DIR}/binary/libzmq-4.3.4)
#boost路径
SET(BOOST_PATH ${PROJECT_SOURCE_DIR}/binary/boost_1_64_0)
#openssl路径
SET(OPENSSL_PATH ${PROJECT_SOURCE_DIR}/binary/openssl-1.1.0l)
#thift库
SET(THRIFT_LIB thrift)
#libzmq库
SET(LIBZMQ_LIB zmq)
#openssl库
SET(LIBOPENSSL_LIB crypto ssl)

#设置头文件
include_directories(. ${THRIFT_PATH}/include ${LIBZMQ_PATH}/include ${BOOST_PATH}/include ${OPENSSL_PATH}/include ${COMPILER_INC} ${COMPILER_CXX_INC} )

#配置链接指令
link_directories(${THRIFT_PATH}/lib ${LIBZMQ_PATH}/lib)
 
#添加子模块
#ADD_SUBDIRECTORY(./CMSIS)
#ADD_SUBDIRECTORY(./HTSources)
add_definitions(-DZMQ_HAVE_SO_KEEPALIVE -DZMQ_HAVE_TCP_KEEPCNT -DZMQ_HAVE_TCP_KEEPIDLE -DZMQ_HAVE_TCP_KEEPINTVL)
 
#添加源文件
AUX_SOURCE_DIRECTORY(. MAIN_SRCS)
AUX_SOURCE_DIRECTORY(CommInt/gen-cpp THRIFT_INT)
 
#编译主目录的文件并指定可执行文件
ADD_EXECUTABLE(${PROJECT_NAME}.elf ${MAIN_SRCS} ${THRIFT_INT})
 
#链接静态库和可执行文件
TARGET_LINK_LIBRARIES(${PROJECT_NAME}.elf ${THRIFT_LIB} ${LIBZMQ_LIB} -lpthread -ldl)
 
 
#生成.bin和.hex
#SET(ELF_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf)
#SET(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
#SET(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
 
#SET(BIN_OPTION "-O binary")
#SET(HEX_OPTION "-O ihex")
 
#ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME}.elf POST_BUILD
#    COMMAND ${CMAKE_OBJCOPY} -Oihex ${ELF_FILE} ${HEX_FILE}
#    COMMAND ${CMAKE_OBJCOPY} -Obinary ${ELF_FILE} ${BIN_FILE}
#)

{
  "configurations": [
    {
      "name": "arm",
      "generator": "Ninja",
      "configurationType": "Release",
      "inheritEnvironments": [
        "gcc-arm-linux-gnueabi"
      ],
      "buildRoot": "D:\\CornerStone_svn\\Tremolite_c\\build\\${name}",
      "installRoot": "D:\\CornerStone_svn\\Tremolite_c\\install\\${name}",
      "cmakeCommandArgs": "",
      "buildCommandArgs": "",
      "ctestCommandArgs": "",
      "intelliSenseMode": "linux-gcc-arm",
      "variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-gcc.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "D:\\vidado2017.4\\Xilinx\\SDK\\2017.4\\gnu\\aarch32\\nt\\gcc-arm-linux-gnueabi\\bin\\arm-linux-gnueabihf-g++.exe"
        },
        {
          "name": "CMAKE_C_FLAGS",
          "value": ""
        },
        {
          "name": "CMAKE_CXX_FLAGS",
          "value": ""
        },
        {
          "name": "CMAKE_CXX_STANDARD",
          "value": ""
        },
        {
          "name": "CMAKE_SYSTEM_NAME",
          "value": "Linux"
        },
        {
          "name": "CMAKE_SYSTEM_PROCESSOR",
          "value": "arm"
        }
      ]
    }
  ]
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值