É difícil dizer exatamente o que causa isso. Infelizmente, as portas seriais do Linux não oferecem garantias de tempo, e os protocolos UART normais não devem ter requisitos de tempo apertados como este. Se o seu protocolo exigir esse tipo de garantia de tempo, você terá que acessar seus drivers de kernel e talvez escrever seu próprio driver que garanta a entrega atômica de todos os bytes sem intervalos, provavelmente usando interrupções para garantir que o buffer UART seja sempre recarregado em tempo hábil. Você não pode obter esse tipo de garantia do userspace sem a ajuda do kernel.
Dito isto, você pode tentar descobrir o que causa sua divisão e, talvez, trabalhar em torno dela e determinar empiricamente que ela é confiável o suficiente na prática para trabalhar com seus propósitos. O atraso é sempre antes do último byte? Em caso afirmativo, parece que algo na pilha está armazenando um caractere em buffer por algum motivo, talvez para otimizar o throughput fornecendo vários bytes para o hardware de uma só vez e apenas fornecendo o byte solitário após um pequeno tempo limite. Você deve primeiro certificar-se de que seu aplicativo de espaço do usuário está se comportando corretamente: verifique as chamadas do sistema executando-as em
strace
e verifique se o pacote está gravado no kernel em uma única chamada de sistema
write
. Se estiver, é hora de ler a fonte do kernel para o seu driver UART e ver se há algum buffer estranho envolvido.
Outra possibilidade é que o driver do kernel simplesmente lide com os dados em um encadeamento do kernel (ou diretamente em seu contexto de processo), e as lacunas que você está vendo são outro processo sendo agendado. Se assim for, a única maneira de contornar isso é modificar o driver do kernel ou escrever o seu próprio, para que ele manipule a transmissão de forma estrita em tempo real, sem permitir que outros processos tenham prioridade (por exemplo, fazendo tudo em contexto de interrupção).