GPIO interrupt program under ARM-Linux

Publisher:脑洞狂想Latest update time:2019-04-22 Source: eefocusKeywords:ARM Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

       In order to debug the GPIO pin interrupt effect on the ARM board, so that in the subsequent project, when using ARM and the ZLG7290 key LED interrupt chip to connect, I can arbitrarily select the idle GPIO pin as the interrupt signal line of the ZLG7290. I specially wrote a small Linux GPIO interrupt driver and downloaded it to the development board for experiment. It has been verified that this software interrupt method is also not satisfactory. The following is the immature code I wrote, please forgive me (


       The hardware circuit of the experiment is that PB17 of ARM GPIO is connected to a common cathode LED, PB18 is connected to PB19, PB18 is set to low level trigger by interrupt driver, PB19 is controlled by GPIO driver, and the upper-level application controls the high and low level changes of PB19 by driving, thereby triggering an interrupt of PB18, and the LED of PB17 is controlled to turn on and off in the interrupt program.


      Linux interrupt driver part:

/*

 * PB18_IRQTest.c

 * This is  a test program for sam9260, using PB19(J5_18 pin) input a signal to PB18(J5_16 pin),

 * PB18 receive this signal as IRQ and make the LED linking on PB17((J5_14 pin)) turn on or turn off   

 *

 *           @Author: Cun Tian Rui 

 *           @Date :March.18.2011

 */


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


void led_on()

{    

     at91_set_gpio_output(AT91_PIN_PB17,1);

}


void led_off()

{    

     at91_set_gpio_output(AT91_PIN_PB17 ,0);

}


struct light_dev *light_devp;

int light_major = 200;


struct light_dev

{

    struct cdev cdev;

    unsigned char value;

};


MODULE_AUTHOR("Cun Tian Rui");

MODULE_LICENSE("Dual BSD/GPL");



static void io_init(void)

{

    at91_set_gpio_input(AT91_PIN_PB18, 1);        

    at91_set_deglitch(AT91_PIN_PB18, 1); 

    at91_sys_write(1 + PIO_IDR,  1<<18);

    at91_sys_write(1 + PIO_IER,  (~(1<<18)));

    at91_sys_write(AT91_PMC_PCER, 1 << 3);

}



struct gpio_irq_desc

{

int irq;

unsigned long flags;

char *name;

};


static struct gpio_irq_desc PB18_IRQ={AT91_PIN_PB18,AT91_AIC_SRCTYPE_LOW,"PB18"};


static irqreturn_t PB18_intHandle(int irq, void *dev_id)

{

led_on();

return IRQ_RETVAL(IRQ_HANDLED);

}


int light_open(struct inode *inode,struct file *filp)

{

    int err;

    struct light_dev *dev;

    dev = container_of(inode->i_cdev,struct light_dev,cdev);

    filp->private_data = dev;

    io_init();

    err = request_irq(PB18_IRQ.irq,PB18_intHandle,PB18_IRQ.flags,PB18_IRQ.name,(void*)0);

    if(err) 

    {

free_irq(PB18_IRQ.irq,(void*)0);

return -BUSY;

}

    return 0;

}


int light_release(struct inode *inode,struct file *filp)

{

free_irq(PB18_IRQ.irq,(void*)0);

return 0;    

}




// ioctl

int light_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,

unsigned long arg)

{

    struct light_dev *dev = filp->private_data;


    switch(cmd)

    {

        case 0:

            at91_set_gpio_output(AT91_PIN_PB19,0);     

        break;


        case 1:

          at91_set_gpio_output(AT91_PIN_PB19,1);

   led_off();

        break;


        default:


            return -ENOTTY;

        // break;

    }


    return 0;

}     


struct file_operations light_fops = 

{

    .owner = THIS_MODULE,

    .ioctl = light_ioctl,

    .open  = light_open,

    .release = light_release,

};



static void light_setup_cdev(struct light_dev *dev,int index)

{

    int err,devno = MKDEV(light_major,index);


    cdev_init(&dev->cdev,&light_fops);

    dev->cdev.owner = THIS_MODULE;

    dev->cdev.ops = &light_fops;


    err = cdev_add(&dev->cdev,devno,1);


    if(err)

    {

        printk(KERN_NOTICE "Error %d adding LED%d",err,index);

    }

}



int light_init(void)

{

    int result;


    dev_t dev = MKDEV(light_major,0);

    if(light_major)

    {

        

        result = register_chrdev_region(dev,1,"PB18_IRQTest");

    }


    if(result < 0)

    {

        return result;

    }


    light_devp = kmalloc(sizeof(struct light_dev),GFP_KERNEL);

    if(!light_devp)

    {

        result = - ENOMEM;

        goto fail_malloc;

    }


    memset(light_devp,0,sizeof(struct light_dev));

    light_setup_cdev(light_devp,0);

    


    return 0;


    fail_malloc:unregister_chrdev_region(dev,light_devp);

    return result;

    

}


void light_cleanup(void)

{

    cdev_del(&light_devp->cdev);   

    kfree(light_devp);

    unregister_chrdev_region(MKDEV(light_major,0),1);  

}


module_init(light_init);

module_exit(light_cleanup);

    Linux upper layer applications:

#include

//#include

#include

#include

#include

#include

#include

#include

#include

#include



int main(int argc ,char *argv[])

{

int fd;

        char input;

 fd = open("/dev/PB18_IRQTest",O_RDWR);

if(fd < 0)

  {

perror("open PB18_IRQTest device");

     return 0;

}

while(1)

{

     printf("input 0 to trigger int/n");

     scanf("%c",&input);

     switch(input)

     {

case '0':

                    ioctl(fd,0,0);

printf("/n");

break;

case '1':

ioctl(fd,1,0);

printf("/n");

break;

        default:

printf("/n");

                break;                             

                     }

                 }                                        

                  return 0;

}

     As can be seen from the above code, the Linux kernel has made a lot of abstractions in interrupt program processing. Driver writers only need to implement certain control functions according to the kernel interrupt architecture. In the future, I will write a special article to analyze and restore the abstractions of interrupt implementation in the Linux kernel.

Keywords:ARM Reference address:GPIO interrupt program under ARM-Linux

Previous article:How to determine the address space used by peripherals
Next article:Solution to LPC2378 serial port query and send lost data

Recommended ReadingLatest update time:2024-11-15 15:23

Foreign media: Many technology giants oppose Nvidia's acquisition of ARM, including Intel, Qualcomm, etc.
According to fudzilla, multiple sources revealed that many Silicon Valley technology companies opposed Nvidia's acquisition of ARM. In addition to ARM and Nvidia, many technology companies said that the deal was not good for the industry. Fudzilla pointed out that given that it traditionally takes 18 to 24 months to
[Mobile phone portable]
22 commonly used concepts of ARM!
1. Explanation of some common English abbreviations in ARM MSB: most significant bit; LSB: least significant bit; AHB: Advanced High-Performance Bus; VPB: VLSI peripheral bus that connects on-chip and off-chip functions; EMC: External Memory Controller; MAM: Memory Acceleration Module; VIC: Vectored Inte
[Microcontroller]
ARM study notes 4 - load and store instructions
1. Word data transfer instruction Function: Used to transfer single data into or out of a register.   1. LDR instruction     1.1. Function       Read a 32-bit field from memory to the target register Rd according to the address mode determined by addr_mode . If the address determined by the addressing mode in the in
[Microcontroller]
ARM study notes 4 - load and store instructions
Eclipse development and debugging of ARM bare metal programs (VI) About bare metal debugging i2c records
        Regarding bare metal debugging i2c record, I encountered many problems. Now they have been solved. Record them.   1. Overall planning         Since I am learning the function of a certain hardware, I think I should be able to do it with the simplest code without involving other hardware. So my plan is
[Microcontroller]
Eclipse development and debugging of ARM bare metal programs (VI) About bare metal debugging i2c records
OK6410A development board (eight) 2 linux-5.11 OK6410A linux development environment construction
Code : https://github.com/lisider/linux/tree/ok6410a-linux-5.11 Submit id : 4459e78a4d845f08286623b98546bcefbb45ddb9 defconfig : arch/arm/configs/ok6410A_sdboot_mini_net_defconfig To achieve u-boot tftp uImage  uImage network mounted root file system 1 TFTP server and client installation 2 NFS Server Installa
[Microcontroller]
ARM9 mini2451 bare metal learning - NAND flash driver learning 2
In the previous article, we mainly learned the basic knowledge of NAND Falsh. Today, we will summarize the initialization of NAND Flash, as well as block erase, page read and write operations, and the acquisition of chip ID number. 6. NAND FLASH operation interface We know that functions need to use a stack when t
[Microcontroller]
ARM9 mini2451 bare metal learning - NAND flash driver learning 2
ARM assembly instruction set 1
(Assembly) instructions are mnemonics for CPU machine instructions. After compilation, they will produce a string of machine codes consisting of 0011, which can be read and executed by the CPU. (Assembly) Pseudo-instructions are not instructions in essence (they are just written in the code together with instruction
[Microcontroller]
Keil4 compiles when RL-ARM is not allowed with this license
Recently, when I used MDK to compile someone else's project, I got the following prompt: The reason is that Real-Time OS is not registered; Solution: Open the MDK registration machine, set it as above, generate a serial number, and register Real-Time OS; Note: CID is copied from file- license Management of MD
[Microcontroller]
Keil4 compiles when RL-ARM is not allowed with this license
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号