×
单片机 > 单片机程序设计 > 详情

S3C2440 字符设备驱动程序之LED驱动程序_测试改进(三)

发布时间:2024-05-10 发布时间:
|

在加载驱动之前,先来看一下/proc/devices,里面是现在内核所支持的设备。


第一列是主设备号,对应的是内核数组chrdevs的下标,第二列是它的名字。


加载驱动的命令:


insmod first_drv.ko


at /proc/devices


写个测试驱动程序来测试它。


mknod /dev/xxx c 主设备号 次设备号


register_chrdev(111,"first_drv",&first_drv_fops);


怎么确定这设备号111?


1、先cat /proc/devices,有哪一个空缺项,然后选取那个空缺项。(1~255)。


2、也可以写为0,系统会自动给我们分配一个主设备号,它在数组chrdevs找一个空缺项,给你返回主设备号。


major=register_chrdev(0,...,...);


1、驱动的主设备号:自动分配主设备号;手工指定主设备号。


2、应用:open("/dev/xxx");


xxx文件怎么来的?


a.mknod /dev/xxx c 主设备号 次设备号(手工建立,需要先知道主设备号)


b.自动创建:对于应用程序,udev机制;对于busybox来说,mdev程序


cd /sys(系统目录下的信息)。注册驱动时,先会在sys目录下生成设备信息


mdev:会根据系统的信息,创建设备节点。(驱动程序里,如果能提供系统的信息,mdev就能自动帮我们创建设备节点)


★★★


为什么sys目录下的信息一更改,mdev就会自动运行、生成呢?


vi /etc/init.d/rcS:


在创建根文件系统时:


内核里一旦有设备加载进去或者卸载之后,就会根据调用/proc/sys/kernel/hotplug所指示的应用程序。


程序一:first_dev.c


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static struct class *firstdrv_class; //一个类

static struct class_device *firstdrv_class_dev; //一个类里面再建立一个设备

static int first_drv_open(struct inode *inode, struct file *file)

{

printk("first_drv_openn");

return 0;

}

static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

{

printk("first_drv_writen");

return 0;

}

static struct file_operations first_drv_fops = {

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = first_drv_open,

.write = first_drv_write,

};

int major;

int first_drv_init(void)

{

//0:让系统给我们自动分配一个主设备号,在数组中找个空缺,返回主设备号

major = register_chrdev(0, "first_drv", &first_drv_fops); //注册驱动程序,告诉内核,再内核数组里,把fops结构填充进去

/* 下面这两条代码就会在sys目录下,class目录下,建立firstdrv这个类,再firstdrv这个类下,会创建xyz这个设备,再xyz目录下有个dev文件,里面有主设备号:次设备号 */

/* 然后mdev根据上面的系统信息,就会创建/dev/xyz这个设备节点 */

/* ★★下面两条代码会根据自动分配的主设备号,生成设备文件,并且生成系统信息 */

//先建立一个类

firstdrv_class = class_create(THIS_MODULE, "firstdrv");

//在这个类下面建立一个设备

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz");

return 0;

}

void first_drv_exit(void)

{

unregister_chrdev(major, "first_drv"); //卸载驱动

class_device_unregister(firstdrv_class_dev);

class_destroy(firstdrv_class);

}

module_init(first_drv_init);

module_exit(first_drv_exit);

MODULE_LICENSE("GPL"); //license,可以解决class_device_unregister和class_destory不能识别的问题


程序二:测试程序firstdrvtest.c


#include

#include

#include

#include

int main(int argc, char **argv)

{

int fd;

int val = 1;

fd = open("/dev/xyz", O_RDWR); //无论主设备号怎么变,/dev/xyz都是系统为我们创建的

if (fd < 0)

{

printf("can't open!n");

}

write(fd, &val, 4);

return 0;

}


编译程序:arm-linux-gcc -o fristdrvtest fristdrvtest.c


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32 USB HID 键盘