linux系统中一切皆文件
fd = open("led驱动的文件",O_RDWR);
read(fd);
write();
close();
对灯写一个驱动
led_driver.c
driver_open();
driver_read();
driver_write();
driver_close();
struct file_operations
{
int (*open) (struct inode *, struct file *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*release) (struct inode *, struct file *);//(close)
}
cdev:
设备号1 设备号2 设备号n
设备驱动1 设备驱动2 .... 设备驱动n
设备号:32位,无符号数字
高12位 :主设备号 :区分哪一类设备
低20位 :次设备号 :区分同类中哪一个设备
每个驱动里面都有对应的file_operations
open打开文件,这个文件与底层的驱动的设备号有关系,
通过设备号访问设备驱动中的struct file_operations里面的open函数。
open函数会有一个返回值,文件描述符fd,read函数通过fd
找到驱动中的struct file_operations里面的read函数。
struct file_operations
{
int (*open) (struct inode *, struct file *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*release) (struct inode *, struct file *);//(close)
}
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
功能:注册一个字符设备驱动
参数:
@major:主设备号
:如果你填写的值大于0,它认为这个就是主设备号
:如果你填写的值为0,操作系统给你分配一个主设备号
@name :名字 cat /proc/devices
@fops :操作方法结构体
返回值:major>0 ,成功返回0,失败返回错误码(负数) vi -t EIO
major=0,成功主设备号,失败返回错误码(负数)
当注册一个字符设备驱动的时候。
如果成功的话,当你使用cat /proc/devices 命令查看的时候可以看到系统自动分配的主设备号和这个名字
void unregister_chrdev(unsigned int major, const char *name)
功能:注销一个字符设备驱动
参数:
@major:主设备号
@name:名字
返回值:无
三、手动创建设备文件 mknod
sudo mknod led (路径是任意) c/b 主设备号 次设备号
sudo –rf led 删除的时候记得加-rf
#include
#include
#include
#include
#define NAME "chrdev_devled"
int major = 0; //保存主设备号
// open read write release 初始化
int myopen(struct inode *node, struct file *file_t)
{
printk("%s %s %d\n", __FILE__, __func__, __LINE__);
return 0;
}
ssize_t myread(struct file *file_t, char __user *ubuf, size_t n, loff_t *off_t)
{
printk("%s %s %d\n", __FILE__, __func__, __LINE__);
return 0;
}
ssize_t mywrite(struct file *file_t, const char __user *ubuf, size_t n, loff_t *off_t)
{
printk("%s %s %d\n", __FILE__, __func__, __LINE__);
return 0;
}
int myclose(struct inode *node, struct file *file_t)
{
printk("%s %s %d\n", __FILE__, __func__, __LINE__);
return 0;
}
struct file_operations fops = {
.open = myopen,
.read = myread,
.write = mywrite,
.release = myclose,
};
//入口函数
static int __init chrdev_init(void)
{
printk("%s %s %d\n", __FILE__, __func__, __LINE__);
//注册字符设备驱动: 主设备号 驱动名 结构体
major=register_chrdev(major, NAME, &fops);
//容错判断
if(major < 0)
{
printk("chrdev_register err.\n");
return -EINVAL;
}
return 0;
}
//出口函数
static void __exit chrdev_exit(void)
{
printk(KERN_ERR "%s %s %d\n", __FILE__, __func__, __LINE__);
//注销字符设备驱动
unregister_chrdev(major, NAME);
}
module_init(chrdev_init);//入口
module_exit(chrdev_exit);//出口
MODULE_LICENSE("GPL");//协议
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int fd = -1;
char buf[32] = "";
if(argc < 2)
{
printf("请输入要打开的文件\n");
return 1;
}
fd = open(argv[1],O_RDWR);
if(fd < 0)
{
printf("open %s failed\n",argv[1]);
return 2;
}
read(fd,buf,sizeof(buf));
write(fd,buf,sizeof(buf));
read(fd,buf,sizeof(buf));
write(fd,buf,sizeof(buf));
printf("buf=%s\n",buf);
close(fd);
fd = -1;
return 0;
}
--make 驱动文件
--insmod 安装驱动
--cat /proc/devicse 查看设备号
--sudo mknod led c 244 0 创建设备文件(设备节点)
--dmesg 查看消息
--sudo dmesg -C删除消息
--sudo gcc app.c 编译应用层读取文件
--./app .led读取
--led--dmesg 查看消息