全部博文(685)
分类: LINUX
2014-08-21 11:28:28
以下是网上的解释:
——————————————————————————————————————————————杂项设备(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);
不多说了,一目了然。不过好多东西还是不会,得注意。