问题在帖子的最后。先贴代码:
驱动的pressure.c:
/*
功能:
外部中断4接一个人体红外感应,默认感应到有人体,如果人MISS了,低电平触发外
部中断,此时nLED_2(GPB6)亮,并且打印BABY MISS !!!
*/
volatile unsigned long *gpbcon = NULL; // nLED_2(GPB6)
volatile unsigned long *gpbdat = NULL;
volatile unsigned long *gpfcon = NULL; // EINT4 ( GPF4 )
volatile unsigned long *gpfdat = NULL;
volatile unsigned long *eintmask = NULL;
volatile unsigned long *eintpend = NULL;
unsigned int val = 0;
static struct class *pressuredrv_class;
static struct class_device *pressuredrv_class_dev;
//等待队列
static DECLARE_WAIT_QUEUE_HEAD(pressure_waitq);
/* 中断事件标志, 中断服务程序将它置1,pressure_read将它清0 */
static volatile int ev_press = 0;
static irqreturn_t pressure_irq(int irq, void dev_id)
{
//((*eintpend) & (1<<4)) = 1;
val = (*eintpend) & (1<<4); //读取EINTPEND寄存器的第4位的值
while (!val); //如果标志位置1
ev_press = 1; / 表示中断发生了 /
wake_up_interruptible(&pressure_waitq); / 唤醒休眠的进程 */
return IRQ_RETVAL(IRQ_HANDLED);
}
static int pressure_open(struct inode inode, struct file *file)
{
*gpbcon &= ~(0x3<<(06*2)); / 配置GPB6为输出引脚 */
*gpbcon |= (0x1<<(06*2));
*eintmask &= ~(0x1<<4); //把EINTMASK的第4位设为0,使能中断
request_irq(IRQ_EINT4, pressure_irq, IRQT_LOW, "PRESSURE", NULL); //设置外部中断4
return 0;
}
static int pressure_read(struct file file, char __user *buf, size_t size, loff_t *ppos)
{
/*如果没有检测到外部中断4,休眠/
wait_event_interruptible(pressure_waitq, ev_press);
/*如果有外部中断,返回val值*/
copy_to_user(buf, val, 1);
ev_press = 0;
return 0;
}
static ssize_t pressure_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int con = 0;
copy_from_user(&con,buf,1);
if (con == 1)
{
//亮灯报警
*gpbdat &= ~(1<<6);
}
else
{
//灭灯
*gpbdat |= (1<<6);
}
}
static ssize_t pressure_close(struct inode *inode, struct file *file)
{
free_irq(IRQ_EINT4, NULL);
return 0;
}
static struct file_operations pressure_drv_fops = {
.owner = THIS_MODULE,
.open = pressure_open,
.read = pressure_read,
.release = pressure_close,
};
int major;
static int __init pressure_drv_init(void)
{
major = register_chrdev(0, "pressure_drv", &pressure_drv_fops);
pressuredrv_class = class_create(THIS_MODULE, "pressure_drv");
pressuredrv_class_dev = class_device_create(pressuredrv_class, NULL, MKDEV(major, 0), NULL, "PressureDrv");
gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
gpbdat = gpbcon + 1;
gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
gpfdat = gpbcon + 1;
eintmask = (volatile unsigned long *)ioremap(0x560000A4, 8);
eintpend = (volatile unsigned long *)ioremap(0x560000A8, 8);
return 0;
}
static void __exit pressure_drv_exit(void)
{
unregister_chrdev(major, "pressure_drv");
class_device_unregister(pressuredrv_class_dev);
class_destroy(pressuredrv_class);
iounmap(gpbcon);
iounmap(gpfcon);
iounmap(eintmask);
iounmap(eintpend);
}
module_init(pressure_drv_init);
module_exit(pressure_drv_exit);
MODULE_LICENSE("GPL");
应用程序的app.c :
int main(int argc, char **argv)
{
int fd;
int con = 0;
int val = 0;
fd = open("/dev/PressureDrv",O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
while (1);
{
read(fd,val,1);
if (val) //val是eintpend第4位的值,如果被置1,表明有中断发生
{
printf("BABY MISS !!!\n");
con = 1; //;亮灯报警
}
else
{
con = 0; //不报警
//printf("HELLO !!!\n");
}
}
}
现在的问题是我加载了模块,并且运行了应用程序之后,灯马上就亮了,一直亮不会灭,而且没有任何打印信息输出
1
Panic 2015-03-02 19:18:27 +08:00
while(1) 后面有分号, 大bug
|