如何写分层驱动(复杂的字符驱动)

*********如何写分层驱动(复杂的字符驱动)—-以lcd驱动为例**************

思路:复杂的驱动都是建立在简单的驱动的基础上,所以首先要知道内核简单字符设备驱动如何写1.如何简单驱动程序1.1 构造file_operations.open = drv_open.read = drv_read1.2 告诉内核有1.1这个结构,register_chrdev(主设备号,fop,name)上面可以被下面三句话代替分配cdev设置cdevcdev_add1.3 入口函数:调用1.2的注册函数1.4 出口函数:unregister_chrdev2.复杂设备驱动程序:1.简单驱动程序框架+分层第一层:和简单驱动程序框架类似,这里以fbmem.c为例2.1. 构造file_operationsopen/read/write2.2.register_chrdev2.3.入口/出口第二层:驱动层:硬件相关(具体驱动具体不同):三把斧3.1. 分配一个fb_info结构体: framebuffer_alloc3.2. 设置3.3. 注册: register_framebuffer: 实质:register_framebuffer做的事:设置registered_fb数组的值

3.4. 硬件相关的操作

****************************************************************************************

总体架构:

分析fbmem.cstatic const struct file_operations fb_fops = { // ——-2.1.owner =THIS_MODULE,.read =fb_read,.write =fb_write,.ioctl =fb_ioctl,.mmap =fb_mmap,.open =fb_open,.release =fb_release,};static int __initfbmem_init(void)// ——2.3{create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) // ———-2.2printk("unable to get major %d for fb devs\n", FB_MAJOR);fb_class = class_create(THIS_MODULE, "graphics"); // 注册设备类if (IS_ERR(fb_class)) {printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));fb_class = NULL;}return 0;}例子:具体分析:LCD驱动程序 // 要具体由app到内核到驱动分析才知道整个架构如何形成 假设:app: open("/dev/fb0", …) 主设备号: 29, 次设备号: 0————————————————————–kernel:fb_open// 第一层的通用代码作用:1.中转作用:判断参数和设置参数,成为子类的多态函数参数 2.提供通用的操作:如果子类没有覆盖调用该方法,则使用通用代码,实现多态int fbidx = iminor(inode); // 这个是register_framebuffer时候设置的,次设备号就是数组的下标struct fb_info *info = = registered_fb[0]; // 获取3.3驱动注册的结构体file->private_data = info;// 方法1:重新设置file的fop,设置成info里面提供的fop// 方法2:不重新设置file的fop,根据次设备号获取驱动设置的fop,调用驱动提供的函数if (info->fbops->fb_open) {res = info->fbops->fb_open(info,1);if (res)module_put(info->fbops->owner);}app: read()—————————————————————kernel:fb_readint fbidx = iminor(inode);struct fb_info *info = registered_fb[fbidx];// 同fb_openif (!info || ! info->screen_base)// 中转作用:参数合法性判断return -ENODEV;if (info->state != FBINFO_STATE_RUNNING)return -EPERM;if (info->fbops->fb_read)// 多态:子类有自己实现,那么用子类函数return info->fbops->fb_read(info, buf, count, ppos);// 如果子类没有覆盖掉该方法则用基类提供通用方法src = (u32 __iomem *) (info->screen_base + p);dst = buffer;*dst++ = fb_readl(src++);copy_to_user(buf, buffer, c) 附录:register_framebuffer分析intregister_framebuffer(struct fb_info *fb_info){int i;struct fb_event event;struct fb_videomode mode;if (num_registered_fb == FB_MAX)return -ENXIO;num_registered_fb++;// 1.算法:找到次设备号for (i = 0 ; i < FB_MAX; i++)if (!registered_fb[i])break;fb_info->node = i;// 2.建立设备节点fb_info->dev = device_create(fb_class, fb_info->device,//以该次设备号建立设备节点MKDEV(FB_MAJOR, i), "fb%d", i);//在app open的时候fb%d,就有次设备号就传递进来了// 驱动可以利用该次设备号if (IS_ERR(fb_info->dev)) {/* Not fatal */printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));fb_info->dev = NULL;} elsefb_init_device(fb_info);return 0;}忠于梦想 勇于实践

,走自己的路,让人家去说吧。

如何写分层驱动(复杂的字符驱动)

相关文章:

你感兴趣的文章:

标签云: