Oop 在串行通信堆栈c+中使用多态性+;

Oop 在串行通信堆栈c+中使用多态性+;,oop,polymorphism,embedded,message-queue,can-bus,Oop,Polymorphism,Embedded,Message Queue,Can Bus,我正在为STM32微控制器在mbed库之上编写一个定制的高层CAN串行通信协议 我已经定义了大约24条将在协议中使用的消息。一些消息是分段的(即3条单独的消息,可能按顺序出现,也可能不出现) 目前,我有一个大的switch语句,用于根据消息ID处理传入消息,它如下所示: switch (msgID){ case END_CHARGE_REPORT_1_MSG: return processEndChargeReportMsg(msgID); case END_CH

我正在为STM32微控制器在mbed库之上编写一个定制的高层CAN串行通信协议

我已经定义了大约24条将在协议中使用的消息。一些消息是分段的(即3条单独的消息,可能按顺序出现,也可能不出现)

目前,我有一个大的switch语句,用于根据消息ID处理传入消息,它如下所示:

switch (msgID){
    case END_CHARGE_REPORT_1_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REPORT_2_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REPORT_3_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REQUEST_MSG:
        return processEndChargeRequestMsg(msgID);

    case START_CHARGE_REPORT_1_MSG:
        return processStartChargeReportMsg(msgID);
    case START_CHARGE_REPORT_2_MSG:
        return processStartChargeReportMsg(msgID);
    case START_CHARGE_REPORT_3_MSG:
        return processStartChargeReportMsg(msgID);
myCANMessages *polymorphPointer

while(1){
 CANMessage = readCANMessage();

--> somehow assign this automagically to correct derivedObject type


polymorphPointer = &derivedObject;
polymorphPointer->process


}
然后,在每个处理函数中,我检查分段消息组中的所有消息是否已接收,解析/格式化消息数据,将该数据用作调用与接收到的消息对应的函数的参数

我觉得有一种更好/更干净/更快的方法可以利用多态性来实现这一点,但我似乎不知道如何做到这一点

我想要像这样的东西:

class myCANMessages{
    virtual process()
}

//Derived classes for each type of message group
class startChargeMessageGroup : public myCANMessages{
    CANMessage fullMsgGroup[3];
    process(){
          load CANMessage into fullMsgGroup
          if(allMessagesReceived)
                 parse(CANMessage)
                 take_action(decoded data from CANMessage)
    }
}

class endChargeMessageGroup : public myCANMessages{ ///etc...etc...
然后继续以如下结构处理传入的CAN消息(将索引保存到缓冲区中的相关CAN消息,在接收到所有CAN消息后对其进行解析,使用接收到的数据作为参数调用相应的函数):

switch (msgID){
    case END_CHARGE_REPORT_1_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REPORT_2_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REPORT_3_MSG:
        return processEndChargeReportMsg(msgID);
    case END_CHARGE_REQUEST_MSG:
        return processEndChargeRequestMsg(msgID);

    case START_CHARGE_REPORT_1_MSG:
        return processStartChargeReportMsg(msgID);
    case START_CHARGE_REPORT_2_MSG:
        return processStartChargeReportMsg(msgID);
    case START_CHARGE_REPORT_3_MSG:
        return processStartChargeReportMsg(msgID);
myCANMessages *polymorphPointer

while(1){
 CANMessage = readCANMessage();

--> somehow assign this automagically to correct derivedObject type


polymorphPointer = &derivedObject;
polymorphPointer->process


}
……但我还是不太明白。。。哦

您可以将“CAN消息”作为抽象基类,然后为每个唯一的CAN标识符继承它。但对我来说这听起来有点过分了

通常,我通过查找表来解决这些情况,查找表按照标识符排序。表中的每个项都包含一个受支持的标识符和一个函数指针。(本质上,这就是多态性将归结为什么。)

收到消息后,您可以在表中进行二进制搜索,查看是否支持该标识符。如果是,则调用该函数

基本上,这个伪代码:

CAN_msg msg = can_read();
const CAN_msg* supported = binary_search(table, msg.id);
if(supported) 
{
  supported->process();
}

始终检查大小(DLC)和RTR位是否与给定标识符的预期值匹配也是一个好主意。

我喜欢这种方法(快速和肮脏的多态性替代方法)。如何声明/填充查找表?我假设某种类型的typedef或struct包含键/值对,其中键是我的msgID int,值是一个void函数指针?@macdonaldtomw Yes,一个值对结构。函数指针可能应将CAN消息作为参数。