设备驱动模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/youhaibo1990/article/details/12525871
大笑

20131009

 /proc中是系统中的信息

/sys/class按功能化分,内核中的

/dev/是用户可用的

/sys/misc放杂货的类

题:

1.1==>灯亮;0==>灯灭;

app /dev/led  1

0

 

atoi:字符串转换为整数

2题:

自已写一个:从总线,设备,驱动三个文件。

注意:

两个文件(A,B)中的两个变量(a,b),如果A文件中要调用B文件中的变量b,

B文件中:struct bus_type person;

   EXPORT_SYMBOL(person);==>在内核中用这个

1

test.c

//在应用层,输入一个1,灯亮;输入一个0,灯灭;

#include <linux/init.h>

#include <linux/module.h>

#include <linux/io.h>

#include <linux/irq.h>

#include <linux/interrupt.h>

#include <linux/err.h>

#include <linux/device.h>

#include <linux/kdev_t.h>

#include <linux/types.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

int my_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg);

int my_open(struct inode *no, struct file *fp);

int my_release(struct inode *no, struct file *fp);

void led_on();

void led_off();

 

unsigned long led_virt;

unsigned long *gpmcon,*gpmdat;

 

struct miscdevice led;

struct file_operations ops;

 

int test_init()

{

ops.open = my_open;

ops.release = my_release;

ops.ioctl = my_ioctl;

 

led_virt = ioremap(0x7F008820,SZ_4K);

        gpmcon = led_virt+0x00;

        gpmdat = led_virt+0x04;

 

 

led.name = "led";

led.fops = &ops;

misc_register(&led);

 

return 0;

}

void test_exit()

{

printk("goodbye module\n");

misc_deregister(&led);

}

module_init(test_init);

module_exit(test_exit);

 

int my_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg)

{

 

printk("cmd is %d\n",cmd);

printk("cmd is %c\n",cmd);

if(cmd==1)

led_on();

if(cmd==0) 

led_off();

return 0;

}

 

int my_open(struct inode *no, struct file *fp)

{

printk("OPEN\n");

return 0;

}

 

int my_release(struct inode *no, struct file *fp)

{

return 0;

}

 

void led_on()

{

         *gpmcon = 1;

         *gpmdat = 0;

}

void led_off()

{

         *gpmcon = 1;

         *gpmdat = 1;

}

Makefile.c

default:

make -C /home/linux-2.6.28_smdk6410 M=`pwd`

clean:

make -C /home/linux-2.6.28_smdk6410 M=`pwd` clean

rm -rf modules.order

obj-m +=test.o

 

ioctl.c:

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

//./ioctl /dev/led 1

//                 0

int main(int argc,char *argv[])

{

 

printf("argv[2]:%d\n",argv[2]);

if(argc<3)

{

perror("/app <dev_name> <1/0>");

return 1;

}

int fd=open(argv[1],O_RDWR);

if(fd<0)

{

perror("open");

return 1;

}

printf("argv[2]:%d\n",argv[2]);

int cmd=atoi(argv[2]);

printf("argv[2]:%d\n",cmd);

int ret = ioctl(fd,cmd);

if(ret<0)

{

perror("ioctl");

return 1;

}

close(fd);

}

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

设备驱动模型:第一版:

bus.c/device.c/driver.c

bus.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

//#include <linux/types.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

int my_match(struct device *dev, struct device_driver *drv);

 

struct bus_type person;

EXPORT_SYMBOL(person);

 

int test_init()

{

person.name = "person";

person.match = my_match;

bus_register(&person);

return 0;

}

void test_exit()

{

bus_unregister(&person);

printk("exit module");

 

}

module_init(test_init);

module_exit(test_exit);

int my_match(struct device *dev, struct device_driver *drv){

if(!strcmp(dev->init_name,drv->name)){

printk("match ok\n");

return 1;

}

return 0;

}

 

device.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/io.h>

#include <linux/device.h>

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

extern struct bus_type person;//欺骗编译器:在其它文件中声明,这个文件中来用

struct device chunge;

 

int test_init()

{

 

chunge.init_name = "chunge";//名字命名为chungedevice_driver中的名字相同,在bus.c中我们来匹配设备与设备驱动

chunge.bus = &person;

device_register(&chunge);

return 0;

}

void test_exit()

{

device_unregister(&chunge);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

 

driver.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

struct device_driver chunge_drv;

extern struct bus_type person;

int test_init()

{

chunge_drv.name ="chunge";

chunge_drv.bus = &person;

 

driver_register(&chunge_drv);

return 0;

}

void test_exit()

{

driver_unregister(&chunge_drv);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

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

设备驱动模型:第二版:

bus.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

//#include <linux/types.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

int my_match(struct device *dev, struct device_driver *drv);

 

struct bus_type person;

EXPORT_SYMBOL(person);

 

int test_init()

{

person.name = "person";

person.match = my_match;

bus_register(&person);

return 0;

}

void test_exit()

{

bus_unregister(&person);

printk("exit module");

 

}

module_init(test_init);

module_exit(test_exit);

int my_match(struct device *dev, struct device_driver *drv){

if(!strcmp(dev->init_name,drv->name)){

printk("match ok\n");

return 1;

}

return 0;

}

 

device.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/io.h>

#include <linux/device.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

struct person_device{

struct device dev;

};

 

extern struct bus_type person;//欺骗编译器:在其它文件中声明,这个文件中来用

struct person_device chunge;

 

int person_device_register(struct person_device *pdev);

void  person_device_unregister(struct person_device *pdev);

 

int test_init()

{

 

chunge.dev.init_name = "chunge";//名字命名为chungedevice_driver中的名字相同,在bus.c中我们来匹配设备与设备驱动

chunge.dev.bus = &person;

 

person_device_register(&chunge);

return 0;

}

void test_exit()

{

person_device_unregister(&chunge);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

 

int person_device_register(struct person_device *pdev)

{

return device_register(&pdev->dev);

}

void  person_device_unregister(struct person_device *pdev)

{

device_unregister(&pdev->dev);

}

 

driver.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

struct person_device_driver{

 

struct device_driver dev_drv;

};

struct person_device_driver chunge_drv;

extern struct bus_type person;

 

int person_driver_register(struct person_device_driver *pdri);

void person_driver_unregister(struct person_device_driver *pdri);

int test_init()

{

chunge_drv.dev_drv.name ="chunge";

chunge_drv.dev_drv.bus = &person;

 

person_driver_register(&chunge_drv);

return 0;

}

void test_exit()

{

person_driver_unregister(&chunge_drv);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

int person_driver_register(struct person_device_driver *pdri)

{

return driver_register(&pdri->dev_drv);

}

void person_driver_unregister(struct person_device_driver *pdri)

{

driver_unregister(&pdri->dev_drv);

}

 

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

设备驱动模型:第三版:

 

bus.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

#include "bus.h"

//#include <linux/types.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

int my_match(struct device *dev, struct device_driver *drv);

 

struct bus_type person;

EXPORT_SYMBOL(person);

 

int test_init()

{

person.name = "person";

person.match = my_match;

bus_register(&person);

return 0;

}

void test_exit()

{

bus_unregister(&person);

printk("exit module");

 

}

module_init(test_init);

module_exit(test_exit);

int my_match(struct device *dev, struct device_driver *drv){

if(!strcmp(dev->init_name,drv->name)){

printk("match ok\n");

return 1;

}

return 0;

}

//device.c

EXPORT_SYMBOL(person_device_register);

int person_device_register(struct person_device *pdev)

{

return device_register(&pdev->dev);

}

EXPORT_SYMBOL(person_device_unregister);

void  person_device_unregister(struct person_device *pdev)

{

device_unregister(&pdev->dev);

}

//driver.c

 

EXPORT_SYMBOL(person_driver_register);

int person_driver_register(struct person_device_driver *pdri)

{

return driver_register(&pdri->dev_drv);

}

EXPORT_SYMBOL(person_driver_unregister);

void person_driver_unregister(struct person_device_driver *pdri)

{

driver_unregister(&pdri->dev_drv);

}

 

 

bus.h:

struct person_device{

struct device dev;

};

int person_device_register(struct person_device *pdev);

void  person_device_unregister(struct person_device *pdev);

 

 

struct person_device_driver{

struct device_driver dev_drv;

};

int person_driver_register(struct person_device_driver *pdri);

void person_driver_unregister(struct person_device_driver *pdri);

 

int my_match(struct device *dev, struct device_driver *drv);

 

 

 

device.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/io.h>

#include <linux/device.h>

#include "../bus/bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

//struct person_device{

// struct device dev;

//};

//

extern struct bus_type person;//欺骗编译器:在其它文件中声明,这个文件中来用

struct person_device chunge;

//

//int person_device_register(struct person_device *pdev);

//void  person_device_unregister(struct person_device *pdev);

 

int test_init()

{

 

chunge.dev.init_name = "chunge";//名字命名为chungedevice_driver中的名字相同,在bus.c中我们来匹配设备与设备驱动

chunge.dev.bus = &person;

 

person_device_register(&chunge);

return 0;

}

void test_exit()

{

person_device_unregister(&chunge);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

 

//int person_device_register(struct person_device *pdev)

//{

// return device_register(&pdev->dev);

//}

//void  person_device_unregister(struct person_device *pdev)

//{

// device_unregister(&pdev->dev);

//}

 

 

driver.c:

 

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

#include "../bus/bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

//struct person_device_driver{

//

// struct device_driver dev_drv;

//};

struct person_device_driver chunge_drv;

extern struct bus_type person;

//

//int person_driver_register(struct person_device_driver *pdri);

//void person_driver_unregister(struct person_device_driver *pdri);

int test_init()

{

chunge_drv.dev_drv.name ="chunge";

chunge_drv.dev_drv.bus = &person;

 

person_driver_register(&chunge_drv);

return 0;

}

void test_exit()

{

person_driver_unregister(&chunge_drv);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

//int person_driver_register(struct person_device_driver *pdri)

//{

// return driver_register(&pdri->dev_drv);

//}

//void person_driver_unregister(struct person_device_driver *pdri)

//{

// driver_unregister(&pdri->dev_drv);

//}

 

 

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

设备驱动模型:第四版:

bus.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

#include "bus.h"

//#include <linux/types.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

int my_match(struct device *dev, struct device_driver *drv);

 

struct bus_type person;

EXPORT_SYMBOL(person);

 

int test_init()

{

person.name = "person";

person.match = my_match;

bus_register(&person);

return 0;

}

void test_exit()

{

bus_unregister(&person);

printk("exit module");

 

}

module_init(test_init);

module_exit(test_exit);

int my_match(struct device *dev, struct device_driver *drv){

//if(!strcmp(dev->init_name,drv->name)){

// printk("match ok\n");

// return 1;

//}

struct person_device *pdev = container_of(dev,struct person_device,dev);

struct person_device_driver *pdrv = container_of(drv,struct person_device_driver,dev_drv);

if((pdev->pid==pdrv->pid)&&(pdev->vid==pdrv->vid))

{

printk("match ok\n");

return 1;

}

return 0;

}

//device.c

EXPORT_SYMBOL(person_device_register);

int person_device_register(struct person_device *pdev)

{

pdev->dev.bus = &person;

return device_register(&pdev->dev);

}

EXPORT_SYMBOL(person_device_unregister);

void  person_device_unregister(struct person_device *pdev)

{

device_unregister(&pdev->dev);

}

//driver.c

 

EXPORT_SYMBOL(person_driver_register);

int person_driver_register(struct person_device_driver *pdri)

{

pdri->dev_drv.bus = &person;

return driver_register(&pdri->dev_drv);

}

EXPORT_SYMBOL(person_driver_unregister);

void person_driver_unregister(struct person_device_driver *pdri)

{

driver_unregister(&pdri->dev_drv);

}

 

 

bus.h:

 

 

struct person_device{

struct device dev;

unsigned int vid,pid;

};

int person_device_register(struct person_device *pdev);

void  person_device_unregister(struct person_device *pdev);

 

 

struct person_device_driver{

struct device_driver dev_drv;

unsigned int vid,pid;

};

int person_driver_register(struct person_device_driver *pdri);

void person_driver_unregister(struct person_device_driver *pdri);

 

int my_match(struct device *dev, struct device_driver *drv);

 

 

device.c:

 

#include <linux/init.h>

#include <linux/module.h>

#include <linux/io.h>

#include <linux/device.h>

#include "../bus/bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

//struct person_device{

// struct device dev;

//};

//

extern struct bus_type person;//欺骗编译器:在其它文件中声明,这个文件中来用

struct person_device chunge;

//

//int person_device_register(struct person_device *pdev);

//void  person_device_unregister(struct person_device *pdev);

 

int test_init()

{

 

chunge.dev.init_name = "chunge";//名字命名为chungedevice_driver中的名字相同,在bus.c中我们来匹配设备与设备驱动

// chunge.dev.bus = &person;

chunge.vid = 0x1234;

chunge.pid = 0x5678;

 

person_device_register(&chunge);

return 0;

}

void test_exit()

{

person_device_unregister(&chunge);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

 

//int person_device_register(struct person_device *pdev)

//{

// return device_register(&pdev->dev);

//}

//void  person_device_unregister(struct person_device *pdev)

//{

// device_unregister(&pdev->dev);

//}

 

 

driver.c:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/device.h>

#include "../bus/bus.h"

MODULE_LICENSE("GPL");

MODULE_AUTHOR("you");

 

//struct person_device_driver{

//

// struct device_driver dev_drv;

//};

struct person_device_driver chunge_drv;

extern struct bus_type person;

//

//int person_driver_register(struct person_device_driver *pdri);

//void person_driver_unregister(struct person_device_driver *pdri);

int test_init()

{

chunge_drv.dev_drv.name ="chunge";

//chunge_drv.dev_drv.bus = &person;

chunge_drv.vid = 0x1234;

chunge_drv.pid = 0x5678;

 

person_driver_register(&chunge_drv);

return 0;

}

void test_exit()

{

person_driver_unregister(&chunge_drv);

printk("exit module\n");

}

module_init(test_init);

module_exit(test_exit);

//int person_driver_register(struct person_device_driver *pdri)

//{

// return driver_register(&pdri->dev_drv);

//}

//void person_driver_unregister(struct person_device_driver *pdri)

//{

// driver_unregister(&pdri->dev_drv);

//}

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页