Linux Device Driver 3 实验代码修改,
为了让LDD3的示例代码适应新的2.6.32内核,进行了相应的修改
Chp 7 时间、延迟及延缓操作 实验代码
1. 共享队列 示例
编译 jiq.c时出现error。
原因是因为 宏定义INIT_WORK() 在 2.6.10的<linux/workqueue.h>中定义为:
#define INIT_WORK(_work, _func, _data)
而在2.6.32中的定义为:
INIT_WORK(_work, _func)
参数个数从3个变为了2个。
而 结构体 work_struct 的定义在2.6.10中为:
struct work_struct {
unsigned long pending;
struct list_head entry;
void (*func)(void *);
void *data;
void *wq_data;
struct timer_list timer;
};
在2.6.32中的定义为:
atomic_long_t data;
struct list_head entry;
work_func_t func;
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
关键在于func的定义改变了:typedef void (*work_func_t)(struct work_struct *work);
函数指针只能传递 struct work_struct * 类型的参数,而不是2.6.10那样的 void * 随便传参。
现在就要想办法将 jiq_data这个参数传进去。
修改方法:利用container_of()
将原先的:
static struct work_struct jiq_work;
改为:
typedef struct jiq_struct {
struct work_struct jiq_work;
struct clientdata *data;
};
这里定义了一个新的结构体 jiq_struct 用于关联 struct work_struct 类型的 jiq_work 和 jiq_data
然后在需要使用 jiq_data 的函数 static void jiq_print_wq(struct work_struct *work) 中开始的部分添加如下代码:
struct jiq_struct *p = container_of(work, struct jiq_struct, jiq_work);
struct clientdata *data = p->data;
void *ptr = (void *)(data);
就可以使用之前的其余代码部分了。
这里注意:
typedef struct jiq_struct {
struct work_struct jiq_work;
struct clientdata *data;
};
中的 jiq_work 成员一定是一个结构体,不能是指针。
原因在于container_of()的解释,不信可以自己试试,看看系统会不会崩溃 ;-)(高手勿喷)
今天调了好长时间,就是应为这个问题,系统Down了N多次。
此方法已经调试通过。