函数rt_serial_write()中代码帮忙解惑
以下为rt_serial_write()函数中的源代码:else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
{
/* DMA mode Tx */
/* allocate a data node */
struct stm32_serial_data_node* data_node = (struct stm32_serial_data_node*)
rt_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER);
if (data_node == RT_NULL)
{
/* set error code */
err_code = -RT_ENOMEM;
}
else
{
rt_uint32_t level;
/* fill data node */
data_node->data_ptr = ptr;
data_node->data_size = size;
/* insert to data link */
data_node->next = RT_NULL;
/* disable interrupt */
level = rt_hw_interrupt_disable();
data_node->prev = uart->dma_tx->list_tail;
if (uart->dma_tx->list_tail != RT_NULL)
uart->dma_tx->list_tail->next = data_node;
uart->dma_tx->list_tail = data_node;
if (uart->dma_tx->list_head == RT_NULL)
{
/* start DMA to transmit data */
uart->dma_tx->list_head = data_node;
/* Enable DMA Channel */
rt_serial_enable_dma(uart->dma_tx->dma_channel,
(rt_uint32_t)uart->dma_tx->list_head->data_ptr,
uart->dma_tx->list_head->data_size);
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
}
在DMA mode Tx 下,从内存池中分配一数据节点(data_node )内存块,并对数据节点初始化,但以下代码不解,请各位释疑
/* insert to data link */
data_node->next = RT_NULL;
/* disable interrupt */
level = rt_hw_interrupt_disable();
data_node->prev = uart->dma_tx->list_tail;
if (uart->dma_tx->list_tail != RT_NULL)
uart->dma_tx->list_tail->next = data_node;
uart->dma_tx->list_tail = data_node;
if (uart->dma_tx->list_head == RT_NULL)
{
/* start DMA to transmit data */
uart->dma_tx->list_head = data_node;
..............................................
..............................................
好像是将该数据节点插入发送链,可插入操作看不懂。RT-Thread中有很多链表操作,基本都看得懂,但看到此处,有点糊涂。 这个比较拗口些,下次写得简单些。
data_node->prev = uart->dma_tx->list_tail;
if (uart->dma_tx->list_tail != RT_NULL)
uart->dma_tx->list_tail->next = data_node;
uart->dma_tx->list_tail = data_node;
插入到链表的尾端。(每个数据节点是一个双向链表节点,head、tail指向头和尾,它们并不是一个环形链表)
if (uart->dma_tx->list_head == RT_NULL)
{
/* start DMA to transmit data */
uart->dma_tx->list_head = data_node;
插入完成后,如果头节点是空,说明插入的是第一个节点,
-> 对头节点进行赋值
-> 发起一次DMA传送。 谢谢ffxz,理解了。此链表并非环形链表,head、tail分别指向此链表的头和尾。
rt_serial_write()函数往此链表添加待发送数据节点,而rt_hw_serial_dma_tx_isr(rt_device_t device)中断服务中查询此链表,只要链表非空,就继续启动DMA发送数据 不好意思,这个DMA模式的例子在哪里,我看到的sam7s的例子 rt_serial_write 没有DMA模式
在stm32 radio里面找到了,感谢
页:
[1]