激光器自适应模块化

LaserCtrl.h

#pragma once
#include "ThreadProc.h"
#include "LaserUartCtrl.h"
#include "InnerDeviceInfo.h"
#include "LaserCommProc.h"
class CDeviceComCtrl;
class CLaserCtrl:public CThreadProc
{
public:
	// 构造函数
	CLaserCtrl(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl, CDeviceComCtrl * pDeviceComCtrl);
	// 析构函数
	~CLaserCtrl() noexcept;
	// 初始化
	int iInitialize();
	// 服务
	virtual int src(int id) override;
public:
	// 关闭激光机
	int iTurnOffLaser();
	// 打开激光器
	int iTurnOnLaser();
	// 设置激光功率
	int iSetLaserPower(int iLaserPower);
	// 获取激光器信息
	int iGetLaserInfo(stLaserInfo & laserInfo);
	// 获取激光器信息
	int  iGetLaserPower(int &iPower);
protected:
	// 激光器检查线程
	void LaserCheckThread();
	// 激光器检查函数
	void CheckLaser();
	// 判断在工作温度方位
	bool bSafeTemp(const string &sLaserType, int iTemp);
private:
	// 激光器通信处理
	CLaserCommProc  * m_laserCommProc;
	// 设备器件控制
	CDeviceComCtrl * m_pDeviceComCtrl;
	// 温度过高的检测计数
	int m_iTempHightCounter;
	// 激光器检查失败计数
	int m_iCheckFailedCounter;
	// 激光器出光不处于扫描状态计数
	int m_iNoScanLaserOnCounter;

	stUartConfigInfo  m_uartConfigInfo;
	stUartConfigInfo  m_uartConfigInfo1;
	//stUartConfigInfo uartConfigInfo;
	int iSendEMIOCode;
	int iRecvEMIOcode;
	CEMIOCtrl * pEMIOCtrl;
};

LaserCtrl.cpp

#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<iomanip>
#include "Log.h"
#include "DeviceComCtrl.h"
#include "LaserCtrl.h"
#include "DeviceParamMng.h"
#include "DeviceStatusMng.h"
#include "SettingParamMng.h"
#include "LaserCommProcBios488.h"


// 连续温度超过阈值次数停止采集
const int cniStopCaptureMaxHighTempTime = 3;
// 连续检测激光器失败次数超过限制更新状态
const int cniUpdateStatusMaxFailedTime = 3;
// 连续检测不处于扫描状态且激光器出光次数停止出光
const int cniTurnOffLaserNoScanMaxTime = 3;

const int cniBiosLaserSpeed = 115200;

// 构造函数
CLaserCtrl::CLaserCtrl(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl, CDeviceComCtrl * pDeviceComCtrl)
	:CThreadProc(1), m_uartConfigInfo(uartConfigInfo), iSendEMIOCode(iSendEMIOCode), iRecvEMIOcode(iRecvEMIOcode), pEMIOCtrl(pEMIOCtrl)
{
	m_pDeviceComCtrl = pDeviceComCtrl;
	m_iTempHightCounter = 0;
	m_iCheckFailedCounter = 0;
	m_iNoScanLaserOnCounter = 0;

	m_uartConfigInfo1.m_sUartDriverFile = m_uartConfigInfo.m_sUartDriverFile;  //国产激光器设备信息传入参数
	m_uartConfigInfo1.m_iUartSpeed = cniBiosLaserSpeed;
	return;
}

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

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

// 初始化
int CLaserCtrl::iInitialize() 
{
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "initializing Laser begin" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	
	m_laserCommProc = new CLaserCommProcBios488(m_uartConfigInfo1, iSendEMIOCode, iRecvEMIOcode, pEMIOCtrl);
	// 初始化串口
	if (EXIT_FAILURE == m_laserCommProc->iInitialize())
	{
		if (nullptr != m_laserCommProc)
		{
			delete m_laserCommProc;
			m_laserCommProc = nullptr;
		}
		m_laserCommProc = new CLaserCommProc(m_uartConfigInfo, iSendEMIOCode, iRecvEMIOcode, pEMIOCtrl);
		// 初始化串口
		if (EXIT_FAILURE == m_laserCommProc->iInitialize())
		{
			ostringstream os;
			os << "iInitialize DDL Fail" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	
	// 获取错误码
	int iErrCode = 0;
	if (EXIT_FAILURE == m_laserCommProc->iGetLaserStatusCode(iErrCode))
	{
		ostringstream os;
		os << "failed to get ErrCode" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "Laser Err Code after LASER_RECovery:0x" << hex << setfill('0') << setw(8) << iErrCode << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 设置激光功率
	stLaserInfo laserInfo;
	laserInfo.m_laserPowerInfo = CDeviceParamMng::GetInstance()->GetLaserPowerInfo();
	int iLaserPower = laserInfo.m_laserPowerInfo.m_iLaserMaxPower * laserInfo.m_laserPowerInfo.m_iLaserPowerPercent / 100;
	if (EXIT_FAILURE == iSetLaserPower(iLaserPower))
	{
		ostringstream os;
		os << "failed to set laserPower" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		// return EXIT_FAILURE;
	}


	// 检查激光功率状态
	stStateMsg stateMsg;
	stateMsg.m_enComType = enDeviceComType_NoCom;
	if (EXIT_FAILURE == m_laserCommProc->iCheckLaserErrCode(iErrCode))
	{
		stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
		stateMsg.m_deviceErrorCode.m_iCode = DevError_INIT_LASER_ERR;
		ostringstream os;
		os << "failed to check laser state, ErrCode:" << iErrCode << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		// return EXIT_FAILURE;
	}
	else
	{
		stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
		stateMsg.m_deviceErrorCode.m_iCode = 0;
		ostringstream os;
		os << "succeed to initialize, ErrCode:" << iErrCode << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 读取激光器信息
	int iPower;
	if (EXIT_FAILURE == m_laserCommProc->iGetLaserInfo(iPower, laserInfo))
	{
		stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
		stateMsg.m_deviceErrorCode.m_iCode = DevError_INIT_LASER_ERR;
		stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperAnd;
		stateMsg.m_deviceStateCode.m_iCode = ~STATE_INIT_LASER;
		ostringstream os;
		os << "failed to get laserInfo" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	else
	{
		stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperOr;
		stateMsg.m_deviceStateCode.m_iCode = STATE_INIT_LASER;
	}

	CDeviceStatusMng::GetInstance()->iSetLaserInfo(laserInfo);
	CSettingParamMng::GetInstance()->iSetLaserMaxPower(laserInfo.m_laserPowerInfo.m_iLaserMaxPower);
	CSettingParamMng::GetInstance()->iSetLaserPowerPercent(laserInfo.m_laserPowerInfo.m_iLaserPowerPercent);
	CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);

	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "initializing Laser succeed" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	return open();
}

// 关闭激光机
int CLaserCtrl::iTurnOffLaser()
{
	return m_laserCommProc->iTurnOffLaser();
}
// 打开激光器
int CLaserCtrl::iTurnOnLaser() 
{
	return m_laserCommProc->iTurnOnLaser();
}

// 设置激光功率
int CLaserCtrl::iSetLaserPower(int iLaserPower)
{
	return m_laserCommProc->iSetLaserPower(iLaserPower);
}

// 获取激光器信息
int CLaserCtrl::iGetLaserInfo(stLaserInfo & laserInfo)
{
	int iPower;
	return m_laserCommProc->iGetLaserInfo(iPower, laserInfo);
}

// 获取激光器信息
int  CLaserCtrl::iGetLaserPower(int &iPower)
{
	return m_laserCommProc->iGetLaserPower(iPower);
}


// 激光器检查线程
void CLaserCtrl::LaserCheckThread() 
{
	bool bExitFlag = bGetExitFlag();
	while (!bExitFlag)
	{
		CheckLaser();
		sleep(3);
		bExitFlag = bGetExitFlag();
	}
	return;
}


// 激光器检查函数
void CLaserCtrl::CheckLaser()
{
	int iErrCode;
	int iRet = m_laserCommProc->iCheckLaserErrCode(iErrCode);
	if (EXIT_FAILURE == iRet)
	{
		m_iCheckFailedCounter++;
	}
	else
	{
		m_iCheckFailedCounter = 0;
	}

	stStateMsg stateMsg;
	stateMsg.m_enComType = enDeviceComType_Laser;
	if (EXIT_FAILURE == iRet && m_iCheckFailedCounter >= cniUpdateStatusMaxFailedTime)
	{
		stateMsg.m_deviceErrorCode.m_iCode = DevError_LASER_UART_ERR;
		stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
		stateMsg.m_deviceStateCode.m_iCode = STATE_SYS_ERR;
		stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperOr;
		CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
		return;
	}
	else if (EXIT_FAILURE == iRet)
	{
		return;
	}
	else
	{
		stateMsg.m_deviceStateCode.m_iCode = 0xffffffff;
		stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperAnd;
		stateMsg.m_deviceErrorCode.m_iCode = ~DevError_LASER_UART_ERR;
		stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperAnd;
		m_laserCommProc->iGetLaserStatusCode(stateMsg.m_comStateCode.m_iCode); 
		stateMsg.m_comStateCode.m_enCodeOperType = enCodeOperCopy;
		stateMsg.m_comErrorcode.m_iCode = iErrCode;
		stateMsg.m_comErrorcode.m_enCodeOperType = enCodeOperCopy;
		CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
		if (iErrCode != 0)
		{
			stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
			stateMsg.m_deviceErrorCode.m_iCode = DevError_LASER_DEVICE_ERR;
		}
		else
		{
			stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperAnd;
			stateMsg.m_deviceErrorCode.m_iCode = ~DevError_LASER_DEVICE_ERR;
		}
		CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
	}

	// 获取激光器温度电压信息
	stLaserInfo laserInfo = CDeviceStatusMng::GetInstance()->GetLaserInfo();
	int iPower = 0;
	int iPowerPercent = 0;
	if (EXIT_SUCCESS == m_laserCommProc->iGetLaserPower(iPower))
	{
		int iMaxLaserPower = CSettingParamMng::GetInstance()->iGetLaserMaxPower();
		iPowerPercent = iPower * 100 / iMaxLaserPower;
		iPowerPercent = iPowerPercent > 100 ? 100 : iPowerPercent;
		laserInfo.m_laserPowerInfo.m_iLaserPowerPercent = iPowerPercent;
	}
	m_laserCommProc->iGetLaserTempInfo(laserInfo.m_fCurrent, laserInfo.m_fBasePlateTemp, laserInfo.m_fDiodeTemp);
	CDeviceStatusMng::GetInstance()->iSetLaserInfo(laserInfo);


	// 获取激光器型号
	if (laserInfo.m_sType.empty())
	{
		m_laserCommProc->iGetLaserType(laserInfo.m_sType);
	}
	if (!laserInfo.m_sType.empty())
	{
		if (bSafeTemp(laserInfo.m_sType, laserInfo.m_fBasePlateTemp))
		{
			stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperAnd;
			stateMsg.m_deviceStateCode.m_iCode = 0xffffffff;
			stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperAnd;
			stateMsg.m_deviceErrorCode.m_iCode = ~DevErrorCode_LaserHighTemp_ERR;
			m_iTempHightCounter = 0;
		}
		else
		{
			stateMsg.m_deviceStateCode.m_enCodeOperType = enCodeOperOr;
			stateMsg.m_deviceStateCode.m_iCode = STATE_SYS_ERR;
			stateMsg.m_deviceErrorCode.m_enCodeOperType = enCodeOperOr;
			stateMsg.m_deviceErrorCode.m_iCode = DevErrorCode_LaserHighTemp_ERR;

			if (CLog::GetInstance()->bLogOK(Log_Info))
			{
				ostringstream os;
				os << "Laser Temputer overrun ,laser base tepmuter=" << laserInfo.m_fBasePlateTemp << endl;
				CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
			}
			m_iTempHightCounter++;
			if (m_iTempHightCounter >= cniStopCaptureMaxHighTempTime)
			{
				m_pDeviceComCtrl->iStopCapture();
			}	
		}
		CDeviceStatusMng::GetInstance()->SendStateMsg(stateMsg);
	}

	// 处于扫描状态,激光器未出光
	bool bScanFlag = CDeviceStatusMng::GetInstance()->bScanFlag();
	if (bScanFlag && (!(stateMsg.m_comStateCode.m_iCode & 0x00000102)))  //激光器状态无出光标志
	{
		if (CLog::GetInstance()->bLogOK(Log_Info))
		{
			ostringstream os;
			os << "Start Scan,But Laser Emission error LaserStatusCode=" << hex << stateMsg.m_comStateCode.m_iCode << ", LaserErrorCode=" << stateMsg.m_comErrorcode.m_iCode << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		}

		usleep(1000000);   //延时1S再打开一次激光器
		m_laserCommProc->iTurnOnLaser();   //再次发送一次激光器出光命令
		m_iNoScanLaserOnCounter = 0;
	}
	else if (bScanFlag)
	{
		m_iNoScanLaserOnCounter = 0;
	}
	else
	{
		if (!bScanFlag && ((stateMsg.m_comStateCode.m_iCode & 0x00000002)!=0)) // 不处于扫描状态且出光
		{
			m_iNoScanLaserOnCounter++;
		}

		if (cniTurnOffLaserNoScanMaxTime == m_iNoScanLaserOnCounter)
		{
			m_laserCommProc->iTurnOffLaser();
		}
	}
	return;
}


// 判断在工作温度方位
bool CLaserCtrl::bSafeTemp(const string &sLaserType, int iTemp)
{
	if ("OPSL" == sLaserType)
	{
		return (iTemp < BASE_PALTE_TEMP_THRESH_LS);
	}
	else if ("DDL" == sLaserType)
	{
		return (iTemp < BASE_PALTE_TEMP_THRESH_LX);
	}
	else
	{
		return (iTemp < BASE_PALTE_TEMP_THRESH_UNKNOWN_TYPE);
	}
}

LaserCommProc.h

#pragma once
#include <mutex>
#include "LaserUartCtrl.h"
#include "InnerDeviceInfo.h"
#include "ccb.h"
using namespace std;
class CLaserCommProc
{
public:
	// 构造函数
	CLaserCommProc(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl);
	// 析构函数
	~CLaserCommProc();
	// 初始化
	virtual int iInitialize();
public:
	// 关闭激光机
	virtual int iTurnOffLaser();
	// 打开激光器
	virtual int iTurnOnLaser();
	// 设置激光功率
	virtual int iSetLaserPower(int iLaserPower);
	// 恢复激光器
	virtual int iRecoverLaser();
	// 关闭CDRH
	virtual int iTurnOffCDRH(int & iCode);
	// 激光器预热
	virtual int iSetLaserDiodeWarmOn();
	// 获取激光器状态码
	virtual int iGetLaserStatusCode(int &iStatusCode);
	// 获取激光器错误码
	virtual int iGetLaserErrCode(int & iErrCode);
	// 获取激光器类型
	virtual int iGetLaserType(string & sLaserType);
	// 获取激光器基础信息
	virtual int iGetLaserBaseInfo(string & sModel, string & sPN, string & sSN);
	// 获取激光器波长
	virtual int iGetLaserWaveLength(int &iWaveLength);
	// 获取激光器温度信息
	virtual int iGetLaserTempInfo(float &fCurrent, float & fTemp, float & fDiode);
	// 获取激光器信息
	virtual int iGetLaserInfo(int & iPower, stLaserInfo & laserInfo);
	// 检查激光器错误码
	virtual int iCheckLaserErrCode(int &iErrCode);
	// 获取激光功率
	virtual int iGetLaserPower(int & iPower);
public:
	// 重置总线
	int iResetBus();
	// 分配地址
	int iAssignAddr();
protected:
	// 命令执行
	int iExeCmd(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len, char *rebuf);
	// 执行命令
	int iExeCmd(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len);
	// 发送消息
	int iSendMsg(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len);
	// 接收激光器数据
	int iRecvData(char * sData);
	// 打包数据
	int iPackageFrameMsg(CCBMsgHdr_t *hdr, const UINT8 *src,
		UINT32 srclen,
		UINT8 *dest,
		UINT32 destlen);
	// 命令执行
	virtual int iExeCmd(char *msg, unsigned len, char *rebuf);
	// 解析接收消息
	int iParseFrameMsg(char * sData, const UINT8 *src, UINT32 srclen);
private:
	// 激光器串口控制
	CLaserUartCtrl m_laserUartCtrl;
	// 操作互斥锁
	mutex m_mtxLaserCtrl;
};

LaserCommProc.cpp

#include <iomanip>
#include <unistd.h>
#include <stdlib.h>
#include "Log.h"
#include "LaserCommProc.h"
#include "UtilFun.h"
#include "obis_cmd.h"
#include "Log.h"
#include "DeviceComCtrl.h"
#include "LaserCtrl.h"
#include "DeviceParamMng.h"
#include "DeviceStatusMng.h"
#include "SettingParamMng.h"

CCBMsgHdr_t AssignMsgHdr =
{
	CCB_CONTROLLER_ADDR,  //source address
	CCB_DEFAULT_DEV_ADDR,   //destination address
	CCB_FLAG_BUSMGMT,     //flags
	0,                  //tags
	0
}; //len optional

CCBMsgHdr_t SendCMDLaserOnHdr =
{
	CCB_CONTROLLER_ADDR,  //source address
	CCB_LOWEST_DEV_ADDR, // CCB_BROADCAST_ADDR  CCB_LOWEST_DEV_ADDR,  //destination address
	0,     //flags
	0,                  //optional tags
	0
}; //optional len

// 构造函数
CLaserCommProc::CLaserCommProc(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl)
	:m_laserUartCtrl(uartConfigInfo, iSendEMIOCode, iRecvEMIOcode, pEMIOCtrl)
{
	return;
}

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


// 初始化
int CLaserCommProc::iInitialize()
{	
	int LaserType = 0;
	if (EXIT_FAILURE == CDeviceComCtrl::GetInstance()->iSetLaserTypes(LaserType)) //通过设计FPGA管脚设置激光器类型,设计为参数0时为旧激光器IBOS,设置参数为1时为新激光器(精英光电)
	{
		ostringstream os;
		os << "failed to initialize SetLaserTypes" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	usleep(1000);

	// 初始化串口
	if (EXIT_FAILURE == m_laserUartCtrl.iInitialize())
	{
		ostringstream os;
		os << "failed to initialize LaserUart" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}


	// 分配地址
	if (EXIT_FAILURE == iAssignAddr())
	{
		ostringstream os;
		os << "failed to assign address" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	usleep(3000000);


	// 获取错误码
	int iErrCode = 0;
	if (EXIT_FAILURE == iGetLaserStatusCode(iErrCode))
	{
		ostringstream os;
		os << "failed to get ErrCode" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "Laser Err Code:0x" << hex << setfill('0') << setw(8) << iErrCode << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}


	// 恢复出厂设置
	if (EXIT_FAILURE == iRecoverLaser())
	{
		ostringstream os;
		os << "failed to recover factory-settting" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	usleep(4000000);

	// 分配地址
	if (EXIT_FAILURE == iAssignAddr())
	{
		ostringstream os;
		os << "failed to assign address" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	usleep(3000000);

	// 获取错误码
	iErrCode = 0;
	if (EXIT_FAILURE == iGetLaserStatusCode(iErrCode))
	{
		ostringstream os;
		os << "failed to get ErrCode" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "Laser Err Code after LASER_RECovery:0x" << hex << setfill('0') << setw(8) << iErrCode << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}

	// 关闭CDRH
	int iCode;
	if (EXIT_FAILURE == iTurnOffCDRH(iCode))
	{
		ostringstream os;
		os << "failed to turn off CDRH" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		//return EXIT_FAILURE;
	}
	usleep(2000);

	// 设置激光器预热
	if (EXIT_FAILURE == iSetLaserDiodeWarmOn())
	{
		ostringstream os;
		os << "failed to set LaserDiodeWarmOn" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		// return EXIT_FAILURE;
	}
	usleep(2000);

	return EXIT_SUCCESS;
}

// 关闭激光机
int CLaserCommProc::iTurnOffLaser()
{
	char reply[256] = { 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_SET_OFF_STR, //关闭激光器,获得应答值
		LASER_SET_OFF_STR_LEN, reply))
	{
		ostringstream os;
		os << "failed to turn off Laser" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "succeed to turn off Laser" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}

// 打开激光器
int CLaserCommProc::iTurnOnLaser()
{
	char reply[256] = { 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LX_CMD_LASER_ON, //打开激光器,获得应答值
		LX_CMD_LASER_ON_LEN, reply))
	{
		ostringstream os;
		os << "failed to turn on Laser" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}

	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		unsigned int ret = 0;
		sscanf(reply, "%08x\r\n", &ret);
		ostringstream os;
		os << "succeed to turn on Laser, RetCode:" << ret << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}

// 设置激光功率
int CLaserCommProc::iSetLaserPower(int iLaserPower)
{
	char cmd_buf[256] = { 0 };
	char reply[256] = { 0 };
	sprintf(cmd_buf, LASER_SET_POWER_STR, iLaserPower);

	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)cmd_buf,        //设置激光功率
		strlen(cmd_buf) + 1, reply))
	{
		ostringstream os;
		os << "failed to set power[" << iLaserPower << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	usleep(1000);
	if (CLog::GetInstance()->bLogOK(Log_Info))
	{
		ostringstream os;
		os << "succeed to set power[" << iLaserPower << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	return EXIT_SUCCESS;
}

// 恢复激光器
int CLaserCommProc::iRecoverLaser()
{
	char buffer[256] = {0};
	return iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_RECovery_SET_STR,
		LASER_RECovery_STR_LEN);
}

// 关闭CDRH
int CLaserCommProc::iTurnOffCDRH(int & iCode)
{
	char buffer[256] = { 0 };
	int iRet;

	//特殊操作,解除CDRH延时,关闭
	iRet = iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_SET_CDRH_OFF_STR,
		LASER_SET_CDRH_OFF_STR_LEN, buffer);
	sscanf(buffer, "%xC\r\n", &iCode);
	return iRet;
}
// 激光器预热
int CLaserCommProc::iSetLaserDiodeWarmOn()
{
	char buffer[256] = { 0 };
	int iRet;

	iRet = iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_SET_WARM_ON_STR, //自测试 获得系统错误代码,无错误,返回0,如果自测试没有执行,返回FF
		LASER_SET_WARM_ON_STR_LEN, buffer);
	return iRet;
}
// 获取激光器状态码
int CLaserCommProc::iGetLaserStatusCode(int &iStatusCode)
{
	char reply[256] = { 0 };

	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_STATUS_CODE_STR,
		LASER_STATUS_CODE_STR_LEN, reply))
	{
		ostringstream os;
		os << "failed to get laserStatusCode" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	string sValue = string(reply);
	size_t nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		string sStrValue = sValue.substr(0, nPos);
		if (CUtilFun::bIsHex(sStrValue))
		{
			iStatusCode = stoi(sStrValue, nullptr, 16);
		}
		else
		{
			ostringstream os;
			os << "Str[" << sStrValue << "] not digit";
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}
// 获取激光器错误码
int CLaserCommProc::iGetLaserErrCode(int & iErrCode)
{
	unsigned int ret = 0;
	char reply[256] = { 0, 0, 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_FAULT_CODE_STR,
		LASER_FAULT_CODE_STR_LEN, reply))
	{
		return EXIT_FAILURE;
	}

	string sValue = string(reply);
	size_t nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		string sStrValue = sValue.substr(0, nPos);
		if (CUtilFun::bIsHex(sStrValue))
		{
			iErrCode = stoi(sStrValue, nullptr, 16);
		}
		else
		{
			ostringstream os;
			os << "Str[" << sStrValue << "] not digit";
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}
// 获取激光器类型
int CLaserCommProc::iGetLaserType(string & sLaserType)
{
	char reply[256] = { 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_MODEL_TYPE, //获得设备型号
		LASER_MODEL_TYPE_LEN, reply))
	{
		return EXIT_FAILURE;
	}
	string sValue = string(reply);
	size_t nPos = sValue.find_first_of("\r\n");
	if (string::npos != nPos)
	{
		sLaserType = sValue.substr(0, nPos);
	}
	else
	{
		sLaserType = sValue;
	}
	return EXIT_SUCCESS;
}
// 获取激光器基础信息
int CLaserCommProc::iGetLaserBaseInfo(string & sModel, string & sPN, string & sSN)
{
	char buffer[256] = { 0 };
	uint8_t Len = 0;
	char LaserTypeBuf[32] = { 0 };

	// 获取型号 
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_MODEL_STR, //获得Model
		LASER_MODEL_STR_LEN, buffer))
	{
		return EXIT_FAILURE;
	}
	string sValue = string(buffer);
	size_t nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		sModel = sValue.substr(0, nPos);
	}

	// 获取PN
	memset(buffer, 0, 256);
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_PN_STR, //获得PN
		LASER_PN_STR_LEN, buffer))
	{
		return EXIT_FAILURE;
	}
	sValue = string(buffer);
	nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		sPN = sValue.substr(0, nPos);
	}

	// 获取SN
	usleep(1000);
	memset(buffer, 0, 256);
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_SN_STR, //获得SN
		LASER_SN_STR_LEN, buffer))
	{
		return EXIT_FAILURE;
	}
	sValue = string(buffer);
	nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		sSN = sValue.substr(0, nPos);
	}
	usleep(1000);
	return EXIT_SUCCESS;
}


// 获取激光功率
int CLaserCommProc::iGetLaserPower(int & iPower)
{
	char reply[256] = { 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_GET_POWER_STR,
		LASER_GET_POWER_STR_LEN, reply))
	{
		return EXIT_FAILURE;
	}
	sscanf(reply, "0.%05d\r\n", &iPower);
	iPower = iPower * 10;
	return EXIT_SUCCESS;
}

// 获取激光器波长
int CLaserCommProc::iGetLaserWaveLength(int &iWaveLength)
{
	unsigned int ret = 0;
	char reply[256] = { 0 };
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_WAVE_LENGTH_STR,
		LASER_WAVE_LENGTH_STR_LEN, reply))
	{
		return EXIT_FAILURE;
	}

	//解析返回值
	string sValue = string(reply);
	size_t nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		string sStrValue = sValue.substr(0, nPos);
		if (CUtilFun::bIsDigit(sStrValue))
		{
			iWaveLength = stoi(sStrValue);
		}
		else
		{
			ostringstream os;
			os << "Str[" << sStrValue << "] not digit";
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
			return EXIT_FAILURE;
		}
	}
	return EXIT_SUCCESS;
}
// 获取激光器温度信息
int CLaserCommProc::iGetLaserTempInfo(float &fCurrent, float & fTemp, float & fDiode)
{
	char buffer[256] = { 0 };
	// 获取电流
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_POW_CURR_STR,
		LASER_POW_CURR_STR_LEN, buffer))
	{
		return EXIT_FAILURE;
	}
	string sValue = string(buffer);
	size_t nPos = sValue.find_first_of("\r\n");
	if (nPos != string::npos)
	{
		fCurrent = stof(sValue.substr(0, nPos + 1));
	}


	// 获取温度
	memset(buffer, 0, 256);
	if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_TEMP_BASE_STR,
		LASER_TEMP_BASE_STR_LEN, buffer))
	{
		return EXIT_FAILURE;
	}
	sValue = string(buffer);
	nPos = sValue.find_last_not_of("C\r\n");
	if (nPos != string::npos)
	{
		fTemp = stof(sValue.substr(0, nPos + 1));
	}

	
	// 获取二极管温度
	string sLaserType;
	if (EXIT_FAILURE == iGetLaserType(sLaserType))// 获取类型
	{
		return EXIT_FAILURE;
	}
	if ("DDL" == sLaserType)
	{
		memset(buffer, 0, 256);
		if (EXIT_FAILURE == iExeCmd(&SendCMDLaserOnHdr, (UINT8 *)LASER_TEMP_DIODE_STR,
			LASER_TEMP_DIODE_STR_LEN, buffer))
		{
			return EXIT_FAILURE;
		}
		sValue = string(buffer);
		nPos = sValue.find_last_not_of("C\r\n");
		if (nPos != string::npos)
		{
			fDiode = stof(sValue.substr(0, nPos + 1));
		}
	}
	else
	{
		fDiode = 0.0;
	}
	usleep(1000);
	return EXIT_SUCCESS;
}
// 获取激光器信息
int CLaserCommProc::iGetLaserInfo(int & iPower, stLaserInfo & laserInfo)
{
	if (EXIT_FAILURE == iGetLaserBaseInfo(laserInfo.m_sModel, laserInfo.m_sPN, laserInfo.m_sSN))
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iGetLaserTempInfo(laserInfo.m_fCurrent, laserInfo.m_fBasePlateTemp, laserInfo.m_fDiodeTemp))
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iGetLaserPower(iPower))
	{
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == iGetLaserWaveLength(laserInfo.m_iWaveLength))
	{
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == iGetLaserType(laserInfo.m_sType))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 命令执行
int CLaserCommProc::iExeCmd(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len, char *rebuf)
{
	int iRet = EXIT_FAILURE;
	{
		lock_guard<mutex>guard(m_mtxLaserCtrl);
		if (EXIT_FAILURE == iSendMsg(hdr, (UINT8 *)msg, len))
		{
			return EXIT_FAILURE;
		}
		usleep(100000);
		iRet = iRecvData(rebuf);
		usleep(2000);
	}
	return iRet;
}

// 执行命令
int CLaserCommProc::iExeCmd(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len)
{
	int iRet = EXIT_FAILURE;
	{
		lock_guard<mutex>guard(m_mtxLaserCtrl);
		iRet = iSendMsg(hdr, (UINT8 *)msg, len);
		usleep(2000);
	}
	return iRet;
}

// 发送消息
int CLaserCommProc::iSendMsg(CCBMsgHdr_t *hdr, UINT8 *msg, UINT32 len)
{
	char data_to_send_over_rs485[CCB_MAX_FR_MLEN];
	memset(data_to_send_over_rs485, 0, CCB_MAX_FR_MLEN);
	int iLen = iPackageFrameMsg(hdr, msg, len, data_to_send_over_rs485,
		sizeof(data_to_send_over_rs485));
	return m_laserUartCtrl.iWrite((unsigned char *)data_to_send_over_rs485, iLen);
}

// 接收激光器数据
int CLaserCommProc::iRecvData(char * sData)
{
	int iLen = 0;
	unsigned char rcv_buf[100];
	memset(rcv_buf, 0, 100);
	iLen = m_laserUartCtrl.iRead(rcv_buf, 100);
	
	if (iLen < 1)    //len 不大于0时.
	{
		ostringstream os;
		os << "Recevice Nothing" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return iParseFrameMsg(sData, (char *)rcv_buf, iLen);
	
}

// 打包数据
int CLaserCommProc::iPackageFrameMsg(CCBMsgHdr_t *hdr, const UINT8 *src,
	UINT32 srclen,
	UINT8 *dest,
	UINT32 destlen)
{
#define ESCAPE_DLE  { *dest++ = DLE ; lrc ^= DLE ; }

	UINT8 lrc = 0xff;
	UINT8 *dstart = dest;
	UINT8 *destlimit = dest + destlen;
	const UINT8 *srclimit = src + srclen;

	/*****************************************************************************
	 * Validate message parameters
	 *****************************************************************************/

	if (destlen < CCB_MAX_UF_HLEN + 4)  // Room for SOM + hdr + EOM?
	{
		return -1;                      // Destination buffer too small
	}

	/*****************************************************************************
	 * Assemble SOM Sequence
	 *****************************************************************************/

	*dest++ = DLE;                  // Prepend two byte SOM sequence
	lrc ^= DLE;
	*dest++ = STX;
	lrc ^= STX;

	/*****************************************************************************
	 * Assemble and append message header
	 *****************************************************************************/
	*dest++ = hdr->sadd;        // Source address byte saddr
	lrc ^= hdr->sadd;
	if (hdr->sadd == DLE)
		ESCAPE_DLE
		;

	*dest++ = hdr->dadd;                // Destination address byte daddr
	lrc ^= hdr->dadd;
	if (hdr->sadd == DLE)
		ESCAPE_DLE
		;

	*dest++ = hdr->flags;               // Message flags byte flags
	lrc ^= hdr->flags;
	if (hdr->flags == DLE)
		ESCAPE_DLE
		;

	*dest++ = hdr->tag;                 // Message tag byte
	lrc ^= hdr->tag;
	if (hdr->tag == DLE)
		ESCAPE_DLE
		;

	*dest++ = srclen;               // Source message length dlen
	lrc ^= srclen;
	if (srclen == DLE)
		ESCAPE_DLE
		;

	/*****************************************************************************
	 * Append source message to destination
	 *****************************************************************************/
	while (src < srclimit && dest < destlimit)
	{
		if (*src == DLE)
		{
			ESCAPE_DLE
				;
			if (dest == destlimit)  // Must be room for two bytes in this case
			{
				return -1;
			}
		}

		lrc ^= *src;
		*dest++ = *src++;
	}

	/*****************************************************************************
	 * Append two byte EOM sequence
	 *****************************************************************************/
	if (destlimit - dest >= 2)          // Append two byte EOM sequence
	{
		*dest++ = DLE;
		lrc ^= DLE;
		*dest++ = ETX;
		lrc ^= ETX;

		/*****************************************************************************
		 * Append LRC
		 *****************************************************************************/
		*dest++ = lrc;
		return dest - dstart;           // Return length of framed message
	}

	return -1;
}


// 解析接收消息
int CLaserCommProc::iParseFrameMsg(char * sData, const UINT8 *src, UINT32 srclen)
{
	UINT8 *dstart, *dest;
	UINT8 *destlimit;
	const UINT8 *srclimit = src + srclen;
	bool esc = false;
	DeFramedMsg_t *curr;        // Current slot being written
	CCBMsg_t *m; // Pointer to unframed message
	DeFramedMsg_t WorkBuff;
	curr = &WorkBuff;                           // Point to result buffer
	dstart = dest = curr->msg;                  // Start of destination buffer
	destlimit = dest + CCB_MAX_UF_MLEN;     // End of destination buffer

	while ((src < srclimit) && (dest < destlimit))
	{

		if ((*src == DLE) && (esc == false))
		{
			src++;
			esc = true;
		}
		else if (esc == true && (*src == STX || *src == ETX))
		{
			src++;
			esc = false;
		}
		else
		{
			*dest++ = *src++;
			esc = false;
		}
	}

	if (dest == destlimit && src < srclimit)
	{
		ostringstream os;
		os << "failed to parse FrameMsg[" << CUtilFun::sByte2String((unsigned char*)src, srclen > 32? 32: srclen) << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	curr->len = dest - dstart;      // Store length in result buffer

	m = (CCBMsg_t *)&WorkBuff.msg[0];

	//discard messages not intended for the controller.
	if (m->hdr.dadd != CCB_CONTROLLER_ADDR)
	{

		ostringstream os;
		os << "Laser CCB_CONTROLLER_ADDR[" << m->hdr.dadd << "], expected Addr[" << CCB_CONTROLLER_ADDR  << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	strcpy(sData, WorkBuff.msg + 5);
	return EXIT_SUCCESS;
}


// 检查激光器错误码
int CLaserCommProc::iCheckLaserErrCode(int &iErrCode)
{
	char reply[256] = { 0 };
	iErrCode = 0;
	
	if (EXIT_FAILURE == iGetLaserErrCode(iErrCode)) //当出现数据接收错误时, 退出
	{
		return EXIT_FAILURE;
	}
	if (iErrCode)       //当错位代码有包含总线错位和二极管温度错位时
	{
		if (iErrCode & 0x00000800)        //485总线错误
		{
			if (EXIT_FAILURE == iResetBus())
			{
				return EXIT_FAILURE;
			}
		}

		//读取激光器错误代码
		if (EXIT_FAILURE == iGetLaserErrCode(iErrCode))
		{
			return EXIT_FAILURE;
		}
		else
		{
			return EXIT_SUCCESS;
		}
	}
	else
	{
		return EXIT_SUCCESS;
	}
}

// 重置总线
int CLaserCommProc::iResetBus()
{
	// 复位总线
	UINT8 Msg[CCB_MAX_UF_MLEN];
	Msg[0] = MASTER_RESET_BUS; //MASTER_ASSIGN_ADDRESS; //bus management command
	Msg[1] = CCB_LOWEST_DEV_ADDR; //new address for device;
	Msg[2] = '\0'; //terminate command data
	UINT8 MsgLen = 1; // 3 length of data component in address assignment message.
	CCBMsgHdr_t assignMsgHdr11 =
	{
		CCB_CONTROLLER_ADDR,  //source address
		CCB_BROADCAST_ADDR,  //CCB_LOWEST_DEV_ADDR,  //destination address
		CCB_FLAG_BUSMGMT, //0    //flags
		0,                  //optional tags
		0
	}; 
	if (EXIT_FAILURE == iExeCmd(&assignMsgHdr11, Msg, MsgLen))
	{
		ostringstream os;
		os << "failed to reset bus" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	sleep(2);

	// 分配地址
	if (EXIT_FAILURE == iAssignAddr())
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 分配地址
int CLaserCommProc::iAssignAddr()
{
	UINT8 Msg[CCB_MAX_UF_MLEN];
	Msg[0] = MASTER_ASSIGN_ADDRESS; //bus management command
	Msg[1] = CCB_LOWEST_DEV_ADDR; //new address for device;
	Msg[2] = '\0'; //terminate command data
	UINT8 MsgLen = 3; //length of data component in address assignment message.
	CCBMsgHdr_t assignMsgHdr11 = { CCB_CONTROLLER_ADDR,  //source address
								   CCB_DEFAULT_DEV_ADDR,   //destination address
								   CCB_FLAG_BUSMGMT,     //flags
								   0,                  //tags
								   0
	};

	if (EXIT_FAILURE == iExeCmd(&assignMsgHdr11, Msg, MsgLen))
	{
		ostringstream os;
		os << "failed to assign addr" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

int CLaserCommProc::iExeCmd(char *msg, unsigned len, char *rebuf)
{
	return EXIT_FAILURE;
}

LaserCommProcBios488.h

#pragma once
#include <stdint.h>
#include "ccb.h"
#include "InnerDeviceInfo.h"
#include "LaserCommProc.h"
#include "LaserUartCtrlBios488.h"

class CLaserCommProcBios488:public CLaserCommProc
{
public:
	// 构造函数
	CLaserCommProcBios488(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl);
	// 析构函数
	~CLaserCommProcBios488();
	// 初始化
	virtual int iInitialize();
public:
	// 关闭激光机
	virtual int iTurnOffLaser();
	// 打开激光器
	virtual int iTurnOnLaser();
	// 设置激光功率
	virtual int iSetLaserPower(int iLaserPower);
	// 恢复激光器
	virtual int iRecoverLaser();
	// 获取激光器状态码
	virtual int iGetLaserStatusCode(int &iStatusCode);
	// 获取激光器类型
	virtual int iGetLaserType(string & sLaserType);
	// 获取激光器基础信息
	virtual int iGetLaserBaseInfo(string & sModel, string & sPN, string & sSN);
	// 获取激光器波长
	virtual int iGetLaserWaveLength(int & iWaveLength);
	// 获取激光器温度信息
	virtual int iGetLaserTempInfo(float &fCurrent, float & fTemp, float & fDiode);
	// 获取激光器信息
	virtual int iGetLaserInfo(int & iPower, stLaserInfo & laserInfo);
	// 获取激光功率
	virtual int iGetLaserPower(int & iPower);
	// 检查激光器错误码
	virtual int iCheckLaserErrCode(int &iErrCode);

    //void setLaserEngineerMode();  //激光器进入工程模式

private:
	// 命令执行
	int iExeCmd(const char *msg, unsigned len, char *rebuf);

private:
	// 激光器串口控制
	CLaserUartCtrlBios488 m_laserUartCtrl;
	// 操作互斥锁
	mutex m_mtxLaserCtrl;
};

LaserCommProcBios488.cpp

  #include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <termios.h>
#include<iostream>
#include<string>
#include <iomanip>
#include <stdlib.h>
#include "InnerDeviceInfo.h"
#include "LaserCommProcBios488.h"
#include "LX_obis_cmd.h"
#include "Log.h"
#include "LaserCommProc.h"
#include "UtilFun.h"
#include "obis_cmd.h"
#include "DeviceComCtrl.h"
#include "LaserCtrl.h"
#include "DeviceParamMng.h"
#include "DeviceStatusMng.h"
#include "SettingParamMng.h"
using namespace std;
/// 构造函数
CLaserCommProcBios488::CLaserCommProcBios488(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl)
	:m_laserUartCtrl(uartConfigInfo), CLaserCommProc(uartConfigInfo, iSendEMIOCode, iRecvEMIOcode, pEMIOCtrl)
{
	return;
}

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

// 初始化
int CLaserCommProcBios488::iInitialize()
{
	int iLaserType = 1;
	if (EXIT_FAILURE == CDeviceComCtrl::GetInstance()->iSetLaserTypes(iLaserType)) //通过设计FPGA管脚设置激光器类型,设计为参数0时为旧激光器IBOS,设置参数为1时为新激光器(精英光电)
	{
		ostringstream os;
		os << "failed to initialize SetLaserTypes" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	usleep(1000);
	// 初始化串口
	if (EXIT_FAILURE == m_laserUartCtrl.iInitialize())
	{
		printf("iInitialize erro");
		return EXIT_FAILURE;
	}

	// 获取错误码
	string sLaserType;
	if (EXIT_FAILURE == iGetLaserType(sLaserType))
	{
		ostringstream os;
		os << "failed to initializing" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 关闭激光机
int CLaserCommProcBios488::iTurnOffLaser()
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_SET_OFF_STR, LASER_SET_OFF_STR_LEN, sReadBuf);
    usleep(1000);
    if(iLen > 1)
	{
		ostringstream os;
		os << ".............turnOffLaser successed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	else
	{
		ostringstream os;
		os << ".............turnOffLaser failed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 打开激光器
int CLaserCommProcBios488::iTurnOnLaser()
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_SET_ON_STR, LASER_SET_ON_STR_LEN, sReadBuf);
	usleep(1000);
    if(iLen > 1)
	{
		ostringstream os;
		os << ".............turnOnLaser successed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
	}
	else//len 不大于0时.
	{
		ostringstream os;
		os << ".............turnOnLaser failed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

// 设置激光功率
int CLaserCommProcBios488::iSetLaserPower(int iLaserPower)
{
	char sReadBuf[100];
	iLaserPower = iLaserPower / 10;
	sprintf(sReadBuf, LASER_SET_POWER_STR, iLaserPower);
	char reply[100];
	int iLen = iExeCmd((const char *)sReadBuf, strlen(sReadBuf) + 1, reply);
    if(iLen > 1)
	{
		iLaserPower = iLaserPower * 10;
		//LOG(DEBUG, "setLaserPower successed = %d\n", iLaserPower);
	}
	else
	{
		ostringstream os;
		os << ".............setLaserPower failed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	usleep(1000);
	return EXIT_SUCCESS;
}
// 恢复激光器
int CLaserCommProcBios488::iRecoverLaser()
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_RESET_STR, LASER_RESET_STR_LEN, sReadBuf);
    if(iLen < 1)
	{
		ostringstream os;
		os << ".............setLaserPower failed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	usleep(1000);
	return iLen;
}

// 获取激光器状态码                       ***
int CLaserCommProcBios488::iGetLaserStatusCode(int &iStatusCode)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_GET_CDRH_STR, LASER_GET_CDRH_STR_LEN, sReadBuf);
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get Status failed\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	string status = sReadBuf;
	string iState = status.substr(0, 2);
	CUtilFun CF;
	if (iState == "OK")
	{
		const string sState = status.substr(4, 8);
		if (CF.bIsHex(sState))
		{
			iStatusCode = stoi(sState, 0, 16);
		}
		else
		{
			//LOG(ERROR, "LaserStatus failed\n");
			return EXIT_FAILURE;
		}
	}
	else
	{
		status = status.substr(0, 8);
		if (CF.bIsHex(status))
		{
			iStatusCode = stoi(status, 0, 16);
		}
		else
		{
			//LOG(ERROR, "LaserStatus failed\n");
			return EXIT_FAILURE;
		}
	}
	usleep(1000);
	return EXIT_SUCCESS;
}

// 获取激光器类型
int CLaserCommProcBios488::iGetLaserType(string & sLaserType)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_TEST_STR, LASER_TEST_STR_LEN, sReadBuf);                //激光器类型
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get Type failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sLaserType = sReadBuf;
	sLaserType = sLaserType.substr(0, 11);
	usleep(1000);
	return EXIT_SUCCESS;
}
// 获取激光器基础信息
int CLaserCommProcBios488::iGetLaserBaseInfo(string & sModel, string & sPN, string & sSN)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_MODEL_TYPE, LASER_MODEL_TYPE_LEN, sReadBuf);            //获取型号
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get Mod failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sModel = sReadBuf;
	sModel = sModel.substr(0, 11);
	usleep(1000);
	iLen = iExeCmd(LASER_PN_STR, LASER_PN_STR_LEN, sReadBuf);              //获取PN 零件号
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get Pn failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sPN = sReadBuf;
	sPN = sPN.substr(0, 9);
	usleep(1000);
	iLen = iExeCmd(LASER_SN_STR, LASER_SN_STR_LEN, sReadBuf);                        //获取SN 产品序列号
	if(iLen < 1)
	{
		ostringstream os;
		os << ".............Get Sn failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sSN = sReadBuf;
	sSN = sSN.substr(0, 15);
	usleep(1000);
	return EXIT_SUCCESS;
}

// 获取激光器波长
int CLaserCommProcBios488::iGetLaserWaveLength(int & iWaveLength)
{
	usleep(1000);
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_WAVE_LENGTH_STR, LASER_WAVE_LENGTH_STR_LEN, sReadBuf);  //获取激光器波长
	if(iLen < 1)
	{
		ostringstream os;
		os << ".............Get Wave failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sscanf(sReadBuf, "%i", &iWaveLength);
	usleep(1000);
	return EXIT_SUCCESS;
}

// 获取激光器温度信息 ***
int CLaserCommProcBios488::iGetLaserTempInfo(float &fCurrent, float & fTemp, float & fDiode)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_POW_CURR_STR, LASER_POW_CURR_STR_LEN, sReadBuf);        //获取电流	
	if(iLen < 1)
	{
		ostringstream os;
		os << ".............Get Curr failed !\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sscanf(sReadBuf, " %f ", &fCurrent);
	if (fCurrent < 0)
	{
		fCurrent = 0.000;
	}
	usleep(1000);
	iLen = iExeCmd(LASER_TEMP_SHELL_STR, LASER_TEMP_SHELL_STR_LEN, sReadBuf);        //激光器外壳温度
	if(iLen < 1)
	{
		ostringstream os;
		os << ".............Get ShellTemp failed!\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sscanf(sReadBuf, "%f", &fTemp);
	usleep(1000);

	iLen = iExeCmd(LASER_TEMP_DIODE_STR, LASER_TEMP_DIODE_STR_LEN, sReadBuf);        //激光器二极管温度
	if(iLen < 1)
	{
		ostringstream os;
		os << ".............Get Temp failed!\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	sscanf(sReadBuf, "%f", &fDiode);
	usleep(1000);
	return EXIT_SUCCESS;
}

// 获取激光器信息   **/*
int CLaserCommProcBios488::iGetLaserInfo(int & iPower, stLaserInfo & laserInfo)
{
	if (EXIT_FAILURE == iGetLaserBaseInfo(laserInfo.m_sModel, laserInfo.m_sPN, laserInfo.m_sSN))
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iGetLaserTempInfo(laserInfo.m_fCurrent, laserInfo.m_fBasePlateTemp, laserInfo.m_fDiodeTemp))
	{
		return EXIT_FAILURE;
	}

	if (EXIT_FAILURE == iGetLaserPower(iPower))
	{
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == iGetLaserWaveLength(laserInfo.m_iWaveLength))
	{
		return EXIT_FAILURE;
	}
	if (EXIT_FAILURE == iGetLaserType(laserInfo.m_sType))
	{
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}           

// 获取激光功率  ***
int CLaserCommProcBios488::iGetLaserPower(int & iPower)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_GET_POWER_STR, LASER_GET_POWER_STR_LEN, sReadBuf);      //获取激光器功率
	sscanf(sReadBuf, "0.%05d\r\n", &iPower);
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get iPower failed!\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	unsigned int uiLaserPower = iPower;
	iPower = iPower * 10;
	iPower = iPower + 1000 - (iPower%1000);  
	if (uiLaserPower < 150)
	{
		iPower = 0;
	}
	usleep(1000);
	return EXIT_SUCCESS;
}

// 读写获取信息
int CLaserCommProcBios488::iExeCmd(const char *msg, unsigned len, char *rebuf)
{
	memset(rebuf, 0, 100);
	int iLen = m_laserUartCtrl.iWrite((unsigned char *)msg, len);
	if (iLen < 1)
	{
		return EXIT_FAILURE;
	}
	iLen = m_laserUartCtrl.iRead((unsigned char *)rebuf, 100);
	usleep(1000);
	return iLen;
}

//激光器错误代码
int CLaserCommProcBios488::iCheckLaserErrCode(int &iErrCode)
{
	char sReadBuf[100];
	int iLen = iExeCmd(LASER_FAULT_CODE_STR, LASER_FAULT_CODE_STR_LEN, sReadBuf);      //获取激光器功率
	if (iLen < 1)
	{
		ostringstream os;
		os << ".............Get Laser failed!\n" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Info);
		return EXIT_FAILURE;
	}
	
	string status = sReadBuf;
	string iState = status.substr(0, 2);
	CUtilFun CF;
	if (iState == "OK")
	{
		const string sState = status.substr(4, 8);
		if (CF.bIsHex(sState))
		{
			iErrCode = stoi(sState, 0, 16);
			cout << "erro code" << iErrCode << endl;
		}
		else
		{
			//LOG(ERROR, "LaserStatus failed\n");
			return EXIT_FAILURE;
		}
	}
	else
	{
		status = status.substr(0, 8);
		if (CF.bIsHex(status))
		{
			iErrCode = stoi(status, 0, 16);
		}
		else
		{
			//LOG(ERROR, "LaserStatus failed\n");
			return EXIT_FAILURE;
		}
	}

	usleep(1000);
	return EXIT_SUCCESS;
}

LaserUartCtrl.h

#pragma once
#include <mutex>
#include "UartCtrl.h"
#include "SysConfigInfo.h"
#include "EMIODevCtrl.h"
using namespace std;
class CLaserUartCtrl:public CUartCtrl
{
public:
	// 构造函数
	CLaserUartCtrl(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl);
	// 析构函数
	~CLaserUartCtrl();
public:
	// 读数据
	virtual int iRead(unsigned char * rdBuf, int iRdSize);
	// 写数据
	virtual int iWrite(unsigned char * wrBuf, int iWrSize);

	int iRead(char * rdBuf, int iRdSize);
	// 写数据
	int iWrite(const char * wrBuf, int iWrSize);
protected:
	// 设置串口
	virtual int iSetUart(int iFlowCtrl, int iBits, int iStopBits, int iParity);
private:
	// 串口发送EMIO控制
	CEMIODevCtrl m_uartSendCtrl;
	// 串口接收EMIO控制
	CEMIODevCtrl m_uartRecvCtrl;
	// 串口的读写互斥
	mutex m_mtxRdWr;
};

LaserUartCtrl.cpp

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include<linux/ioctl.h>
#include <linux/i2c-dev.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <termios.h>
#include "Log.h"
#include "LaserUartCtrl.h"

// 构造函数
CLaserUartCtrl::CLaserUartCtrl(const stUartConfigInfo & uartConfigInfo, int iSendEMIOCode, int iRecvEMIOcode, CEMIOCtrl * pEMIOCtrl)
	:CUartCtrl(uartConfigInfo.m_sUartDriverFile, uartConfigInfo.m_iUartSpeed),m_uartSendCtrl(iSendEMIOCode, pEMIOCtrl), m_uartRecvCtrl(iRecvEMIOcode, pEMIOCtrl)
{
	m_uartSendCtrl.iSetHigh();
	m_uartRecvCtrl.iSetHigh();
	return;
}

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

// 读数据
int CLaserUartCtrl::iRead(unsigned char * rdBuf, int iRdSize)
{
	int iLen = -1; 
	fd_set fs_read;
	struct timeval time;

	FD_ZERO(&fs_read);
	FD_SET(m_iDriverFileHandle, &fs_read);

	time.tv_sec = 0;
	time.tv_usec = 101000;
	select(m_iDriverFileHandle + 1, &fs_read, NULL, NULL, &time);
	string sData;
	if (FD_ISSET(m_iDriverFileHandle, &fs_read))
	{
		lock_guard<mutex>guard(m_mtxRdWr);
		iLen = read(m_iDriverFileHandle, rdBuf, iRdSize);
		while (iLen > 0)
		{
			copy(rdBuf, rdBuf + iLen, back_inserter(sData));
			iLen = read(m_iDriverFileHandle, rdBuf, iRdSize);
		}
	}
	else
	{
		ostringstream os;
		os << "failed to read data" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	iLen = (iRdSize > sData.size() ? sData.size() : iRdSize);
	memcpy(rdBuf, &sData[0], iLen);
	return iLen;
}

// 写数据
int CLaserUartCtrl::iWrite(unsigned char * wrBuf, int iWrSize)
{
	int iLen = -1;
	{
		lock_guard<mutex>guard(m_mtxRdWr);
		m_uartSendCtrl.iSetHigh();
		m_uartRecvCtrl.iSetHigh();
		usleep(1000);
		iLen = write(m_iDriverFileHandle, wrBuf, iWrSize);
		usleep(500);
		m_uartSendCtrl.iSetLow();
		m_uartRecvCtrl.iSetLow();
	}
	
	if (iLen != iWrSize)
	{
		tcflush(m_iDriverFileHandle, TCOFLUSH);
		ostringstream os;
		os << "failed to write data" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	return iLen;
}

// 配置状态
int CLaserUartCtrl::iSetUart(int iFlowCtrl, int iBits, int iStopBits, int iParity)
{
	struct termios options;
	if (tcgetattr(m_iDriverFileHandle, &options) != 0)
	{
		ostringstream os;
		os << "failed to setup Serial[" << sGetDriverFile() << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	// 设置比特率\
	.
	int iUartSpeedMode;
	if (EXIT_FAILURE == iGetUartSpeedMode(iUartSpeedMode))
	{
		return EXIT_FAILURE;
	}

	cfsetispeed(&options, iUartSpeedMode);    //输入波特率
	cfsetospeed(&options, iUartSpeedMode);    //输出波特率


	// 设置控制模式状态
	options.c_cflag |= CLOCAL; // 本地连接
	options.c_cflag |= CREAD;  // 接收使能

	// 设置数据流控制
	switch (iFlowCtrl)
	{
	case 0:
		options.c_cflag &= ~CRTSCTS;   //无硬件流控
		break;
	case 1:
		options.c_cflag |= CRTSCTS;    //使用硬件流控制
		break;
	case 2:
		options.c_cflag |= (IXON | IXOFF | IXANY);//使用软件流控制
		break;

	}

	//设置数据位
	//屏蔽其他标志位
	options.c_cflag &= ~CSIZE;
	switch (iBits)
	{
	case 5:
		options.c_cflag |= CS5;
		break;
	case 6:
		options.c_cflag |= CS6;
		break;
	case 7:
		options.c_cflag |= CS7;
		break;
	case 8:
		options.c_cflag |= CS8;
		break;
	default:
	{
		ostringstream os;
		os << "DataBits[" << iStopBits << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}

	//设置校验位
	switch (iParity)
	{
	case 'n':
	case 'N': //无奇偶校验位。
		options.c_cflag &= ~PARENB;
		options.c_iflag &= ~INPCK;
		break;
	case 'o':
	case 'O': //设置为奇校验
		options.c_cflag |= (PARODD | PARENB);
		options.c_iflag |= INPCK;
		break;
	case 'e':
	case 'E': //设置为偶校验
		options.c_cflag |= PARENB;
		options.c_cflag &= ~PARODD;
		options.c_iflag |= INPCK;
		break;
	case 's':
	case 'S': //设置为空格
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		break;
	default:
	{
		ostringstream os;
		os << "Parity[" << (char)iParity << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}

	// 设置停止位
	switch (iStopBits)
	{
	case 1:
		options.c_cflag &= ~CSTOPB;
		break;
	case 2:
		options.c_cflag |= CSTOPB;
		break;

	default:
	{
		ostringstream os;
		os << "StopBits[" << iStopBits << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}
	//修改输出模式,原始数据输出
	options.c_oflag &= ~OPOST;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	options.c_oflag &= ~(ONLCR | OCRNL);   //防止输出映射处理

	options.c_iflag &= ~(IXON | IXOFF | IXANY);
	options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
	options.c_iflag |= IGNPAR;

	//设置等待时间和最小接收字符
	options.c_cc[VTIME] = 2; //读取一个字符等待1*(1/10)s
	options.c_cc[VMIN] = 1;  //读取字符的最少个数为1

	//清空输出
	tcflush(m_iDriverFileHandle, TCIFLUSH);

	//激活配置
	if (tcsetattr(m_iDriverFileHandle, TCSANOW, &options) != 0)
	{
		ostringstream os;
		os << "failed to set Serial[" << sGetDriverFile() << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	else
	{
		tcflush(m_iDriverFileHandle, TCIOFLUSH);
		return EXIT_SUCCESS;
	}
}


// 读数据
int CLaserUartCtrl::iRead(char * rdBuf, int iRdSize)
{
	fd_set fs_read;
	struct timeval tv_timeout;
	FD_ZERO(&fs_read);
	FD_SET(m_iDriverFileHandle, &fs_read);
	tv_timeout.tv_sec = 1;
	tv_timeout.tv_usec = 101000;
	select(m_iDriverFileHandle + 1, &fs_read, NULL, NULL, &tv_timeout);
	usleep(1500);
	int iLen = read(m_iDriverFileHandle, rdBuf, iRdSize);
	if (iLen < 1)
	{
		//LOG(DEBUG, " fail write date \n");
	}
	return iLen;
}

// 写数据
int CLaserUartCtrl::iWrite(const char * wrBuf, int iWrSize)
{
	const string cnsSetPowerCmdInfo = wrBuf;
	usleep(1000);
	int iLen = write(m_iDriverFileHandle, cnsSetPowerCmdInfo.c_str(), cnsSetPowerCmdInfo.length());
	if (iLen < 1)
	{
		//LOG(DEBUG, " fail write date \n");
	}
	usleep(10000);
	return iLen;
}

LaserUartCtrlBios488.h

#pragma once
#include <mutex>
#include "UartCtrl.h"
#include "SysConfigInfo.h"
using namespace std;
class CLaserUartCtrlBios488 :public CUartCtrl
{
public:
	// 构造函数
	CLaserUartCtrlBios488(const stUartConfigInfo & uartConfigInfo);
	// 析构函数
	~CLaserUartCtrlBios488();
public:
	// 读数据
	virtual int iRead(unsigned char * rdBuf, int iRdSize);
	// 写数据
	virtual int iWrite(unsigned char * wrBuf, int iWrSize);
protected:
	// 设置串口
	virtual int iSetUart(int iFlowCtrl, int iBits, int iStopBits, int iParity);
private:
	// 串口的读写互斥
	mutex m_mtxRdWr;
};

LaserUartCtrlBios488.cpp

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include<linux/ioctl.h>
#include <linux/i2c-dev.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <termios.h>
#include "Log.h"
#include "LaserUartCtrlBios488.h"

// 构造函数
CLaserUartCtrlBios488::CLaserUartCtrlBios488(const stUartConfigInfo & uartConfigInfo)
	:CUartCtrl(uartConfigInfo.m_sUartDriverFile, uartConfigInfo.m_iUartSpeed)
{
	return;
}

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

// 读数据
int CLaserUartCtrlBios488::iRead(unsigned char * rdBuf, int iRdSize)
{
	int iLen = -1; 

	fd_set fs_read;
	struct timeval tv_timeout;
	FD_ZERO(&fs_read);
	FD_SET(m_iDriverFileHandle, &fs_read);
	tv_timeout.tv_sec = 1;
	tv_timeout.tv_usec = 101000;
	select(m_iDriverFileHandle + 1, &fs_read, NULL, NULL, &tv_timeout);
	string sData;
	if (FD_ISSET(m_iDriverFileHandle, &fs_read))
	{
		lock_guard<mutex>guard(m_mtxRdWr);
		int iLen = read(m_iDriverFileHandle, rdBuf, iRdSize);
		if (iLen < 1)
		{
			ostringstream os;
			os << "failed to read data ! [" << m_iDriverFileHandle << "]" << endl;
			CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		}
		while (iLen > 0)
		{
			copy(rdBuf, rdBuf + iLen, back_inserter(sData));
			iLen = read(m_iDriverFileHandle, rdBuf, iRdSize);
		}
	}
	else
	{
		ostringstream os;
		os << "failed to read data" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	iLen = (iRdSize > sData.size() ? sData.size() : iRdSize);
	memcpy(rdBuf, &sData[0], iLen);
	return iLen;
}

// 写数据
int CLaserUartCtrlBios488::iWrite(unsigned char * wrBuf, int iWrSize)
{
	const string cnsSetPowerCmdInfo = (const char* )wrBuf;
	int iLen = -1;
	{
		lock_guard<mutex>guard(m_mtxRdWr);
		iLen = write(m_iDriverFileHandle, cnsSetPowerCmdInfo.c_str(), cnsSetPowerCmdInfo.length());
	}
	
	if (iLen != iWrSize)
	{
		tcflush(m_iDriverFileHandle, TCOFLUSH);
		ostringstream os;
		os << "failed to write data" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
	}
	return iLen;

}

// 配置状态
int CLaserUartCtrlBios488::iSetUart(int iFlowCtrl, int iBits, int iStopBits, int iParity)
{
	struct termios options;
	if (tcgetattr(m_iDriverFileHandle, &options) != 0)
	{
		ostringstream os;
		os << "failed to setup Serial[" << sGetDriverFile() << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}

	// 设置比特率
	int iUartSpeedMode;
	if (EXIT_FAILURE == iGetUartSpeedMode(iUartSpeedMode))
	{
		return EXIT_FAILURE;
	}

	cfsetispeed(&options, iUartSpeedMode);    //输入波特率
	cfsetospeed(&options, iUartSpeedMode);    //输出波特率


	// 设置控制模式状态
	options.c_cflag |= CLOCAL; // 本地连接
	options.c_cflag |= CREAD;  // 接收使能

	// 设置数据流控制
	switch (iFlowCtrl)
	{
	case 0:
		options.c_cflag &= ~CRTSCTS;   //无硬件流控
		break;
	case 1:
		options.c_cflag |= CRTSCTS;    //使用硬件流控制
		break;
	case 2:
		options.c_cflag |= (IXON | IXOFF | IXANY);//使用软件流控制
		break;

	}

	//设置数据位
	//屏蔽其他标志位
	options.c_cflag &= ~CSIZE;
	switch (iBits)
	{
	case 5:
		options.c_cflag |= CS5;
		break;
	case 6:
		options.c_cflag |= CS6;
		break;
	case 7:
		options.c_cflag |= CS7;
		break;
	case 8:
		options.c_cflag |= CS8;
		break;
	default:
	{
		ostringstream os;
		os << "DataBits[" << iStopBits << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}

	//设置校验位
	switch (iParity)
	{
	case 'n':
	case 'N': //无奇偶校验位。
		options.c_cflag &= ~PARENB;
		options.c_iflag &= ~INPCK;
		break;
	case 'o':
	case 'O': //设置为奇校验
		options.c_cflag |= (PARODD | PARENB);
		options.c_iflag |= INPCK;
		break;
	case 'e':
	case 'E': //设置为偶校验
		options.c_cflag |= PARENB;
		options.c_cflag &= ~PARODD;
		options.c_iflag |= INPCK;
		break;
	case 's':
	case 'S': //设置为空格
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		break;
	default:
	{
		ostringstream os;
		os << "Parity[" << (char)iParity << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}

	// 设置停止位
	switch (iStopBits)
	{
	case 1:
		options.c_cflag &= ~CSTOPB;
		break;
	case 2:
		options.c_cflag |= CSTOPB;
		break;

	default:
	{
		ostringstream os;
		os << "StopBits[" << iStopBits << "] No supported" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	}
	//修改输出模式,原始数据输出
	options.c_oflag &= ~OPOST;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	options.c_oflag &= ~(ONLCR | OCRNL);   //防止输出映射处理

	options.c_iflag &= ~(IXON | IXOFF | IXANY);
	options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
	options.c_iflag |= IGNPAR;

	//设置等待时间和最小接收字符
	options.c_cc[VTIME] = 2; //读取一个字符等待1*(1/10)s
	options.c_cc[VMIN] = 1;  //读取字符的最少个数为1

	//清空输出
	tcflush(m_iDriverFileHandle, TCIFLUSH);

	//激活配置
	if (tcsetattr(m_iDriverFileHandle, TCSANOW, &options) != 0)
	{
		ostringstream os;
		os << "failed to set Serial[" << sGetDriverFile() << "]" << endl;
		CLog::GetInstance()->WriteLog(__FUNCTION__, __LINE__, os.str(), Log_Error);
		return EXIT_FAILURE;
	}
	else
	{
		tcflush(m_iDriverFileHandle, TCIOFLUSH);
		return EXIT_SUCCESS;
	}
}

ThreadProc.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; // 线程列表
};

ThreadProc.cpp

#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;
}

main()  将外部程序的实现包含在内部,或外部调用的模式,保持激光器控制的完整性

int main()
{
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;}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值