18, Interrupt independent key

1, Introduction

Interrupt: it means that the CPU needs to stop the execution of the current program, transfer to deal with emergencies, and return to the original program after processing.
 

Interrupt source: refers to the cause of an interrupt.
 

Hardware interrupt: generally refers to the interrupt request sent by the peripheral and the interrupt generated by the internal hardware (calculation overflow, divisor 0, power failure, etc.)


Software interrupt:   Typically, the lower half of the interrupt handler operates
 

Classification of hardware interrupts
Internal interrupt: interrupt generated by internal hardware (for example, divisor is 0)
External interrupt: interrupt generated by peripheral (key)
 

Trigger mode of external interrupt
Rising edge trigger and falling edge trigger level trigger
 

Interrupt priority
According to the importance and urgency of interrupt events, the system divides interrupt sources into several levels, and the one with high priority shall be executed first.

Interrupt handling function
A piece of code executed after an interrupt is generated.

Interrupt vector number
The identification mark of the interrupt source is to jump to the "entry address" of the interrupt program.

Interrupt vector and non interrupt vector
The hardware provides the address of the interrupt handling function
After passing the judgment, the software provides the final address of the interrupt processing function

Judgment method of vector interrupt and non vector interrupt
Generally, an interrupt number corresponds to an interrupt function, which is a vector interrupt (independent key). Multiple interrupt functions share an interrupt number (matrix keyboard)
 

Interrupt handler architecture
There are many interrupts in the operating system. It is impossible to execute backward after all interrupts are processed, so the interrupt handler is divided into the upper half and the lower half. The upper half is generally hardware related code, and the lower half is generally time-consuming operations.
For example, inserting a U SB flash disk into a PC will generate an interrupt. After receiving it, the hardware will respond immediately. The interrupt operation will quickly execute the upper part, and then notify the upper part of the system to call the corresponding driver. The procedure driven by the later call can be called the lower half.


2, Key schematic diagram

  3, Driver code

Interrupt request function
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
There are the following parameters.
Parameter unsigned int irq: irq is the interrupt number
Parameter irq_handler_t handler: handler is the processing function registered with the system
Parameter unsigned long flags: irqflags is the trigger flag bit(

                                                                                / Irq_type_edge_rising

                                                                                / Irq_type_edge_both

                                                                                / Irq_type_level_high

                                                                                /  Irq_type_level_low

                                                                                / IRQ_TYPE_SIMPLE(Simple interrupt)

                                                                                / Irq_type_per CPU interrupt:
)
Parameter const char *name: devname is the interrupt name, which can be viewed through "cat /proc/interrupts" after registration
Parameter void *dev: dev_id is the device
Corresponding to the above interrupt application function is the interrupt release function free_irq, which needs to be called when unloading the driver, as shown in the following figure, which is also in the header file "include/linux/interrupt.h".

#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
//#include <mach/gpio-bank.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/regulator/consumer.h>
//#include "gps.h"
#include <linux/delay.h>

//Interrupt header file
#include <linux/irq.h>
#include <linux/interrupt.h>

#define DPRINTK(x...) printk("keyirq DEBUG:" x)

#define DRIVER_NAME "keyirq"

static irqreturn_t eint9_interrupt(int irq,void *dev_id)
{
	printk("receive a interrupt 9!\n");
	return IRQ_HANDLED;
}

static irqreturn_t eint10_interrupt(int irq,void *dev_id)
{
	printk("receive a interrupt 10!\n");
	return IRQ_HANDLED;
}

static int keyirq_probe(struct platform_device *pdev)
{
	//int ret, i;
	char *banner = "keyirq Initialize\n";
	printk(banner);
	//Registration interruption
	request_irq(IRQ_EINT(9),eint9_interrupt,IRQ_TYPE_EDGE_FALLING,"my_eint9",pdev);
	request_irq(IRQ_EINT(10),eint10_interrupt,IRQ_TYPE_EDGE_FALLING,"my_eint10",pdev);
	
	return 0;
}

static int keyirq_remove (struct platform_device *pdev)
{
	free_irq(IRQ_EINT(9),pdev);
	free_irq(IRQ_EINT(10),pdev);
	
	return 0;
}

static int keyirq_suspend (struct platform_device *pdev, pm_message_t state)
{
	DPRINTK("keyirq suspend:power off!\n");
	return 0;
}

static int keyirq_resume (struct platform_device *pdev)
{
	DPRINTK("keyirq resume:power on!\n");
	return 0;
}

static struct platform_driver keyirq_driver = {
	.probe = keyirq_probe,
	.remove = keyirq_remove,
	.suspend = keyirq_suspend,
	.resume = keyirq_resume,
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
	},
};

static void __exit keyirq_exit(void)
{
	platform_driver_unregister(&keyirq_driver);
}

static int __init keyirq_init(void)
{
	return platform_driver_register(&keyirq_driver);
}

module_init(keyirq_init);
module_exit(keyirq_exit);
MODULE_LICENSE("Dual BSD/GPL");

4, Add device

vim arch/arm/mach-exynos/mach-itop4412.c

 

  5, Run

   cat /proc/interrupts (view interrupts)

 

Tags: Linux

Posted on Fri, 26 Nov 2021 01:11:45 -0500 by daeken