Вот-вот. У меня примерно так же: while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(Tms - lastT > 499){ // throw out short messages twice per second
usart_transmit();
lastT = Tms;
}
proc_esw();
CAN_proc();
while((can_mesg = CAN_messagebuf_pop())){
DBG("got CAN message\n");
IWDG->KR = IWDG_REFRESH;
// run command for my or broadcast ID
if(can_mesg->ID == the_conf.CANIDin || can_mesg->ID == 0)
parseCANcommand(can_mesg);
if(flags.can_monitor){
uint8_t len = can_mesg->length;
printu(Tms);
usart_send(" #");
printuhex(can_mesg->ID);
for(uint8_t ctr = 0; ctr < len; ++ctr){
usart_putchar(' ');
printuhex(can_mesg->data[ctr]);
}
usart_putchar('\n');
}
}
char *str;
int g = usart_getline(&str);
if(g < 0) usart_send("USART IN buffer overflow!\n");
else if(g > 0) cmd_parser(str);
parsemodbus();
}
Удобно еще то, что многие вещи можно посредством DMA делать (правда, к сожалению, с CAN и USB так не прокатит, приходится или в прерываниях обрабатывать, или поллингом заниматься).
Зато прием/передача по USART - элементарно (особенно удобно, если в МК есть прерывание по приему символа '\n').