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");
}

 

 

 

 

 
posted @ 2024-04-01 02:45  lethe1203  阅读(32)  评论(0编辑  收藏  举报