SMP PPI中断使用
SPI作为共享中断,直接使用request_irq等函数注册中断处理函数即可
对于SMP系统PPI中断来说,就需要为每个core都注册一个中断处理函数,相关处理函数如下:
int smp_call_function(void (*func)(void *info), void *info, int retry, int wait); // 参数说明 func 参数是指向要执行的函数的指针。 info 参数是一个可选的参数指针,可以传递给被调用的函数。 retry 参数指定了在发生错误时重试的次数。如果为 0,则不会重试。 wait 参数指示是否等待所有 CPU 完成函数的执行。如果为 0,则该函数立即返回,不等待所有 CPU 完成执行。如果为非零,则该函数会等待所有 CPU 完成执行。 int smp_call_function_single(int cpu, void (*func)(void *info), void *info, int retry, int wait); // 参数说明 cpu 参数是要执行函数的 CPU 核心编号。 func 参数是指向要执行的函数的指针。 info 参数是一个可选的参数指针,可以传递给被调用的函数。 retry 参数指定了在发生错误时重试的次数。如果为 0,则不会重试。 wait 参数指示是否等待指定 CPU 完成函数的执行。如果为 0,则该函数立即返回,不等待 CPU 完成执行。如果为非零,则该函数会等待指定 CPU 完成执行。 int request_percpu_irq(unsigned int irq, irq_handler_t handler, const char *devname, void *dev_id); // 参数说明 irq:要请求的中断号。 handler:中断处理函数,当中断事件发生时被调用。 devname:与中断相关联的设备的名称,用于调试和记录目的。 dev_id:传递给中断处理函数的设备标识符。
使用demo如下:
#include <linux/interrupt.h> #include <linux/smp.h> #define IRQ_NUM_BASE 10 // PPI中断号,irq而非hwirq // 中断处理函数 static irqreturn_t my_interrupt_handler(int irq, void *dev_id) { // 中断事件发生时执行的处理代码 return IRQ_HANDLED; } // 在指定 CPU 上注册基于 CPU 的中断 static int register_percpu_irq_on_cpu(void *info) { int cpu = smp_processor_id(); int irq_num = IRQ_NUM_BASE + cpu; int ret; // 请求分配一个基于 CPU 的中断 ret = request_percpu_irq(irq_num, my_interrupt_handler, "my_device", NULL); if (ret) { printk(KERN_ERR "Failed to request percpu IRQ %d on CPU %d: %d\n", irq_num, cpu, ret); return ret; } printk(KERN_INFO "Successfully requested percpu IRQ %d on CPU %d\n", irq_num, cpu); return 0; } // 初始化模块 int init_module(void) { int ret; // 在每个 CPU 核心上注册基于 CPU 的中断 ret = smp_call_function(register_percpu_irq_on_cpu, NULL, 1); if (ret) { printk(KERN_ERR "Failed to register percpu IRQ on all CPUs: %d\n", ret); return ret; } printk(KERN_INFO "Module initialized\n"); return 0; } // 清理模块 void cleanup_module(void) { int cpu; // 释放在每个 CPU 核心上注册的中断资源 for_each_possible_cpu(cpu) { free_percpu_irq(IRQ_NUM_BASE + cpu, NULL); } printk(KERN_INFO "Module unloaded\n"); }