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