I'm reluctant to accept that a 9600 baud data flow should overwhelm an Uno - and wonder if an approach like the one shown below (where the requirement for synchronicity between receipt of data and processing is removed) might allow doing the job on a single Uno...
/*----------------------------------------------------------------------------*/
/* Assumptions: */
/* 1. get_packets() can get serial data and store it into a local buffer */
/* faster than it arrives. */
/* 2. proc() can process a message in less time than it takes to fill and */
/* overrun the serial data source's buffer. */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* get_packets() */
/* This function dequeues an empty buffer, fills it with data, and adds it to */
/* the full buffer queue for processing. If, at any time, it cannot proceed */
/* (either because all buffers have been filled or because there is no input */
/* data available), it calls proc() to process one buffer of queued data and */
/* retries whatever it could not do. */
/*----------------------------------------------------------------------------*/
void get_packets(void)
{ element *b;
unsigned char n,*p;
for (;;)
{ while (!(b = dequeue(emty))) proc();
for (;;)
{ do
{ while (!cam.available()) proc();
} while (0x0A != cam.read());
while (!cam.available()) proc();
if (8 < (n = cam.read())) continue;
*(p = b->data) = n;
for (n*=5; n--;)
{ while (!cam.available()) proc();
*++p = cam.read();
}
while (!cam.available()) proc();
if (0xFF == cam.read()) break;
}
enqueue(full,b);
}
}
/*----------------------------------------------------------------------------*/
/* proc() */
/* If there is data waiting in the full buffer queue, this function dequeues */
/* and processes it, then adds the buffer to the empty buffer queue to be */
/* refilled. If there is no data awaiting processing, it simply returns. */
/*----------------------------------------------------------------------------*/
void proc(void)
{ element *b;
unsigned char n;
if (b = dequeue(full))
{ if (n = *(p = b->data))
{ ++p;
/* Process n sets of data (n*5 bytes) at p */
}
enqueue(empt,b);
}
}