自己写的简单的字符设备驱动,不能实现功能,搞不懂,求帮忙分析找错

2015-03-02 18:29:56 +08:00
 logbang

问题在帖子的最后。先贴代码:

驱动的pressure.c:

/*
功能:
外部中断4接一个人体红外感应,默认感应到有人体,如果人MISS了,低电平触发外
部中断,此时nLED_2(GPB6)亮,并且打印BABY MISS !!!
*/

include <linux/module.h>

include <linux/kernel.h>

include <linux/fs.h>

include <linux/init.h>

include <linux/delay.h>

include <linux/irq.h>

include <linux/poll.h>

include <linux/device.h>

include <linux/interrupt.h>

include <asm/uaccess.h>

include <asm/irq.h>

include <asm/io.h>

include <asm/arch/regs-gpio.h>

include <asm/hardware.h>

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 :

include <sys/types.h>

include <sys/stat.h>

include <fcntl.h>

include <stdio.h>

include <poll.h>

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");
            }
    }

}

现在的问题是我加载了模块,并且运行了应用程序之后,灯马上就亮了,一直亮不会灭,而且没有任何打印信息输出

2210 次点击
所在节点    Linux
2 条回复
Panic
2015-03-02 19:18:27 +08:00
while(1) 后面有分号, 大bug
jesse_luo
2015-03-02 21:53:12 +08:00
@Panic 哈哈哈一语中的

另外 lz 最好放在 github 或者 gist 上,太难看了……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/173999

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX