В случае UART вы обращаетесь либо к тайм-ауту приема DMA, как вы сказали, либо (если не используется DMA) прерывание IDLE.Я не знаю, что такое происходит «из коробки» для USB CDC - вы должны реализовать это время самостоятельно, что не должно быть слишком сложным.Имейте таймер (аппаратное обеспечение программного обеспечения), который вы повторно запускаете каждый раз, когда вы получаете данные.Установите для его периода значение тайм-аута по вашему выбору и выполните синтаксический анализ протокола по истечении времени ожидания.
Если бы мне пришлось что-то добавить - такого рода проблемы (не зная, сколько байтов нужно получить), как правило, решаются в протоколе.уровень.Предполагая двоичный протокол, одним из способов достижения этого является наличие байтов начала и конца кадра, которые никогда не встречаются в данных (и если они это делают - вы избегаете их), и в этом случае вы получаете все, начиная с «начального байта», пока не получите «конечный байт»,Еще один способ состоит в том, чтобы иметь «стартовый байт» и поле, указывающее, сколько байтов нужно получить.Все это, конечно, должно быть проверено каким-то образом.
Сказав, что, если у вас есть возможность изменить протокол, вы действительно должны это сделать.Полагаясь на тайминги в вашем общении, особенно на таком низком уровне, только в долгосрочной перспективе возникают проблемы и головные боли.Вы вводите тесную связь между вашим уровнем протокола и уровнем интерфейса.Это будет иметь неприятные последствия для вас каждый раз, когда вы решите использовать другой интерфейс, так как вам придется заново изобретать ту же вещь.Не говоря уже о том, как больно будет, когда вы решите перейти на TCP / IP со всем его великолепием - дрожание сети, отбрасывание пакетов и т. Д.