Chinaunix首页 | 论坛 | 博客
  • 博客访问: 203548
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 385
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-16 18:53
个人简介

只要心够决,没有什么不可以!!!

文章存档

2013年(35)

我的朋友

分类: 嵌入式

2013-09-10 20:22:58

注:在分析tiny6410adc驱动时遇到的

以下是网上的解释:

——————————————————————————————————————————————杂项设备(misc device)
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动。在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc device从设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号10 ,一起归于misc device,其实misc_register就是用主标号10调用register_chrdev()的。

也就是说,misc设备其实也就是特殊的字符设备,可自动生成设备节点。

 

字符设备(char device)

使用register_chrdev(LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱动程序时,如果有多个设 备使用该函数注册驱动程序,LED_MAJOR不能相同,否则几个设备都无法注册(我已验证)。如果模块使用该方式注册并且 LED_MAJOR为0(自动分配主设备号 ),使用insmod命令加载模块时会在终端显示分配的主设备号和次设备号,在/dev目录下建立该节点,比如 设备leds,如果加载该模块时分配的主设备号和次设备号为253和0,则建立节点:mknod leds c 253 0。使用register_chrdev (LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱动程序时都要手动建立节点 ,否则在应用程序无法打开该设备。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lanmanck/archive/2009/10/22/4713978.aspx

——————————————————————————————————————————————————————

问题一:为什么我使用的时候需要手动建立设备节点?

问题二:misc_register具体使用说明?

 

先解决问题二:

misc_register():

 

/linux-2.6.x/include/linux/miscdevice.h

 

struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *dev;
struct class_device *class;
};

extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice * misc);


Defined as a function in:
drivers/char/misc.c, line 201

 

 

 

201 int misc_register(struct miscdevice * misc)
202 {
203 struct miscdevice *c;
204 dev_t dev;
205 int err = 0;
206
207 down(&misc_sem);
208 list_for_each_entry(c, &misc_list, list) {
209 if (c->minor == misc->minor) {
210 up(&misc_sem);
211 return -EBUSY;
212 }
213 }
214
215 if (misc->minor == MISC_DYNAMIC_MINOR) {
216 int i = DYNAMIC_MINORS;
217 while (--i >= 0)
218 if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
219 break;
220 if (i<0) {
221 up(&misc_sem);
222 return -EBUSY;
223 }
224 misc->minor = i;
225 }
226
227 if (misc->minor < DYNAMIC_MINORS)
228 misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
229 dev = MKDEV(MISC_MAJOR, misc->minor);
230
231 misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
232 "%s", misc->name);
233 if (IS_ERR(misc->class)) {
234 err = PTR_ERR(misc->class);
235 goto out;
236 }
237
238 /*
239 * Add it to the front, so that later devices can "override"
240 * earlier defaults
241 */
242 list_add(&misc->list, &misc_list);
243 out:
244 up(&misc_sem);
245 return err;
246 }
247

248 /**
249 * misc_deregister - unregister a miscellaneous device
250 * @misc: device to unregister
251 *
252 * Unregister a miscellaneous device that was previously
253 * successfully registered with misc_register(). Success
254 * is indicated by a zero return, a negative errno code
255 * indicates an error.
256 */
257
258 int misc_deregister(struct miscdevice * misc)
259 {
260 int i = misc->minor;
261
262 if (list_empty(&misc->list))
263 return -EINVAL;
264
265 down(&misc_sem);
266 list_del(&misc->list);
267 class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
268 if (i < DYNAMIC_MINORS && i>0) {
269 misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
270 }
271 up(&misc_sem);
272 return 0;
273 }
274
275 EXPORT_SYMBOL(misc_register);
276 EXPORT_SYMBOL(misc_deregister);
277
278 static int __init misc_init(void)
279 {
280 #ifdef CONFIG_PROC_FS
281 struct proc_dir_entry *ent;
282
283 ent = create_proc_entry("misc", 0, NULL);
284 if (ent)
285 ent->proc_fops = &misc_proc_fops;
286 #endif
287 misc_class = class_create(THIS_MODULE, "misc");
288 if (IS_ERR(misc_class))
289 return PTR_ERR(misc_class);

 

290
291 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
292 printk("unable to get major %d for misc devices/n",
293 MISC_MAJOR);
294 class_destroy(misc_class);
295 return -EIO;
296 }
297 return 0;
298 }
299 subsys_initcall(misc_init);

 

 

不多说了,一目了然。不过好多东西还是不会,得注意。

 

阅读(1793) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~