qq_38839860 2024-06-13 16:11 采纳率: 40%
浏览 37

GPIO中断无法绑定CPU问题

我在RK3568平台上申请了GPIO作为中断代码如下:

无法将中断绑定在其他CPU上
第一种方法:echo 2>/proc/irg/78/smp_affinity
 这种方法试了提示sh: write error: Input/output error
第二种方法:
#include <linux/irq.h>
#include <linux/cpumask.h>

void bind_irq_to_cpu0(unsigned int irq) {
    cpumask_var_t cpumask;
    if (!alloc_cpumask_var(&cpumask, GFP_KERNEL))
        return;

    cpumask_set_cpu(0, cpumask); 
    irq_set_affinity(irq, cpumask); 
    free_cpumask_var(cpumask);
}
请问有懂得大佬吗?讲一下。

&{/} {
    button_interrupt: button_interrupt {
        status = "okay";
        compatible = "button_interrupt";
        pinctrl-names = "default";
        pinctrl-0 = <&button_interrupt_pin>;
        interrupt-parent = <&gpio0>;
        interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
        interrupt-affinity = <&cpu3>;
        button-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
    };
};

&{/pinctrl} {
    button_interrupt {
        button_interrupt_pin: button_interrupt_pin {
            rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
        };
    };
};
/*获取按键 设备树节点*/
button_device_node = of_find_node_by_path("/button_interrupt");
if(NULL == button_device_node)
{
    printk("of_find_node_by_path error!");
    return -1;
}

/*获取按键使用的GPIO*/
button_GPIO_number = of_get_named_gpio(button_device_node ,"button-gpios", 0);
if(!button_GPIO_number)
{
    printk("of_get_named_gpio error");
    return -1;
}
printk("button_GPIO_number = %d \n", button_GPIO_number);

/*申请GPIO  , 记得释放*/
error = gpio_request(button_GPIO_number, "button_gpios");
if(error < 0)
{
    printk("gpio_request error");
    gpio_free(button_GPIO_number);
    return -1;
}

error = gpio_direction_input(button_GPIO_number);//设置引脚为输入模式

/*获取中断号*/
interrupt_number = irq_of_parse_and_map(button_device_node, 0);
printk("\n irq_of_parse_and_map =  %d \n",interrupt_number);


/*申请中断, 记得释放*/
error = request_irq(interrupt_number,button_irq_hander,IRQF_TRIGGER_FALLING,"button_interrupt",NULL);
if(error != 0)
{
    printk("request_irq error");
    free_irq(interrupt_number, NULL);
    return -1;
}
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-13 16:11
    关注

    引自免费微信小程序:皆我百晓生

    针对你遇到的问题,即在RK3568平台上尝试将GPIO中断绑定到特定CPU核心时遇到的障碍,这里提供一种可能的解决方案。首先,我们来分析一下你所提及的两种方法,并提出相应的调整建议。

    方法一:通过 /proc 文件系统修改中断亲和性

    你提到使用 echo 2>/proc/irq/78/smp_affinity 的方式来修改中断亲和性,但遇到了I/O错误。这通常意味着目标文件不可写,或者系统配置阻止了这种修改。确保你的系统内核支持动态调整中断亲和性,且你有足够权限进行此类操作。

    解决方案:

    • 确认内核配置中是否启用了动态调整中断亲和性的选项。
    • 使用 root 权限执行命令,确保有足够的权限。

    方法二:通过内核API修改中断亲和性

    你展示的C代码试图通过 irq_set_affinity() 函数来设置中断亲和性,这是一个有效的方法,但需要注意函数的正确使用。

    解决方案:

    代码本身看起来是合理的,但是为了确保没有遗漏,这里给出一个完整的示例函数,用于将中断绑定到特定CPU(例如,CPU 0):

    #include <linux/irq.h>
    #include <linux/cpumask.h>
    
    void bind_irq_to_cpu(unsigned int irq, unsigned int cpu_id) {
        struct cpumask *cpumask;
        cpumask = cpumalloc_node(NODE_DEFAULT);
        if (!cpumask)
            return;
    
        cpumask_clear(cpumask);
        cpumask_set_cpu(cpu_id, cpumask);
        irq_set_affinity(irq, cpumask);
        cpufree(cpumask);
    }
    

    使用这个函数,你可以将任何中断绑定到特定的CPU,只需传递中断号和目标CPU的ID作为参数。

    设备树配置

    你提供的设备树片段看起来是正确的,用于定义一个按钮中断,其中 interrupt-affinity 字段指定中断应绑定的CPU(在这个例子中是 CPU3)。然而,要确保设备树中的其他部分也正确配置,包括中断控制器和其他必要的配置。

    总结

    1. 确认内核配置:确保你的内核支持动态调整中断亲和性。
    2. 检查权限:如果你选择使用 /proc 文件系统的方法,确保你有足够的权限。
    3. 使用内核API:使用 bind_irq_to_cpu 函数(或类似功能)来安全地调整中断亲和性。
    4. 检查设备树:确保设备树正确配置,特别是与中断和GPIO相关的部分。

    希望上述信息能帮助你解决当前的问题。如果还有其他疑问或遇到新的问题,随时提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月13日

悬赏问题

  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振
  • ¥20 pip2.40更新pip2.43时报错
  • ¥15 换yum源但仍然用不了httpd
  • ¥50 C# 使用DEVMOD设置打印机首选项