创建一个hello的设备来举例应用层如何调用kernel驱动,kernel驱动部分为转载,仅对部分语句做解释。
init函数
Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。
内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
创建"hello_class"以及"hello"设备,这两个设备分别挂载在如下路径:
/sys/class/hello_class
/dev/hello
/* 5. kernel启动时initcall(module_init)会调用这个入口函数 */
static int __init hello_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);major = register_chrdev(0, "hello", &hello_drv); /* /dev/hello *//* 7. 其他完善:提供设备信息,自动创建设备节点 */hello_class = class_create(THIS_MODULE, "hello_class");err = PTR_ERR(hello_class);if (IS_ERR(hello_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "hello");return -1;} device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"); /* /dev/hello */return 0;
}/* 指定驱动的入口和出口,以及声明自己的驱动遵循GPL协议(不声明的话无法把驱动加载进内核) */
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");将驱动编译进kernel内核后,我们来写一个app打开该设备,调用设备驱动的接口。
注意一下open函数的设备名称为:"/dev/hello"
#include
#include
#include
#include
#include
#include static char databuf[1024];
static char writebuf[1024];int main(int argc,char *argv[])
{int fd;int ret;fd = open("/dev/hello", O_RDWR);if(fd < 0){printf("open fail! \n");printf("error number: %d \n",fd);return -1;}memset(databuf,0x0,1024);ret = read(fd, databuf, sizeof(databuf));memset(writebuf,0x0,1024);ret = write(fd, writebuf, sizeof(writebuf));printf("write over \n");
}
上一篇:我的网站需要什么SSL证书?
下一篇:Flink(Java版)学习