关于医疗器械的算法、协议开发(五)

监控芯片接收内容:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值