Linux火焰传感器驱动程序

ioremap()地址映射

ioremap 函数用于将设备的物理地址映射到内核的虚拟地址空间,这样内核就可以通过普通的指针访问硬件寄存器。

void *regGPGCON = ioremap(0x00000000, 4);

这里的 0x00000000 是 物理地址,而 regGPGCON 指向的是 虚拟地址。


void *regGPGCON;
regGPGCON = ioremap(GPGCON, 4);

GPGCON 是 物理地址,即硬件寄存器的实际地址。

regGPGCON 是 虚拟地址,即通过 ioremap 映射后的地址,用于内核访问硬件寄存器。

等待队列 Wait Queue 处理内核中断

等待队列:是一个数据结构,用于跟踪一组等待特定事件发生的进程。

等待队列条目:每个进程都会在等待队列中有一个对应的条目,记录着进程的状态和其他相关信息。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <mach/irqs.h>
#include <asm/uaccess.h>
#include <asm/io.h>


#define GPGCON (0x56000060)   //端口控制寄存器  用来设置端口的引脚功能  将来配为 外部中断EINT模式
#define GPGDAT (0X56000064)	  //数据寄存器    在EINT模式下  如果检测到外部中断 就会改变这个寄存器的电平   读取引脚的电平
#define GPGUP  (0x56000068)  // 上拉使能寄存器

static unsigned int *regGPGCON; // 物理地址映射到虚拟地址  所指向的指针
static unsigned int *regGPGDAT;
static unsigned int *regGPGUP;


static wait_queue_head_t wq;  // 等待队列队头
static int condition;    // 等待条件
int fire = 0;

irqreturn_t fire_handler(int irq_num,void *dev)
{
	if(irq_num == IRQ_EINT15)
	{
		fire = 1;
	}
	condition = 1;
	wake_up(&wq);
	return IRQ_HANDLED;
}

int fire_open(struct inode *p_node,struct file *fp)
{
	return 0;
}

int fire_release(struct inode *p_node,struct file *fp)
{
	return 0;
}

ssize_t fire_write(struct file *fp,const char __user *user_buffer,size_t n,loff_t *offset)
{

	return 0;
}

ssize_t fire_read(struct file *fp,char __user *user_buffer,size_t n,loff_t *offset)
{
	condition = 0;
	wait_event_interruptible(wq,condition);
	copy_to_user(user_buffer,&fire,4);
	fire = 0;
	return sizeof(fire);
}

static struct file_operations fops =
{
	.owner = THIS_MODULE,
	.open = fire_open,
	.release = fire_release,
	.read = fire_read,
};
//定义了一个杂项设备,用于注册设备节点。
static struct miscdevice fire_device =
{
	.minor = MISC_DYNAMIC_MINOR,
	.fops = &fops,
	.name = "fire"
};

static int __init fire_driver_init(void)
{
	int ret;
	ret = misc_register(&fire_device);
	if(ret)
	{
		printk("misc_register is error");
		return ret;
	}

	ret = request_irq(IRQ_EINT15,fire_handler,IRQF_TRIGGER_RISING | IRQF_DISABLED,"fire_irq",&fire_device);
	if(ret)
	{
		printk("request_irq is error\n");
		misc_deregister(&fire_device);
	}

	init_waitqueue_head(&wq);

	regGPGCON = ioremap(GPGCON,4);
	regGPGDAT = ioremap(GPGDAT,4);
	regGPGUP = ioremap(GPGUP,4);

	return 0;
}

void __exit fire_exit(void)
{
	iounmap(regGPGCON);
	iounmap(regGPGDAT);
	iounmap(regGPGUP);

	disable_irq(IRQ_EINT15);
	free_irq(IRQ_EINT15,&fire_device);
	misc_deregister(&fire_device);
}


module_init(fire_driver_init);
module_exit(fire_exit);

MODULE_LICENSE("GPL");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值