这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » smartarm2200 请教在smartarm2200上写外部中断的问题

共2条 1/1 1 跳转至

smartarm2200 请教在smartarm2200上写外部中断的问题

院士
2006-09-17 18:14:16     打赏
smartarm2200 请教在smartarm2200上写外部中断的问题



关键词: smartarm2200     请教     外部     中断     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问 我目前在smartARM2200上的uclinux下写了一个用KEY1来触发外部中断,并用中断处理函数处理后将按键值返回给用户空间应用程序的驱动。但是发觉在asm/arch/irqs.h中定义的IRQ_EXT3与板子上的eth0的中断号一样都为17。驱动无法加载。若改变中断号,虽可以加载驱动,但按KEY1之后无任何反映,而且还出现IRQ17 is locking the system ,disable的消息。所以将程序贴出来大家帮我看看应该怎么办。我第一次写带中断的驱动,大家多多指点一下。
#include "config.h"
static int request_irqs(void);
static void free_irqs(void);
static int matrix4_buttons_open(struct inode *inode, struct file *filp);
static int matrix4_buttons_release(struct inode *inode, struct file *filp);
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg);
int read_gpio_bit(unsigned int gpio_port);
static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos);
static unsigned int matrix4_buttons_select(struct file *file,struct poll_table_struct *wait);
static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);


//unsigned int GPIO_F3=20;
int num;
//#define IRQ_EXT3 19

#define GPIO_ADDR_BASE   0xE0028000
#define GPIO_PIN_OFFSET  0x00000000
#define GPIO_SET_OFFSET  0x00000001
#define GPIO_DIR_OFFSET  0x00000002
#define GPIO_CLR_OFFSET  0x00000003

#define GPIO_PORT_ADD    0x00000010

static struct key_info {
    int irq_no;
    unsigned int gpio_port;
    int key_no;
}key_info_tab={IRQ_EXT3,20,1};

static int ready = 0;
static int key_value = 0;
static u32 RunTime;
static u32 PinSel0Save, PinSel1Save;
static unsigned int usage;

static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);

static int request_irqs(void)
{
    struct key_info *k;
       
        k = &key_info_tab;
                if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) {
              return -1;
        }
        printk("request_irq successful\n");
   
    return 0;
}

static void free_irqs(void)
{
    struct key_info *k;
     
        k = &key_info_tab ;
        free_irq(k->irq_no, buttons_irq);
   
}

static int matrix4_buttons_open(struct inode *inode, struct file *filp)
{
   unsigned long flag;
   int ret;
    
    if(usage==0)
     {
             ret = request_irqs();
    if (ret) {
        unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
        printk(DEVICE_NAME " CAN't request irqs\n");
        return ret;
    }
      printk("open successful\n");
       local_irq_save(flag);
         PinSel0Save = inl(PINSEL0) & 0xfc00f;
         PinSel1Save = inl(PINSEL1) & (0x03 << 10);
     
         outl(3<<8,PINSEL1);
         outl(1<<7,IO0DIR);
                 outb(0x00,EXTMODE);
                printk("EXTMODE=0x%x",EXTMODE);
                   outb(1<<3,EXTINT);
               // CLEAR_PEND_INT(IRQ_EXT3);
             printk("EXTINT=0x%x",EXTINT);
        
         RunTime=0;
       local_irq_restore(flag);
         enable_irq(IRQ_EXT3);

      }    
     num = MINOR(inode->i_rdev);
      printk("num=%d",num);
     usage++;
     MOD_INC_USE_COUNT;
    return 0;          /* success */
}

static int matrix4_buttons_release(struct inode *inode, struct file *filp)
{
   unsigned long flag;
   
   MOD_DEC_USE_COUNT;
    
   usage--;
   if(usage==0)
    {
       local_irq_save(flag);
        outl(PinSel0Save | (inl(PINSEL0) & (~0xfc00f)), PINSEL0);
        outl(PinSel1Save | (inl(PINSEL1) & (~(0x3 << 10))), PINSEL1);
       local_irq_restore(flag);
        free_irqs();
  
    }
   return(0);
}

static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
    struct key_info *k;
      int found = 0;
    int up;
    int flags;
   
        k = &key_info_tab ;
        if (k->irq_no == irq) {
              found = 1;
             
       
    }
    if (!found) {
        printk("bad irq %d in button\n", irq);
        return;
    }

    save_flags(flags);
             disable_irq(IRQ_EXT3);
        
        up = read_gpio_bit(k->gpio_port);
            outb(1<<3,EXTINT);
        enable_irq(IRQ_EXT3);
    restore_flags(flags);
    if (up) {
          key_value = k->key_no + 0x80;
    } else {
          key_value = k->key_no;
    }
        ready = 1;
    wake_up_interruptible(&buttons_wait);
    
    RunTime++;
}

int read_gpio_bit(unsigned int gpio_port)
{
  volatile u32 *Reg;
u32 temp1;

  
Reg = (volatile u32 *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * num);

temp1 = Reg[GPIO_PIN_OFFSET] & (1u << gpio_port);
                if (temp1 != 0)
                {
                    temp1 = GPIO_PIN_HIGH;
                }
                else
                {
                    temp1 = GPIO_PIN_LOW;
                }

return temp1;
}





static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
    static int key;
    int flags;
    int repeat;
    if (!ready)
          return -EAGAIN;
    if (count != sizeof key_value)
          return -EINVAL;
   save_flags(flags);
    if (key != key_value) {
        key = key_value;
        repeat = 0;
    } else {
        repeat = 1;
    }
  restore_flags(flags);

    if (repeat) {
        return -EAGAIN;
    }
    
    copy_to_user(buffer, &key, sizeof key);
    ready = 0;
    return sizeof key_value;
}

static unsigned int matrix4_buttons_select(
    struct file *file,
    struct poll_table_struct *wait)
{
    if (ready)
          return 1;
    poll_wait(file, &buttons_wait, wait);
    return 0;
}


static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    switch(cmd) {
    default:
        return -EINVAL;
    }
}
static struct file_operations matrix4_buttons_fops = {
    owner:     THIS_MODULE,
    ioctl: matrix4_buttons_ioctl,
    poll: matrix4_buttons_select,
    read: matrix4_buttons_read,
    open: matrix4_buttons_open,
    release:matrix4_buttons_release,
};


static int __init matrix4_buttons_init(void)
{
    int ret;

    ready = 0;
    ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops);
    if (ret < 0) {
      printk(DEVICE_NAME " CAN't register major number\n");
      return ret;
    }
    printk("Init ok\n");
/*************************************
    ret = request_irqs();
    if (ret) {
        unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
        printk(DEVICE_NAME " CAN't request irqs\n");
        return ret;
    }
***************************************/
  
    return 0;
}

static void __exit matrix4_buttons_exit(void)
{
        unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
}

module_init(matrix4_buttons_init);
module_exit(matrix4_buttons_exit);
MODULE_LICENSE("GPL");
1: 奇怪怎么就没人回应呢 2: hihi.doya.问个问题,你是用仿真器下载的吗? 3: no我是在uclinux上用NFS下载到板子上然后用ismod加载的。

我不知道是不是能用EXTMODE=0X00来设置中断模式,应该如何清除中断。这些操作在uclinux下的接口是什么?希望大家教教我 4: 要注册中断要用request_irq()函数注册中断,还有,要注意中断的触发模式,是否与你要求的一致,可读相应寄存器的值出来看看对不对.看看<LINUX设备驱动程序>吧,中断那章有详细说明. 5: 写程序一个注释都没有~

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]