Linux驱动(二)——设备操作集file_operations:

结构体file_operations为应用程序提供了操作设备的接口,包括打开设备、关闭设备、读设备、写设备等操作。
驱动程序部分:

/* 源代码文件名为"xxx.c"*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#define SHANWUYAN_MAJOR 200
#define SHANWUYAN_NAME "shanwuyan"

/*打开设备*/
static int shanwuyan_open(struct inode *inode, struct file *filp)
{
	printk(KERN_EMERG "shanwuyan_open\r\n");
	return 0;
}

/*释放(关闭)设备*/
static int shanwuyan_release(struct inode *inode, struct file *filp)
{
	printk(KERN_EMERG "shanwuyan_close\r\n");
	return 0;
}

/*读设备*/
static ssize_t shanwuyan_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
	printk(KERN_EMERG "shanwuyan_read\r\n");
	return 0;
}

/*写设备*/
static ssize_t shanwuyan_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
	printk(KERN_EMERG "shanwuyan_write\r\n");
	return 0;
}

static struct file_operations shanwuyan_fops = 
{
	.owner = THIS_MODULE,			//默认
	.open = shanwuyan_open,			//打开设备
	.release = shanwuyan_release,	//关闭设备
	.read = shanwuyan_read,			//读设备
	.write = shanwuyan_write,		//写设备
};

static int __init shanwuyan_init(void)	//驱动入口函数
{
	int ret = 0;

	ret = register_chrdev(SHANWUYAN_MAJOR, SHANWUYAN_NAME, &shanwuyan_fops);
	if(ret < 0)
		printk(KERN_EMERG "init failed\r\n");	//注册失败
	else
		printk(KERN_EMERG "shanwuyan_init\r\n");//注册成功
	return 0;
}

static void __exit shanwuyan_exit(void)	//驱动出口函数
{
	unregister_chrdev(SHANWUYAN_MAJOR, SHANWUYAN_NAME);	//注销字符设备
	printk(KERN_EMERG "shanwuyan_exit\r\n");
}

module_init(shanwuyan_init);	//注册入口函数
module_exit(shanwuyan_exit);	//注册出口函数

MODULE_LICENSE("GPL");	//同意GPL开源协议
MODULE_AUTHOR("......");	//添加作者名称

makefile部分:

#!/bin/bash

obj-m += shanwuyan.o

KDIR := /home/topeet/Android/itop4412_kernel_4_14_2_bsp/linux-4.14.2_iTop-4412_scp #这里要对应你的Linux内核目录

PWD ?= $(shell pwd)

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean

应用程序部分:

//文件名为"xxx_APP.c"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

/*
*argc:应用程序参数个数,包括应用程序本身
*argv[]:具体的参数内容,字符串形式
*./shanwuyan_APP <filename> <r:w>	r表示读,w表示写
*/
int main(int argc, char *argv[])
{
	int ret = 0;
	int fd = 0;
	char *filename;

	if(argc != 3)	//共有三个参数
	{
		printf("Error usage!\r\n");
		return -1;
	}
		
	filename = argv[1];	//获取文件名称

	fd = open(filename, O_RDWR);
	if(fd < 0)
	{
		printf("cannot open file %s\r\n", filename);
		return -1;
	}

	if(!strcmp(argv[2], "r"))	//读设备
	{
		
		read(fd, NULL, 0);	//只是使用读函数,但不读出数据
	}
	else if(!strcmp(argv[2], "w"))	//写设备
	{
		write(fd, NULL, 0);	//只是使用

	}
	else
	{
		printf("ERROR usage!\r\n");
	}

	/*关闭设备*/
	close(fd);

	return 0;
}

4.应用
  编译驱动文件,交叉编译应用程序,拷贝到开发板中,并加载驱动。
  驱动加载完成后,使用命令"mknod /dev/shanwuyan c 200 0",在"/dev"目录下创建"shanwuyan"设备节点。其中参数"c"是指创建一个字符设备节点,200表示主设备号,0表示次设备号。然后使用ls命令查看是否创建成功。
  在这里插入图片描述
分别输入命令"./shanwuyan_APP /dev/shanwuyan r"和命令"./shanwuyan_APP /dev/shanwuyan w",可以看到终端打印了如下信息。可以看到,应用程序打开设备、关闭设备、读设备、写设备的操作都有所体现。
在这里插入图片描述
在本章中,我们只是单纯得调用了read和write函数,但是并没有真正的读写数据。读写数据操作将在下一章中出现。
 本章的全部代码在这里。
 原文地址:https://blog.csdn.net/a154299/article/details/108579348

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值