You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
caseRT_SERIAL_EVENT_TX_DMADONE:
{
structrt_serial_tx_fifo*tx_fifo;
tx_fifo= (structrt_serial_tx_fifo*)serial->serial_tx;
RT_ASSERT(tx_fifo!=RT_NULL);
tx_fifo->activated=RT_FALSE;
/* Trigger the transmit completion callback */if (serial->parent.tx_complete!=RT_NULL)
serial->parent.tx_complete(&serial->parent, RT_NULL);
if (serial->parent.open_flag&RT_SERIAL_TX_BLOCKING)
{
rt_completion_done(&(tx_fifo->tx_cpt));
break;
}
rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size);
/* Get the length of the data from the ringbuffer. * If there is some data in tx_ringbuffer, * then call the transmit interface for transmission again */if (rt_ringbuffer_data_len(&tx_fifo->rb))
{
tx_fifo->activated=RT_TRUE;
rt_uint8_t*put_ptr=RT_NULL;
/* Get the linear length buffer from rinbuffer */tx_fifo->put_size=rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr);
/* Call the transmit interface for transmission again */serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
}
break;
}
caseRT_SERIAL_EVENT_TX_DMADONE:
{
structrt_serial_tx_fifo*tx_fifo;
tx_fifo= (structrt_serial_tx_fifo*)serial->serial_tx;
RT_ASSERT(tx_fifo!=RT_NULL);
tx_fifo->activated=RT_FALSE;
rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size);
/* Get the length of the data from the ringbuffer. * If there is some data in tx_ringbuffer, * then call the transmit interface for transmission again */if (rt_ringbuffer_data_len(&tx_fifo->rb))
{
tx_fifo->activated=RT_TRUE;
rt_uint8_t*put_ptr=RT_NULL;
/* Get the linear length buffer from rinbuffer */tx_fifo->put_size=rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr);
/* Call the transmit interface for transmission again */serial->ops->transmit(serial,
put_ptr,
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
}
else
{
/* Trigger the transmit completion callback */if (serial->parent.tx_complete!=RT_NULL)
serial->parent.tx_complete(&serial->parent, RT_NULL);
if (serial->parent.open_flag&RT_SERIAL_TX_BLOCKING)
{
rt_completion_done(&(tx_fifo->tx_cpt));
break;
}
}
break;
}
以上仅为个人的一个见解,作为讨论,如有错误,欢迎指正
The text was updated successfully, but these errors were encountered:
在
rt_hw_serial_isr
中的RT_SERIAL_EVENT_TX_DMADONE
分支逻辑如下:可以看到尾部加入了再次发送的逻辑,本意是在 ringbuffer 中的数据未发送完成的情况下继续发送。这个逻辑没有任何问题,但是传输完成回调却是进入该分支就会被调用。个人认为虽然这个分支是 DMA 发送完成逻辑,但是实际上驱动在某些情况下(如 ringbuffer 有效数据在 buffer 尾部不连续)会分包发送,这种情况严格意义上并不能称之为发送完成,只能叫做“部分完成”。
虽然在多数情况下这个也不是什么问题,但如果遇到一些需要严格判断数据发送完成的情况下,如 RS485 需要在所有数据发送完成后才能操作使能脚,就会出现问题,即数据发到一半就触发完成回调,并在回调中操作使能脚,此时数据实际才发送了一部分。
仅个人观点,这里的发送完成回调既然是通知应用层的,那就应该是应用层的数据完全发送完成后才被调用,而不是应用层数据传输到驱动层后被驱动分包,然后驱动层的一包发送完成后就调用。
个人在使用时进行了如下修改:
以上仅为个人的一个见解,作为讨论,如有错误,欢迎指正
The text was updated successfully, but these errors were encountered: