softwind 发表于 2010-3-26 11:54:46

RT-Thread STM32 分支 串口DMA方式发送

请问有同学用过吗?下面这段代码有点儿不明白,
void rt_hw_serial_dma_tx_isr(rt_device_t device)
{
#ifdef RT_USING_HEAP
        rt_uint32_t level;
        struct stm32_serial_data_node* data_node;
        struct stm32_serial_device* uart = (struct stm32_serial_device*) device->private;

        /* DMA mode receive */
        RT_ASSERT(device->flag & RT_DEVICE_FLAG_DMA_TX);

        /* get the first data node */
        data_node = uart->dma_tx->list_head;
        RT_ASSERT(data_node != RT_NULL);

        /* invoke call to notify tx complete */
        if (device->tx_complete != RT_NULL)
                device->tx_complete(device, data_node->data_ptr);

        /* disable interrupt */
        level = rt_hw_interrupt_disable();

        /* remove list tail */
        uart->dma_tx->list_tail = data_node->prev;
        if (uart->dma_tx->list_tail == RT_NULL)
           uart->dma_tx->list_head = RT_NULL;

        /* enable interrupt */
        rt_hw_interrupt_enable(level);

        /* free data node memory(!!) */
        rt_free(data_node);

        if (uart->dma_tx->list_tail != RT_NULL)
        {
                /* transmit next data node */
                rt_serial_enable_dma(uart->dma_tx->dma_channel,
                        (rt_uint32_t)uart->dma_tx->list_tail->data_ptr,
                        uart->dma_tx->list_tail->data_size);
        }
        else
        {
                /* no data to be transmitted, disable DMA */
                DMA_Cmd(uart->dma_tx->dma_channel, DISABLE);
        }
#endif
}
当前节点data_node = uart->dma_tx->list_head(头节点)的数据发送完成,不是应该移除头节点吗?为什么是
/*remove list tail*/
uart->dma_tx->list_tail = data_node->prev呢?

另外,感觉这段代码中所有的list_tail似乎应该是list_head才对呀。
请高手赐教,谢谢。

ffxz 发表于 2010-3-26 12:06:32

head指向头、tail指向尾

device_write时,是把数据节点放到head上;而发送时,则是从tail上做发送。

所以发送完成会把tail节点拿掉(因为它已经发送成功)。

softwind 发表于 2010-3-26 12:13:47

嗯,谢谢。不过rt_serial_write()中有段代码
......
                        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);
                }
......
感觉是链接到tail上的呀?

ffxz 发表于 2010-3-26 13:03:42

好像确实是的。

串口这块代码一直没得到好好测试,DMA也用得少,好像除了这个上次还有个什么问题遗留在里面的。一直想对STM32的串口弄个比较好的解决方法,但依然不容易找出来。这个是当时讨论时的一些帖子:
http://www.rt-thread.org/phpbb/viewtopic.php?f=2&t=446

softwind 发表于 2010-3-26 13:10:45

嗯,谢谢ffxz。我再看看。
页: [1]
查看完整版本: RT-Thread STM32 分支 串口DMA方式发送