I think it's a general software paradigm problem, so it's not related that much to embedded software.
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.
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.
Here is what I'm doing:
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;
}
}
and in the main loop
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;
}
See Question&Answers more detail:os