athros 有线网卡驱动的知识点 1

1. athr_gmac_init(void) 模块初始化:(工作队列部分)

 1)ATHR_MAC_INIT_WORK(mac, athr_gmac_tx_timeout_task);

    此处定义为: #define ATHR_MAC_INIT_WORK(m, f)INIT_WORK(&m->mac_tx_timeout, (void *)f) 

    工作队列(work queue)Linux kernel中将工作推后执行的一种机制。这种机制和BHTasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。

工作队列一般用来做滞后的工作,比如在中断里面要做很多事,但是比较耗时,这时就可以把耗时的工作放到工作队列。说白了就是系统延时调度的一个自定义函数。

1、定义struct work_struct irq_queue;

2、初始化INIT_WORK(&irq_queue,do_irq_queuework);

3、调用方法:schedule_work(&rq_queue);

注,调用完毕后系统会释放此函数,所以如果想再次执行的话,就再次调用schedule_work()即可。

另外,内核必须挂载文件系统才可以使用工作队列。我的理解是:工作队列也属于调度,如果内核挂了,他就不调度了,当然就不能用工作队列了


    下面我们来分析INIT_WORD();

#define INIT_WORK(_work, _func)\
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT();\
INIT_LIST_HEAD(&(_work)->entry);\
PREPARE_WORK((_work), (_func));\
} while (0)


 其中_work为结构体 work_struct

 struct work_struct {
atomic_long_t data;/*传递跟函数的参数*/
#define WORK_STRUCT_PENDING 0/* T if work item pending execution这个工作正在等待处理吗*/
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct list_head entry;        /*连接所有工作的链表,对工作进行调度,即把给定工作的处理函数提交给缺省的工作队列和工作者线程。工作者线程本质上是一个普通的内核线程,在默认情况下,每CPU均有一个类型为“events”的工作者线程,当调用schedule_work时,这个工作者线程会被唤醒去执行工作链表上的所有工作。 */
work_func_t func;   /*要执行的函数,func的参数是一个work_struct指针,指向的数据就是定义funcwork_struct*/
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};


下面回到我们自己的代码,继续分析:

这个函数是工作队列中,我们自己定义的,需要推后执行的函数。

static void
athr_gmac_tx_timeout_task(ATHR_MAC_TASK_ARG)/*func的参数(ATHR_MAC_TASK_ARG)是一个work_struct指针,指向的数据就是定funcwork_struct*/
{  
    ATHR_MAC_TASK_MAC(); /*利用container_of 从一个成员,来找到结构体的首地址,也就是mac结构体。       container_of:http://blog.csdn.net/yinkaizhong/article/details/4093795*/
    athr_gmac_trc(mac,"mac");


    if (mac->ops->check_dma_st)
       mac->ops->check_dma_st(mac,0);
}

INIT_WORK的处理函数 athr_gmac_tx_timeout_task(ATHR_MAC_TASK_ARG)是如何取得参数的呢?看下面

   #define PREPARE_WORK(_work, _func)\
do { \
(_work)->func = (_func);\
} while (0)

#define ATHR_MAC_TASK_MAC()                \
athr_gmac_t *mac = (athr_gmac_t *)\
container_of(ws, athr_gmac_t, mac_tx_timeout)

 func 的参数为结构体 struct work_struct(),此结构体正是INIT_WORK宏的第一个参数,然后通过调用container_of宏这个小技巧,

通过结构体中一个成员找到结构体的首地址(struct athr_gmac_t),func中所需要用的数据,就存在结构 athr_gmac_t中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值