wait_event_interruptible and wake_up_interruptible error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I want to use  wait_event_interruptible and wake_up_interruptible to do
some jobs,but some error ouccor when  wake_up_interruptible. Attach is
the code.please help me.

The errors messages as follow:

irq7: nobody
cared                                                              
                                                                                
Pid: 497, comm:
ir_send_stream                                            
CPU:
0                                                                          
PC is at ir_open+0x3c/0x64
[ir]                                                 
LR is at ir_open+0x3c/0x64
[ir]                                                 
pc : [<bf00c350>]    lr : [<bf00c350>]    Not
tainted                           
sp : c0851e78  ip : 00000000  fp :
c0851e88                                     
r10: c0de86cc  r9 : c0e22e04  r8 :
c023bf98                                     
r7 : 0000003d  r6 : 00000001  r5 : c023bea8  r4 :
00000000                      
r3 : 00000004  r2 : c1869410  r1 : 00000004  r0 :
00000000                      
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  Segment
user                        
Control: 5317F  Table: 60648000  DAC:
00000015                                  
[<c0023a48>] (show_regs+0x0/0x4c) from [<c0022a18>] (report_bad_irq
+0x6c/0xcc)  
 r4 =
C0851E30                                                                  
[<c00229ac>] (report_bad_irq+0x0/0xcc) from [<c0022d4c>] (do_level_IRQ
+0x8c/0xc)
 r5 = 00000007  r4 =
C027C12C                                                   
[<c0022cc0>] (do_level_IRQ+0x0/0xc8) from [<c0022ddc>] (asm_do_IRQ
+0x54/0x150)  
 r6 = 00000001  r5 = C027C12C  r4 =
00000007                                    
[<c0022d88>] (asm_do_IRQ+0x0/0x150) from [<c00219b8>] (__irq_svc
+0x38/0x8c)     
[<bf00c314>] (ir_open+0x0/0x64 [ir]) from [<c0117eb4>] (misc_open
+0x28c/0x458)  
 r4 =
BF00D148                                                                  
[<c0117c28>] (misc_open+0x0/0x458) from [<c0087ef4>] (chrdev_open
+0x1b8/0x1e0)  
[<c0087d3c>] (chrdev_open+0x0/0x1e0) from [<c007c1c0>] (__dentry_open
+0x138/0x2)
[<c007c088>] (__dentry_open+0x0/0x2b0) from [<c007c3b4>] (filp_open
+0x7c/0x98)  
[<c007c338>] (filp_open+0x0/0x98) from [<c007c60c>] (do_sys_open
+0x44/0xd0)     
 r7 = 00000005  r6 = 00000004  r5 = 00000180  r4 =
00000002                     
[<c007c5c8>] (do_sys_open+0x0/0xd0) from [<c007c6a8>] (sys_open
+0x10/0x14)      
[<c007c698>] (sys_open+0x0/0x14) from [<c0021de0>] (ret_fast_syscall
+0x0/0x2c)  
[<c0027078>] (dump_stack+0x0/0x14) from [<c0022a1c>] (report_bad_irq
+0x70/0xcc) 
[<c00229ac>] (report_bad_irq+0x0/0xcc) from [<c0022d4c>] (do_level_IRQ
+0x8c/0xc)
 r5 = 00000007  r4 =
C027C12C                                                   
[<c0022cc0>] (do_level_IRQ+0x0/0xc8) from [<c0022ddc>] (asm_do_IRQ
+0x54/0x150)  
 r6 = 00000001  r5 = C027C12C  r4 =
00000007                                    
[<c0022d88>] (asm_do_IRQ+0x0/0x150) from [<c00219b8>] (__irq_svc
+0x38/0x8c)     
[<bf00c314>] (ir_open+0x0/0x64 [ir]) from [<c0117eb4>] (misc_open
+0x28c/0x458)  
 r4 =
BF00D148                                                                  
[<c0117c28>] (misc_open+0x0/0x458) from [<c0087ef4>] (chrdev_open
+0x1b8/0x1e0)  
[<c0087d3c>] (chrdev_open+0x0/0x1e0) from [<c007c1c0>] (__dentry_open
+0x138/0x2)
[<c007c088>] (__dentry_open+0x0/0x2b0) from [<c007c3b4>] (filp_open
+0x7c/0x98)  
[<c007c338>] (filp_open+0x0/0x98) from [<c007c60c>] (do_sys_open
+0x44/0xd0)     
 r7 = 00000005  r6 = 00000004  r5 = 00000180  r4 =
00000002                     
[<c007c5c8>] (do_sys_open+0x0/0xd0) from [<c007c6a8>] (sys_open
+0x10/0x14)      
[<c007c698>] (sys_open+0x0/0x14) from [<c0021de0>] (ret_fast_syscall
+0x0/0x2c)  
handlers:                                                                       
[<bf00c2f0>] (ir_in_irq+0x0/0x24 [ir])
/******************************************************************
*file: ir.c
*history:2007.10.24  add ir carry
*
******************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/time.h>

#include <asm/semaphore.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#include "ir.h"
#include "hi_gpio.h"

#define IR_PORT GPIO_1_BASE
#define Irq_1 7

DECLARE_WAIT_QUEUE_HEAD(ir_wait_q);

struct semaphore ir_sem;
unsigned char sleep_flag=0;

void gpio_init(void);



/**************************receive*******************************/
void gpio_init(void)
{
    unsigned int tmp;
    /*set gpio1 dir:out 3 in 2 */
    gpio_dirgetbyte(1,&tmp);
    tmp=tmp&0xfb;
    tmp=tmp|0x08;
    gpio_dirsetbyte(1,tmp);

    /*set gpio1 interrupt:raise edge interrpt 2bit*/
    gpio_interruptsenseset(1,2,SENSE_EDGE);
    gpio_interruptsenseboth(1,2,SENSE_SINGLE);
    gpio_interruptevenset(1,2,EVENT_RISING_EDGE);

    /*disable gpio1_2 interrupt*/
    tmp=0x04;
    gpio_interruptdisable_byte(1,tmp);
    
    /*clear data gpio1_3*/
    gpio_writebit(1,3,0);

    /*clear interrupt:gpio1_2*/
    gpio_interruptclear(1,2);
    
    /*enable interrupt gpio1_2*/
    /*tmp=0x04;
    gpio_interruptenable_byte(1,tmp);*/
}

int ir_save_stream(void)
{
    unsigned char current_irq;
    unsigned char flag;
    unsigned int tmp;
    unsigned int count;
    unsigned int i;    

    i=1;
    flag=1;

    current_irq=readw(IR_PORT+GPIO_RIS);
    if(!(current_irq&0x4))
    {
	printk("this is not ir_in_irq\n");
	return -1;
    }

    udelay(250);
    gpio_readbit(1,2,&tmp);
    if (tmp!=1) // false irq;
    {
       printk("false ir_irq\n") ;
       return -1;
    }
    else
    {
	count=5;
    }

    while(count<250&&i<128)
    {
        udelay(50);  
        gpio_readbit(1,2,&tmp);
        if(tmp==1)     //high level
	{
	    if(flag==1) //1 rising;0 falling
	    {
                count=count+1;
	    }
	    else
	    {
	        ir_receive_stream[i].high_low=0;
	        ir_receive_stream[i].counter_time=count;
                i++;
                count=1;
		flag=1;
	    }
	}
	else  //low level
	{
	    if(flag==0)
	    {
		count=count+1;
	    }
	    else
	    {
	        ir_receive_stream[i].high_low=1;
	        ir_receive_stream[i].counter_time=count;
                i++;
	        count=1;
		flag=0;
	    }
	}

	if(i>127)
	{
	    printk("ir_receive_stream buffer full!\n");
	}
	if(count>=250)
	{
	    printk("count biger than count!\n");
	}

    }

    printk("ir save stream finished\n");
    sleep_flag=1;
    printk("wake up ir_wait_q\n");
    wake_up_interruptible(&ir_wait_q);
    return 0;
}

int ir_send_stream(void)
{
   unsigned char i;
   unsigned char level;
   unsigned char count_delay;
   unsigned int bcount_delay;

   for(i=1;i<128;i++)
   {
      level=ir_temp_stream[i].high_low;
      count_delay=ir_temp_stream[i].counter_time;
      if(level)
      {
	 bcount_delay=(unsigned int)(4*count_delay);
	 for(;bcount_delay>0;bcount_delay--)
	 {
             gpio_writebit(1,3,level);
	     udelay(13);
             level=(~level)&0x01;
	 }
      }
      else
      {
         gpio_writebit(1,3,level);
         further_delay_n50us(count_delay);        
      }
   }  
   return 0;   
}
static irqreturn_t ir_in_irq(int irq,void *dev_id,struct pt_regs *reg)
{
    unsigned int tmp;
    int handled=0;

    tmp=0x04;
    gpio_interruptdisable_byte(1,tmp);

    ir_save_stream();

    //gpio_interruptenable_byte(1,0x04);
    return IRQ_RETVAL(handled);

}

/***************************************************************************
 **************************************************************************/

static int ir_open(struct inode *inode,struct file *file)
{
    int i;
    for(i=0;i<128;i++)
    {
       ir_receive_stream[i].high_low=0;
       ir_receive_stream[i].counter_time=0;        
    }
    gpio_interruptenable_byte(1,0x04);
    printk("ir_irq enable\n");
    sleep_flag=0;
    return 0;
}

static int ir_close(struct inode *inode,struct file *file)
{   
    gpio_interruptdisable_byte(1,0x04);
    printk("ir_irq disable\n");
    return 0; 
}

static int ir_read(struct file *file,char __user *buffer,size_t count,loff_t *ppos)
{ 
    struct ir_stream *user_buf;
    int ret; 
   
    user_buf=(struct ir_stream *)buffer;
    
    printk("process %i(%s) going to sleep\n",current->pid,current->comm);

    wait_event_interruptible(ir_wait_q,sleep_flag!=0);

    printk("process %i(%s) awoken\n",current->pid,current->comm);

    ret=copy_to_user(user_buf,(struct ir_stream *)ir_receive_stream,128*sizeof(struct ir_stream));
    if(ret)
    {
        printk("IR_error:error_val is %lu\n",ret);
    }
    else
    {
        printk("get ir stream success\n");
        printk("copy_return val is %lu\n",ret);
    }
   
    sleep_flag=0;
    return 0;
}

static int ir_write(struct file *file,char __user *buffer,size_t count,loff_t *ppos)
{
    struct ir_stream *user_buf;
    int ret; 
   
    user_buf=(struct ir_stream *)buffer;
    
    ret=copy_from_user((struct ir_stream *)ir_temp_stream,user_buf,128*sizeof(struct ir_stream));
    if(ret)
    {
        printk("IR_error:cpy_error_val is %lu\n",ret);
    }
    else
    {
        printk("get stream from user success\n");
        printk("copy_return val is %lu\n",ret);
    }
    ir_send_stream(); 
    return 0;
}

static int ir_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
    void __user *argp=(void __user *)arg;
    switch(cmd)
    {
	case IR_GET_STREAM:
	    {
		break;
	    }
	default:
	    return -EINVAL;
    }
}

static struct file_operations ir_fops=
{
    .owner=THIS_MODULE,
    .open =ir_open,
    .release=ir_close,
    .ioctl=ir_ioctl,
    .read=ir_read,
    .write=ir_write,
};

static struct miscdevice ir_dev=
{
    MISC_DYNAMIC_MINOR,
    "irdev",
    &ir_fops,
};

static int __init ir_init(void)
{
    int ret;
    ret=misc_register(&ir_dev);
    if(ret)
    {
	printk("could not register ir devices.\n");
	return ret;
    }
   
    gpio_remap();

    ret=request_irq(Irq_1,&ir_in_irq,0,"irdev",NULL);
    if(ret)
    {
	misc_deregister(&ir_dev);
	printk("can't request irq 7\n");
	return ret;
    }

    gpio_init();
   
    return 0;
}

static void __exit ir_exit(void)
{
    misc_deregister(&ir_dev);
    free_irq(Irq_1,NULL);
    gpio_unmap();
}

module_init(ir_init);
module_exit(ir_exit);

MODULE_LICENSE("GPL");

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include "ir_common.h"

static struct ir_stream ir_get_stream[128]; 

int ir_check_stream(unsigned char ir_nomber)
{
    FILE * fp;
    int fdesc;
    int i;
   
    fp=fopen("ir_stream","w");
    fdesc=open("/dev/misc/irdev",O_RDWR,S_IRUSR|S_IWUSR);
    if (fdesc<0)
    {
        printf("Cannot open /dev/misc/irdev\n");
    }
    else
    {  
        printf("open the devies: irdev\n");
    }
    read(fdesc,(struct ir_stream *)ir_get_stream,128*sizeof(struct ir_stream));
    ir_get_stream[0].high_low=ir_nomber;//index information; 
    printf("the ir_nomber is %d\n",ir_nomber);   

    if(fwrite((struct ir_stream *)ir_get_stream,sizeof(struct ir_stream),128,fp)!=128)
    {
         printf("write error!\n");
    }
    else
    {
         printf("fwrite success\n");
    }
    
    for(i=0;i<128;i++)
    {
        printf("ir_get_tream.hl and count_time is %d     %d\n",ir_get_stream[i].high_low,ir_get_stream[i].counter_time);
    }    
 
    close(fdesc);
    fclose(fp);
    return 0;
}

int main(void)
{
   int ir_nomber;
   ir_nomber=1;
   ir_check_stream(ir_nomber);
   return 0;
}

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux