最近在一个项目中用到uart的使用问题,对阻塞和非阻塞有了硬件级的理解。
需求描述:该项目中AP侧使用uart和某个外设通讯。
通讯起始阶段,AP和外设的默认波特率均为115200,二者可以顺利通讯。
第二阶段,AP会发给外设一个请求,该请求要求外设切换到2000000的波特率。然后AP立刻修改自己的波特率为2000000
第三阶段,外设收到该请求,并将自身切换到2000000的波特率,并以该新的波特率发送一个ACK
第四阶段,AP收到上述ACK,双方完成速率更新
出现的问题:
在第二阶段,当AP发出要求外设更新速率的数据包后,AP立刻切换自身的波特率,这种情况下外设收到的该数据包是错误的。怀疑AP切换自身波特率的时机太早,可能当时uart总线上正在传输该数据包,此时切换必然导致正在传输的数据被破坏。因此在AP调用write(uart_fd,send_buffer,data_size); 后做sleep(1); 问题解决,外设可以收到正确的数据包。
考虑到我们在AP侧打开该uart接口时采用的是非阻塞模式:uart_fd = open("/dev/ttyS0", O_RDWR | O_NONBLOCK );因此出现上述问题也可以理解,即在非阻塞模式下write调用会立刻返回,所以在write后直接修改AP侧uart的波特率会破坏正在发送的数据。那么,在调用write之前,我们将其操作模式改为阻塞方式,问题不就解决了吗?因为在阻塞模式下,只有数据真正发送完毕write才会返回ÿ