在双向图传的驱动代码中使用到了链表,在setup_fpga_dma函数中初始化了几个链表,如fpga.read_ready_q等。而后在初始化每个帧空间的时候,将此帧结构的链表fpga.read_frame[i].queue按顺序连接到fpga.read_ready_q中。
在接收中断中,首先判断fpga.read_ready_q是否为空,如果不空则从fpga.read_ready_q链表中找到fpga.read_ready_q.next(也即第一个fpga.read_frame[i].queue)相应的帧结构,并删除在fpga.read_ready_q中的此帧链表,再加入到fpga.read_work_q链表中。然后启动DMA传输。
在DMA完成的回调函数中,首先判断fpga.read_work_q是否为空,如果不空则从fpga.read_work_q链表中找到fpga.read_work_q.next(也即第一个fpga.read_frame[i].queue)相应的帧结构,并删除在fpga.read_work_q中的此帧链表,再加入到fpga.read_done_q链表中。然后启动tasklet。
在fpga_rx_task函数中,首先判断fpga.read_done_q是否为空,如果不空则从fpga.read_done_q链表中找到fpga.read_done_q.next(也即第一个fpga.read_frame[i].queue)相应的帧结构,并删除在fpga.read_done_q中的此帧链表,相应处理以后调用驱动的接收函数,最后再加入到fpga.read_ready_q链表中。
链表的概念较难理解,需反复思考。本驱动中涉及到基本链表有三个,可以理解发等待链表,工作链表,完成链表。我们把相应帧结构中的链表成员分别放到等待链表中,随着程序的流程,逐步转到工作链表,完成链表,最后又回归到等待链表。可以想像成几个FIFO等助理解。
阅读(2011) | 评论(0) | 转发(0) |