同步不同的消息

时间:2019-06-19 14:15:04

标签: c stm32 can-bus

我认为这是一个通用的软件范例问题,因此它与嵌入式软件关系不大。

我有3条在不同时间段收到的消息,这3条消息分别是 Odo,速度,gps。每个都有20ms,1sec和1sec的时间片。

我的问题是,只有当这三个文件都已被提取时,我如何才能同步并获得完整的消息。

我当前的方法是有三个循环队列,并放入三个布尔变量并检查它们是否全部同步,但是如果例如具有20毫秒时间片的odo被一遍又一遍地拉过,那是行不通的消息。

这是我在做什么:

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{

  HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxMessage, RxData);
  static bool t1 = 0, t2=0, t3 =0;

  if (RxMessage.StdId == 0x098)
  {
    insertCirQueue(&q_velocity, 0x098);
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
    t1=1;
  }
  else if (RxMessage.StdId == 0x309)
  {
    /* Rx message Error */
    insertCirQueue(&q_Odo, 0x309);
    t2=1;
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
  }
  else if (RxMessage.StdId == 0x3EB)
  {
    /* Rx message Error */
    insertCirQueue(&q_Gps, 0x3EB);
    t3=1;
    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
  }

  if (t1 && t2 && t3)
  {
    t2 = t3 = t1 = 0;
    isSynced = true;
  }
}

并在主循环中

 if (isSynced)
      {
        isSynced = false;

        int vel[8] = {0}, gps[8] = {0}, odo[8] = {0};
        int counter = 0;
        while (!isEmpty(&q_velocity))
        {
          if (deleteCirQueue(&q_velocity, &vel[counter++]) == -1)
              break;
        }

        counter = 0;
        while (!isEmpty(&q_Gps))
        {
          if(deleteCirQueue(&q_Gps, &gps[counter++]) == -1)
              break;
        }

        counter = 0;
        while (!isEmpty(&q_Odo))
        {

          if(deleteCirQueue(&q_Odo, &odo[counter++]) == -1)
             break;
        }

2 个答案:

答案 0 :(得分:1)

您创建一个位字段,并为每种接收到的消息类型设置一个位。

typedef enum
{
  RECEIVED_NONE = 0x00,
  RECEIVED_ODO  = 0x01,
  RECEIVED_VELO = 0x02,
  RECEIVED_GPS  = 0x04,
  RECEIVED_ALL  = RECEIVED_ODO | RECEIVED_VELO | RECEIVED_GPS,
} can_received_t;



can_received_t can_received = RECEIVED_NONE;

if(/* received odo */)
{
  can_received |= RECEIVED_ODO;
}

...

if(can_received == RECEIVED_ALL)
{
  can_received = RECEIVED_NONE;
  ...
}

不过,存储队列似乎很混乱。 CAN作为实时总线的正常过程是,您只保留最新的有效软件包,而丢弃其余的软件包。尤其是在处理传感器和控制功能时。

答案 1 :(得分:0)

您可以只使用每次收到的最后一个值。因此,您可能会收到里程表的大量更新,但是只有在收集到最后的gps /速度时才“锁存”它(选择一个同步)。如果要从定期且可预测地向您发送消息的系统中获取消息,那很容易。除了最终值(如果您想查看/使用趋势历史记录),您甚至都不需要队列。

如果您希望同步准确无误,则可以内插速度。对里程表执行与上述相同的操作,并在收集GPS后停止保存。收集2个速度值(在GPS收集之前和之后)。对速度进行插值(线性)以在GPS采集时生成速度值。然后报告出来。每次收集速度时,这都会生成一个同步且准确的值,但会因您的速度/ GPS收集时间戳之间的偏移而延迟。