监控芯片接收内容:
#include "ProtocolManager.h"
#include "ProtocolHeartBeat.h"
#include "ProtocolCommunicate.h"
#include "ProtocolAlarm.h"
#include "ProtocolWirelessRawData.h"
#include "ProtocolSpo2.h"
ProtocolManager * ProtocolManager::_instance = NULL;
ProtocolManager::ProtocolManager()
:_circleBuf(2048)
{
_allProtocolObjs.clear();
#if USING_CMD_LIST
_cmds.clear();
#endif
_proDrv = NULL;
}
ProtocolManager::~ProtocolManager()
{
}
int ProtocolManager::registerProtocol(ProtocolObj *obj)
{
int ret = 0;
if (!obj)
{
return 1;
}
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
if (*it == obj)
{
ret = 1;
return ret;
}
}
obj->init();
_allProtocolObjs.push_back(obj);
return ret;
}
int ProtocolManager::unregisterProtocol(ProtocolObj *obj)
{
int ret = 1;
if (!obj)
{
return ret;
}
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
if (*it == obj)
{
ret = 0;
_allProtocolObjs.erase(it);
obj->deinit();
return ret;
}
}
return ret;
}
int ProtocolManager::loopRun()
{
if (_proDrv)
_proDrv->loopRun();
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
obj->loopRun();
}
}
handleProtocol();
#if USING_CMD_LIST
handleSendCmds();
#endif
return 0;
}
void ProtocolManager::init()
{
ProtocolHeartBeat *pHeartBeat = new ProtocolHeartBeat(this);
registerProtocol(pHeartBeat);
ProtocolAlarm *pAlarm = new ProtocolAlarm(this);
registerProtocol(pAlarm);
ProtocolWirelessRawData *pWireless = new ProtocolWirelessRawData(this);
registerProtocol(pWireless);
ProtocolSpo2 *pSpo2 = new ProtocolSpo2(this);
registerProtocol(pSpo2);
ProtocolCommunicate *pCommunicate = new ProtocolCommunicate();
registerProDrv(pCommunicate);
}
void ProtocolManager::registerProDrv(ProtocolDrv *drv)
{
if (drv)
{
drv->init();
_proDrv = drv;
}
}
int ProtocolManager::checkData(uint8_t *buf, int len)
{
int sum = 0;
for (int i = 0; i < len; i++)
{
sum += buf[i];
}
return sum;
}
#if 0
void ProtocolManager::handleProtocol()
{
int loopCnt = 0;
while (_circleBuf.length() >= 7)
{
loopCnt++;
if (loopCnt >= 50)
{
break;//防止出现死循环
}
uint8_t startCh = _circleBuf[0];
if (startCh == 0xAA)
{
uint8_t h1 = _circleBuf[1];
uint8_t h2 = _circleBuf[2];
uint8_t h3 = _circleBuf[3];
uint8_t h4 = _circleBuf[4];
uint16_t len = (h3 << 8) | h4;
//这里存在一个风险,如果数据长度即 _circleBuf[3]_circleBuf[4]数据错位那么就会导致我们buff存满永远处理不了数据
//例如我们循环队列长度是2048 但是len解析出来是4096 那么就会出现错误
//所以我们这里给buffer一个阀值
//如果这包协议中len的长度超出我们的这个值就将数据推出buffer
if (len > 500)
{
_circleBuf.popData();
continue;
}
if (_circleBuf.length() < len + 7)
{
break;
}
else
{
uint8_t *buf = new uint8_t[len + 7];
for (int i = 0; i < len + 7; i++)
{
buf[i] = _circleBuf.popData();
}
int checkRcv = (buf[len + 5] << 8) | buf[len + 6];
int checkRes = checkData(&buf[5], len);
if (checkRcv != checkRes)
{
log_info("Rcv an invalid packet\n");
}
else
{
uint16_t cmd = (buf[1] << 8) | buf[2];
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (; it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
if (obj->getId() == cmd)
{
obj->handleRcvData(&buf[5], len);
}
}
}
}
delete [] buf;
}
}
else
{
//无效的头部信息
_circleBuf.popData();
}
}
}
#endif
void ProtocolManager::handleProtocol()
{
int loopCnt = 0;
while (_circleBuf.length() >= 7)
{
loopCnt++;
if (loopCnt >= 50)
{
break;//防止出现死循环
}
uint8_t startCh1 = _circleBuf[0];
uint8_t startCh2 = _circleBuf[1];
if (startCh1 == 0xAA && startCh2 == 0xFF)
{
uint8_t h3 = _circleBuf[3];
uint8_t h4 = _circleBuf[4];
uint16_t len = (h3 << 8) | h4;
//这里存在一个风险,如果数据长度即 _circleBuf[3]_circleBuf[4]数据错位那么就会导致我们buff存满永远处理不了数据
//例如我们循环队列长度是2048 但是len解析出来是4096 那么就会出现错误
//所以我们这里给buffer一个阀值
//如果这包协议中len的长度超出我们的这个值就将数据推出buffer
if (len > 500)
{
_circleBuf.popData();
continue;
}
if (_circleBuf.length() < len + 7)
{
break;
}
else
{
uint8_t *buf = new uint8_t[len + 7];
for (int i = 0; i < len + 7; i++)
{
//buf[i] = _circleBuf.popData();
buf[i] = _circleBuf[i];
}
int checkRcv = (buf[len + 5] << 8) | buf[len + 6];
int checkRes = checkData(&buf[5], len);
if (checkRcv != checkRes)
{
_circleBuf.popData();
log_info("Rcv an invalid packet\n");
}
else
{
for (int i = 0; i < len + 7; i++)
{
buf[i] = _circleBuf.popData();
}
uint8_t cmd = buf[2];
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (; it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
if (obj->getId() == cmd)
{
obj->handleRcvData(&buf[5], len);
}
}
}
}
delete [] buf;
}
}
else
{
//无效的头部信息
_circleBuf.popData();
}
}
}
int ProtocolManager::sendData(uint8_t *buf, uint16_t len, uint8_t cmd)
{
if (buf)
{
uint16_t sum = 0;
uint16_t sendLen = 1 + 2 + 2 + len + 2; //查看协议文档
uint8_t *sendBuf = new uint8_t[sendLen];
sendBuf[0] = 0xAA;
sendBuf[1] = 0xFF;
sendBuf[2] = cmd;
sendBuf[3] = (len & 0xFF00)>>8;
sendBuf[4] = (len & 0xFF);
for (int i = 0; i < len; i++)
{
sendBuf[5+ i] = buf[i];
sum += buf[i];
}
sendBuf[5 + len] = (sum & 0xFF00)>>8;
sendBuf[5 + len + 1] = (sum & 0xFF);
#if 0
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete [] sendBuf;
#endif
#if USING_CMD_LIST
SendCmd *cmd = new SendCmd;
cmd->cmd = sendBuf;
cmd->len = sendLen;
_cmds.push_back(cmd);
#else
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete [] sendBuf;
#endif
return len;
}
return 0;
}
#if USING_CMD_LIST
void ProtocolManager::handleSendCmds()
{
while (!_cmds.empty())
{
list<SendCmd *>::iterator it = _cmds.begin();
_cmds.erase(it);
SendCmd *cmd = *it;
if (_proDrv)
_proDrv->sendData(cmd->cmd, cmd->len);
delete cmd->cmd;
delete cmd;
}
}
#endif
int ProtocolManager::rcvData(uint8_t *buf, uint16_t len)
{
int ret = 0;
if (buf)
{
for (int i = 0; i < len; i++)
{
_circleBuf.pushData(buf[i]);
}
ret = len;
}
return ret;
}
协议接收数据
void ProtocolManager::handleProtocol()
{
int loopCnt = 0;
while (_circleBuf.length() >= 7)
{
loopCnt++;
if (loopCnt >= 50)
{
break;//防止出现死循环
}
uint8_t startCh1 = _circleBuf[0];
uint8_t startCh2 = _circleBuf[1];
if (startCh1 == 0xAA && startCh2 == 0xFF)
{
uint8_t h3 = _circleBuf[3];
uint8_t h4 = _circleBuf[4];
uint16_t len = (h3 << 8) | h4;
//这里存在一个风险,如果数据长度即 _circleBuf[3]_circleBuf[4]数据错位那么就会导致我们buff存满永远处理不了数据
//例如我们循环队列长度是2048 但是len解析出来是4096 那么就会出现错误
//所以我们这里给buffer一个阀值
//如果这包协议中len的长度超出我们的这个值就将数据推出buffer
if (len > 500)
{
_circleBuf.popData();
continue;
}
if (_circleBuf.length() < len + 7)
{
break;
}
else
{
uint8_t *buf = new uint8_t[len + 7];
for (int i = 0; i < len + 7; i++)
{
//buf[i] = _circleBuf.popData();
buf[i] = _circleBuf[i];
}
int checkRcv = (buf[len + 5] << 8) | buf[len + 6];
int checkRes = checkData(&buf[5], len);
if (checkRcv != checkRes)
{
_circleBuf.popData();
log_info("Rcv an invalid packet\n");
}
else
{
for (int i = 0; i < len + 7; i++)
{
buf[i] = _circleBuf.popData();
}
uint8_t cmd = buf[2];
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (; it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
if (obj->getId() == cmd)
{
obj->handleRcvData(&buf[5], len);
}
}
}
}
delete [] buf;
}
}
else
{
//无效的头部信息
_circleBuf.popData();
}
}
}
协议发送数据
int ProtocolManager::sendData(uint8_t *buf, uint16_t len, uint8_t cmd)
{
if (buf)
{
uint16_t sum = 0;
uint16_t sendLen = 1 + 2 + 2 + len + 2; //查看协议文档
uint8_t *sendBuf = new uint8_t[sendLen];
sendBuf[0] = 0xAA;
sendBuf[1] = 0xFF;
sendBuf[2] = cmd;
sendBuf[3] = (len & 0xFF00)>>8;
sendBuf[4] = (len & 0xFF);
for (int i = 0; i < len; i++)
{
sendBuf[5+ i] = buf[i];
sum += buf[i];
}
sendBuf[5 + len] = (sum & 0xFF00)>>8;
sendBuf[5 + len + 1] = (sum & 0xFF);
#if 0
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete [] sendBuf;
#endif
#if USING_CMD_LIST
SendCmd *cmd = new SendCmd;
cmd->cmd = sendBuf;
cmd->len = sendLen;
_cmds.push_back(cmd);
#else
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete [] sendBuf;
#endif
return len;
}
return 0;
}
应用层的串口发送接口:
int ProtocolCommunicate::init()
{
MX_USART1_UART_Init();
ready();
ProtocolCommunicate::_instance = this;
HAL_UART_Receive_IT(&huart1, _comRcvBuf, 1);
return 0;
}
/*************************************************************
*Brief:发送数据,中断中不能调用此函数,否则发送数据会错乱
*Arguments:
*Returns:
*Author:xiaoyetongxue
*Date:2021
****************************************************************/
int ProtocolCommunicate::sendData(uint8_t *buf, uint16_t len)
{
if (buf)
{
HAL_UART_Transmit(&huart1, buf, len, 100);
//for (int i = 0; i < len; i++)
//{
//HAL_UART_Transmit(&huart1, &buf[i], 1, 100);
//HAL_Delay(1);
//波特率是115200 每次发送一个字节需要时间是69us
//cpu频率是24M每条指令大概是4ns 69*1000/4 = 170000
//这里等待每个字节发送完毕,延迟大概80us,如果使用HAL_Delay(1);
//1ms的时间对于系统来说太长了
// for (int j =0 ;j < 20000; j++)
// {
// }
//}
return len;
}
return -1;
}
***心电发送到主控芯片***
int ProtocolHeartBeat::deinit()
{
return 0;
}
int ProtocolHeartBeat::loopRun()
{
sendHeartBeat();
if (_timeOut)
{
//副cpu已经死机了要开始重启
}
return 0;
}
#if 1
void ProtocolHeartBeat::sendHeartBeat()
{
static int cnt = 0;
int tick = HAL_GetTick();
if (tick - cnt > 1000)
{
cnt = tick;
uint8_t buf[1] = { 0x00 };
sendData(buf, 0, PROTOCOL_ID_HEART_BEAT);
}
}
#endif
***血氧应用***
int SpO2::rcvData(uint8_t *buf, int len)
{
return SysProtocol->sendData(buf, len, PROTOCOL_ID_SPO2_RAW_DATA);
}