hw_c_rtos 发表于 2010-8-26 20:46:54

函数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中有很多链表操作,基本都看得懂,但看到此处,有点糊涂。

ffxz 发表于 2010-8-26 22:59:09

这个比较拗口些,下次写得简单些。

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传送。

hw_c_rtos 发表于 2010-8-27 07:21:36

谢谢ffxz,理解了。此链表并非环形链表,head、tail分别指向此链表的头和尾。
rt_serial_write()函数往此链表添加待发送数据节点,而rt_hw_serial_dma_tx_isr(rt_device_t device)中断服务中查询此链表,只要链表非空,就继续启动DMA发送数据

aaa1982 发表于 2010-8-29 21:30:24

不好意思,这个DMA模式的例子在哪里,我看到的sam7s的例子 rt_serial_write 没有DMA模式

在stm32 radio里面找到了,感谢
页: [1]
查看完整版本: 函数rt_serial_write()中代码帮忙解惑