How to write a layered drive (complex character driver)----LCD Driver as an example

Source: Internet
Author: User

How to write a layered drive (complex character driver)----LCD drive as an example **************


Idea: Complex drivers are built on the basis of simple drives, so first know how the kernel simple character device driver writes
1. How to simply drive a program
1.1 Construction File_operations
. open = Drv_open
. Read = Drv_read
1.2 Tell the kernel there are 1.1 this structure, Register_chrdev (main device number, fop,name)
The above can be replaced by the following three words
assigning Cdev
Set Cdev
Cdev_add
1.3 Entry function: Call 1.2 's registration function
1.4 Exit Function: Unregister_chrdev
2. Complex device drivers: 1. Simple Driver Framework + tiering
The first layer: similar to the simple driver framework, where FBMEM.C is the example
2.1. Construction File_operations
Open/read/write
2.2.register_chrdev
2.3. Inlet/outlet
Second layer: drive layer: Hardware related (Specific drive specific): three axes
3.1. Assigning a fb_info structure: framebuffer_alloc
3.2. Settings
3.3. Registration: Register_framebuffer: Essence: Register_framebuffer: Set the value of the REGISTERED_FB array

3.4. Hardware-related operations


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

Overall architecture:



Analysis FBMEM.C
static 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 __init
Fbmem_init (void)------2.3
{
Create_proc_read_entry ("FB", 0, NULL, FBMEM_READ_PROC, NULL);


if (Register_chrdev (Fb_major, "FB", &fb_fops))//----------2.2
PRINTK ("Unable to get major%d for FB devs\n", fb_major);


Fb_class = Class_create (This_module, "graphics"); Registering Device classes
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;
}

Example: Specific analysis: LCD driver//To be specific from app to kernel to drive analysis to know how the entire architecture is formed

Assume:
App:open ("/dev/fb0", ...) Main device number: 29, secondary device number: 0
--------------------------------------------------------------
Kernel
Fb_open The first layer of the General Code effect: 1. Transfer function: Judge the parameters and set the parameters, become the polymorphic function parameters of the subclass 2. Provides a common operation: if the subclass does not overwrite calls to the method, use common code to implement polymorphic
int fbidx = Iminor (inode); This is the Register_framebuffer time set, the second device number is the subscript of the array
struct Fb_info *info = = Registered_fb[0]; Get the 3.3-drive registered structure
File->private_data = info;Method 1: Re-set the file's FOP, set to the FOP provided in info
Method 2: Do not reset the file fop, according to the secondary device number to obtain the driver settings of the FOP, call the driver-provided function
if (Info->fbops->fb_open) {
res = Info->fbops->fb_open (info,1);
if (res)
Module_put (Info->fbops->owner);
}


App:read ()
---------------------------------------------------------------
Kernel
Fb_read
int fbidx = Iminor (inode);
struct Fb_info *info = Registered_fb[fbidx];With Fb_open

if (!info | |! info->screen_base)Relay function: The judgment of parameter legality
Return-enodev;


if (info->state! = fbinfo_state_running)
Return-eperm;



if (Info->fbops->fb_read)Polymorphic: Subclasses have their own implementations, then use the subclass function
return Info->fbops->fb_read (info, buf, count, PPOs);

Provides a generic method for a base class if the subclass does not overwrite the method
src = (u32 __iomem *) (info->screen_base + p);
DST = buffer;
*dst++ = Fb_readl (src++);
Copy_to_user (buf, buffer, c)



Appendix: Register_framebuffer Analysis
Int
Register_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. Algorithm: Find the secondary device number
for (i = 0; i < Fb_max; i++)
if (!registered_fb[i])
Break
Fb_info->node = i;


2. Set up the device node
Fb_info->dev = Device_create (Fb_class, Fb_info->device,Establish the device node with the secondary device number
MKDEV (Fb_major, i), "fb%d", I);//In the app open fb%d, there is a second device number is passed in
//Drive can take advantage of this secondary device number
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;
} else
Fb_init_device (Fb_info);




return 0;
}



Be faithful to your dreams and practice

How to write a layered drive (complex character driver)----LCD Driver as an example

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.