同步不同的消息 [英] Synchronizing different messages

查看:90
本文介绍了同步不同的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这是一个通用的软件范式问题,所以它与嵌入式软件没有太大关系.

I think it's a general software paradigm problem, so it's not related that much to embedded software.

我在不同的时间段收到了 3 条消息,这三条消息是Odo,速度,GPS.每个都有 20 毫秒、1 秒和 1 秒的时间片.

I have 3 Messages that I get at different time slices, the three messages are Odo, velocity, gps. each one has timeslice 20ms, 1sec, and 1sec.

我的问题是只有当这三个消息都已被获取时,我将如何同步并获得完整的消息.

My problem is how would I sync and get a complete message only when the three are already fetched.

我目前的方法是拥有三个循环队列,并放置三个布尔变量并检查它们是否全部同步,但是如果例如具有 20 毫秒时间片的 odo 被一遍又一遍地拉动而没有另一个,那这将不起作用消息.

My current approach is to have three circural queues, and put three boolean variables and check if they are all in sync, but that doesn't work if for example odo which has timeslice 20ms, is pulled over and over without the other messages.

这是我正在做的:

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

推荐答案

您创建一个位域,并为每个接收到的消息类型设置一个位.

You create a bit-field, and set a bit per received message type.

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 的正常程序是您只保留最新的有效包并丢弃其余的包.特别是在处理传感器和控制功能时.

Storing queues seem fishy though. The normal procedure for CAN, being a real-time bus, is that you only keep the latest valid package and discard the rest. Particularly when dealing with sensors and control functions.

这篇关于同步不同的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆