经典方式注册与杂项设备注册区别
杂项方式注册生成的设备文件会自动挂载在/dev目录下面,经典方式注册的设备不会自动挂载在/dev目录下面
.
杂项设备注册的主设备号只能为10,经典方式注册主设备号可以指定或者系统自动分配一个除了(10)以外的任意一个设备号。杂项方式只暂用一个子设备号,经典方式占用当前主设备号所有的子设备号(0~254)
经典方式注册API函数
头文件:
#include <linux/fs.h>
功能:
注册函数:
函数:
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
参数:
major:主设备号(不可为10),0为自动分配
name:这个name不是注册设备的名称,随便填写
fops:file_operations 结构体。同杂项设备注册里面一样
返回值:
当 major == 0:成功:返回所系统分配的主设备号,失败:返回负数。
当 major >0:成功:返回0 失败:返回负数。(自己指定设备号)
*********************************************************
头文件:
#include <linux/fs.h>
static inline void unregister_chrdev(unsigned int major, const char *name)
功能:
注销函数
参数:
major:
如register_chrdev函数里面参数major为0,则为register_chrdev函数返回的主设备号
如果register_chrdev里面的major自己指定的设备号,为指定的设备号
name:
保持与register_chrdev函数里面的name参数一致
返回值:
无
示例
注册一个蜂鸣器设备:
内核模块:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/cdev.h>
//经典注册方法
/* GPD0_0---beep 0x114000A0 -- con 0x114000A4 -- con*/
struct file_operations my_ops;
int my_major;
unsigned int * base=NULL;
#define GPD0_CON (*((unsigned int *)(base)))
#define GPD0_DTA (*((unsigned int *)(base+1)))
int beep_open (struct inode * inode, struct file * file)
{
GPD0_DTA |= (0x01<<0);
return 0;
}
int beep_close (struct inode * inode, struct file * file)
{
GPD0_DTA &= ~(0x01<<0);
return 0;
}
static int __init beep_init(void)
{
my_ops.owner = THIS_MODULE;
my_ops.open = beep_open;
my_ops.release = beep_close;
my_major=register_chrdev(0,"jason",&my_ops);//0表示主设备号自动分配,次设备号全部占用
//地址映射
base=ioremap(0x114000A0,8);
GPD0_CON &=~(0xF<<0);
GPD0_CON |=(0x01<<0);
printk("分配的主设备号为%d\n",my_major);
return 0;
}
static void __exit beep_exit(void)
{
unregister_chrdev(my_major,"jason");
iounmap(base);
}
module_init(beep_init);
module_exit(beep_exit);
MODULE_LICENSE("GPL");
用户调用设备文件源码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int fd=0;
while(1)
{
fd = open("/dev/beep",O_RDWR);
sleep(1);
close(fd);
sleep(1);
}
return 0;
}
Makefile
obj-m += beep.o
KDIR:=/home/jason/my_drive/linux-3.5
all:
make -C $(KDIR) M=$(PWD) modules
arm-linux-gcc beep_app.c -o beep_app
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.markers *.order
拷贝到开发板根文件目录下面
连接到开发板上面。
运行成功。