Using the answer to your previous question from here, you can use that bitfield in combination with a plain uint8_t [64]
. For example
typedef struct
{
uint8_t data[64];
can_received_t received;
} msg_t;
Fill up with data as you receive it, writing it to the corresponding data bytes, then set the bit to indicate that the message has been partially received. The struct isn't regarded as complete until you have received all parts.
A queue/FIFO only fills one purpose, and that is to delay execution of something until later, when there's more time. There's no reason to do that here. Your CAN message decoding could look something like:
msg_t msg;
switch(received_can_id)
{
...
case CANID_FOO:
memcpy(&msg.data[FOO_INDEX], rec_data, FOO_SIZE);
msg.received |= RECEIVED_FOO;
break;
case CANID_BAR:
memcpy(&msg.data[BAR_INDEX], rec_data, BAR_SIZE);
msg.received |= RECEIVED_BAR;
break;
...
}
if(msg.received == RECEIVED_ALL)
{
use(&msg); // do something
memset(&msg, 0, sizeof msg); // reset everything
}
This is fairly quick code, no need to queue anything.