IMO лучший подход - реализовать циклический буфер, использовать функции, которые вам нравятся, чтобы прочитать 1 байт из места потока в буфере, а затем вызвать функцию обратного вызова приема - или просто опросить циклический буфер на наличие данных.
Это решит все ваши проблемы - вы будете уведомлены (или вы можете опросить наличие данных), когда данные поступят, и не будут перезаписывать буфер (конечно, вам нужно прочитать данные в противном случае, если буфер заполнен) вы будете игнорировать новые данные)
Здесь у вас очень простая реализация
unsigned char buff[128];
struct
{
unsigned head:8;
unsigned tail:8;
}control = {.head = 0, .tail = 0};
int isFull(void)
{
return (control.head + 1) == control.tail;
}
int isEmpty()
{
return control.head == control.tail;
}
int push(int ch)
{
if(!isFull())
{
buff[control.head++] = ch;
return 0;
}
return -1;
}
int pop(void)
{
if(!isEmpty())
{
return buff[control.tail++];
}
return -1;
}
И простое использование
void (*rcvcallback)(void);
initReceive(void (*callback)(void))
{
rcvcallback = callback;
}
void receive(void)
{
int r = 0;
#ifdef LINUX
read(fd, &r, 1);
#endif
#ifdef WINDOWS
size_t size;
ReadFile(handle, &r, 1, &size, NULL);
#endif
push(r);
rcvcallback();
}
#ifdef WINDOWS
#define EL "\n\r"
#endif
#ifdef LINUX
#define EL "\n"
#endif
void myRCVcallback(void)
{
printf("Byte received: %d"EL, pop());
}
int main()
{
printf("Starting ......"EL);
while(1)
{
receive();
}
return 0;
}