linux内核字符驱动程序,Linux内核学习-字符设备驱动学习(二)

在Linux内核学习-字符设备驱动学习(一)中编写字符设备驱动的一种方法,但是需要手动创建设备节点。

有没有能够自动的创建设备节点的呢?

有!使用class_create()和device_create()函数可以自动创建节点。

class_create : 创建class

class_destroy : 销毁class

class_device_create : 创建device

class_device_destroy : 销毁device

class_create()

-------------------------------------------------

linux-2.6.22/include/linux/device.h

struct class *class_create(struct module *owner, const char *name)

class_create - create a struct class structure

@owner: pointer to the module that is to "own" this struct class

@name: pointer to a string for the name of this class.

在/sys/class/下创建类目录

class_device_create()

-------------------------------------------------

linux-2.6.22/include/linux/device.h

struct class_device *class_device_create(struct class *cls,

struct class_device *parent,

dev_t devt,

struct device *device,

const char *fmt, ...)

class_device_create - creates a class device and registers it with sysfs

@cls: pointer to the struct class that this device should be registered to.

@parent: pointer to the parent struct class_device of this new device, if any.

@devt: the dev_t for the char device to be added.

@device: a pointer to a struct device that is assiociated with this class device.

@fmt: string for the class device's name

在驱动模块初始化函数中实现设备节点的自动创建

设备驱动文件char01.c

#include

#include

#include

#include

#include

#include

/

intchar01_open(structinode *inode,structfile *filp)

{

printk("char01 open!/n");

return0;

}

intchar01_release(structinode *inode,structfile *filp)

{

printk("char01 release!/n");

return0;

}

ssize_t char01_read(structfile *filp,char*buf,

size_tcount, loff_t *fpos)

{

printk("char01 read!/n");

return0;

}

ssize_t char01_write(structfile *filp,constchar*buf,

size_tcount, loff_t *fpos)

{

printk("char01 write!/n");

return0;

}

intchar01_ioctl(structinode *inode,structfile *filp,

unsignedintcmd, unsignedlongparam)

{

printk("char01 ioctl!/n");

printk("cmd:%d param:%ld/n", cmd, param);

return0;

}

/

structfile_operations fops =

{

.owner = THIS_MODULE,

.open = char01_open,

.release = char01_release,

.read = char01_read,

.write = char01_write,

.ioctl = char01_ioctl

};

dev_t devno;

structclass*pclass;

structcdev dev;

intchar01_dev_init(void)

{

intresult;

result = alloc_chrdev_region(&devno, 0, 1,"char01");

if(result != 0)

{

printk("alloc_chrdev_region failed!/n");

gotoERR1;

}

cdev_init(&dev, &fops);

dev.owner = THIS_MODULE;

dev.ops = &fops;

result = cdev_add(&dev, devno, 1);

if(result != 0)

{

printk("cdev_add failed!/n");

gotoERR2;

}

pclass = class_create(THIS_MODULE,"char01");

if(IS_ERR(pclass))

{

printk("class_create failed!/n");

gotoERR3;

}

device_create(pclass, NULL, devno, NULL,"char01");

return0;

ERR3:

cdev_del(&dev);

ERR2:

unregister_chrdev_region(devno, 1);

ERR1:

return-1;

}

/

/

/

staticint__init char01_init(void)

{

printk("module char01 init!/n");

returnchar01_dev_init();

}

staticvoid__exit char01_exit(void)

{

printk("module char01 exit!/n");

class_destroy(pclass);

device_destroy(pclass,devno);

cdev_del(&dev);

unregister_chrdev_region(devno, 1);

}

/

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("Yao.GUET");

module_init(char01_init);

module_exit(char01_exit);

/

#include

#include

#include

#include

#include

#include

/

int char01_open(struct inode *inode, struct file *filp)

{

printk("char01 open!/n");

return 0;

}

int char01_release(struct inode *inode, struct file *filp)

{

printk("char01 release!/n");

return 0;

}

ssize_t char01_read(struct file *filp, char *buf,

size_t count, loff_t *fpos)

{

printk("char01 read!/n");

return 0;

}

ssize_t char01_write(struct file *filp, const char *buf,

size_t count, loff_t *fpos)

{

printk("char01 write!/n");

return 0;

}

int char01_ioctl(struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long param)

{

printk("char01 ioctl!/n");

printk("cmd:%d param:%ld/n", cmd, param);

return 0;

}

/

struct file_operations fops =

{

.owner = THIS_MODULE,

.open = char01_open,

.release = char01_release,

.read = char01_read,

.write = char01_write,

.ioctl = char01_ioctl

};

dev_t devno;

struct class *pclass;

struct cdev dev;

int char01_dev_init(void)

{

int result;

result = alloc_chrdev_region(&devno, 0, 1, "char01");

if (result != 0)

{

printk("alloc_chrdev_region failed!/n");

goto ERR1;

}

cdev_init(&dev, &fops);

dev.owner = THIS_MODULE;

dev.ops = &fops;

result = cdev_add(&dev, devno, 1);

if (result != 0)

{

printk("cdev_add failed!/n");

goto ERR2;

}

pclass = class_create(THIS_MODULE, "char01");

if (IS_ERR(pclass))

{

printk("class_create failed!/n");

goto ERR3;

}

device_create(pclass, NULL, devno, NULL, "char01");

return 0;

ERR3:

cdev_del(&dev);

ERR2:

unregister_chrdev_region(devno, 1);

ERR1:

return -1;

}

/

/

/

static int __init char01_init(void)

{

printk("module char01 init!/n");

return char01_dev_init();

}

static void __exit char01_exit(void)

{

printk("module char01 exit!/n");

class_destroy(pclass);

device_destroy(pclass,devno);

cdev_del(&dev);

unregister_chrdev_region(devno, 1);

}

/

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("Yao.GUET");

module_init(char01_init);

module_exit(char01_exit);

/

测试文件char01_test.c

#include

#include

#include

#include

/

intmain(intargc,char*argv)

{

intfd;

fd = open("/dev/char01", O_RDWR);

if(fd<0)

{

printf("open /dev/char01 failed!/n");

printf("%s/n", strerror(errno));

return-1;

}

printf("open /dev/char01 ok!/n");

ioctl(fd, 0);

close(fd);

}

#include

#include

#include

#include

/

int main(int argc, char *argv)

{

int fd;

fd = open("/dev/char01", O_RDWR);

if (fd<0)

{

printf("open /dev/char01 failed!/n");

printf("%s/n", strerror(errno));

return -1;

}

printf("open /dev/char01 ok!/n");

ioctl(fd, 0);

close(fd);

}

Makefile文件:

obj-m:= char01.o

PWD:= $(shell pwd)

K_DIR:= /lib/modules/$(shell uname -r)/build

all:

$(MAKE) -C $(K_DIR)M=$(PWD) modules

clean:

$(MAKE) -C $(K_DIR)M=$(PWD) clean

test:char01_test.o

gcc -o $@ $^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值