#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
static unsigned long flag = 0;
/*设备struct*/
struct led_struct
{
dev_t led_dev;
struct cdev led_cdev;
struct class *led_class;
struct device *led_device;
struct fasync_struct *sigio_list;
struct device_node *led_nd;
};
struct led_struct led_struct;
ssize_t read_flag(struct device *dev,struct device_attribute *attr,char *buf){
size_t count = 0;
count += sprintf(&buf[count],"%lu\n",flag);
return count;
}
ssize_t write_flag(struct device * dev,struct device_attribute *attr,char *buf,size_t count){
flag = buf[0] - '0';
//给所有以FASYNC标志调用fcntl的应用程序发信号
kill_fasync(&led_struct.sigio_list,SIGIO,POLL_IN);
return count;
}
struct device_attribute flag_attr = __ATTR(flag,S_IRUGO | S_IWUSR,read_flag,write_flag);
int led_open(struct inode *inode, struct file *filp)//打开led
{
printk("_____%s_____\n",__FUNCTION__);
return 0;
}
int led_fasync (int fd, struct file *filp, int onflag){
//将需要通知的迸程加入sigio_list链表或者从链表中移除
return fasync_helper(fd, filp, onflag, &led_struct.sigio_list);
}
static struct file_operations led_ops = {
.owner = THIS_MODULE,
.open = led_open,
.fasync = led_fasync,
};
static int __init led_init(void)
{
int ret = 0;
// 1.分配设备号
alloc_chrdev_region(&led_struct.led_dev, 0, 1, "my_led");
//2.创造cdev对象和file_operation,然后cdev_init初始化
cdev_init(&led_struct.led_cdev, &led_ops);
//3.cdev_add将cdev对象注册进入内核
cdev_add(&led_struct.led_cdev, led_struct.led_dev, 1);
//4.创造class与device
led_struct.led_class = class_create(THIS_MODULE, "led_class");
led_struct.led_device=device_create(led_struct.led_class, NULL, led_struct.led_dev, NULL, "led");
//在文件系统中创建一个名为"flag的文件
ret = device_create_file(led_struct.led_device,&flag_attr);
printk("flag = %d\n",flag);
return ret;
}
static void __exit led_exit(void)
{
printk("flag = %d\n",flag);
device_destroy(led_struct.led_class, led_struct.led_dev);
class_destroy(led_struct.led_class);
cdev_del(&led_struct.led_cdev);
unregister_chrdev_region(led_struct.led_dev, 1);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
具体的例子来展示设备驱动程序如何实现fasync方法,以及应用程序如何得到来自设备驱动程序的异步通知。这个例了同时也展示了sysfs文件系统在驱动程序中的用法,以及通过Linux设各模型来创建设备节点及其他一些特性(这个看起来很简单的内核模块其实体现了设备驱动程序中一些比较重要且典型的特征)。 首先是设备驱动程序的代码,在代码中,我们将这段代码是用C语言编写的Linux内核模块,用于控制LED。它包含了几个来自Linux内核的头文件,如linux/types.h、linux/kernel.h和linux/delay.h。代码定义了一个led_struct结构体,其中包含了关于LED设备的信息,包括它的设备号、字符设备、类和设备。代码还定义了几个用于与LED交互的函数,包括用于打开LED设备的led_open和用于处理异步通知的led_fasync。 模块使用led_init函数进行初始化,该函数在模块加载到内核时调用。这个函数为LED分配一个字符设备号,为它初始化并注册一个字符设备,并为LED创建一个类和设备。它还在文件系统中创建了一个名为“flag”的文件,可以用来与LED交互。
资源推荐
资源详情
资源评论
收起资源包目录
sysfs文件接口修改内核模块变量值_fasync.zip (2个子文件)
sysfs文件接口修改内核模块变量值_fasync
app.c 2KB
sysfs.c 3KB
共 2 条
- 1
资源评论
苦梨甜
- 粉丝: 1w+
- 资源: 119
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功