nirq:标志不匹配 irq 80。00002083(ledtrig-gpio)与 00000083(用户)

nirq: Flags mismatch irq 80. 00002083 (ledtrig-gpio) vs. 00000083 (USER)

我正在 SAMA5D27-SOM1-EK1 板上做一些实验。我正在使用 Linux 操作系统。我正在利用我的板的 GPIOS。 RED LED 定义在 GPIO 10USER button 定义在 GPIO 29 。我写了 C++ 程序来控制电路板的 LED,代码如下:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

#define LED0_PATH "/sys/class/leds/red"

void removeTrigger(){
   // remove the trigger from the LED
   std::fstream fs;
   fs.open( LED0_PATH "/trigger", std::fstream::out);
   fs << "none";
   fs.close();
}

int main(int argc, char* argv[]){
   if(argc!=2){
 cout << "Usage is makeLED and one of: on, off, flash or status"
<< endl;
 cout << "e.g. makeLED flash" << endl;
   }

   string cmd(argv[1]);
   std::fstream fs;
   cout << "Starting the LED flash program" << endl;
   cout << "The LED Path is: " << LED0_PATH << endl;


 // select whether it is on, off or flash
   if(cmd=="on"){
 removeTrigger();
 fs.open (LED0_PATH "/brightness", std::fstream::out);
 fs << "1";
 fs.close();
   }

   else if (cmd=="off"){
 removeTrigger();
 fs.open (LED0_PATH "/brightness", std::fstream::out);
 fs << "0";
 fs.close();
   }

   else if (cmd=="flash"){
 fs.open (LED0_PATH "/trigger", std::fstream::out);
 fs << "timer";
 fs.close();
 fs.open (LED0_PATH "/delay_on", std::fstream::out);
 fs << "50";
 fs.close();
 fs.open (LED0_PATH "/delay_off", std::fstream::out);
 fs << "50";
 fs.close();
   }

   else if (cmd=="status"){
 // display the current trigger details
 fs.open( LED0_PATH "/trigger", std::fstream::in);
 string line;
 while(getline(fs,line)) cout << line;
 fs.close();
 }

   else{
 cout << "Invalid command" << endl;
 }

cout << "Finished the LED flash program" << endl;
       return 0;

这似乎工作正常:当我录制 ./target_bin off 时,红色 LED 关闭,onflash 命令也是如此。

但是当我尝试用 BUTTON (USER/GPIO 29) 控制 LED (RED/GPIO 10) 时,我添加了这部分代码:

else if (cmd=="button"){
        removeTrigger();
        fs.open (LED0_PATH "/trigger", std::fstream::out);
        fs << "gpio";
        fs.close();
        fs.open (LED0_PATH "/gpio", std::fstream::out);
        fs << "29";
        fs.close();
   }

现在当我录音时 ./target_bin button 它显示了一个错误:

nirq: Flags mismatch irq 80. 00002083 (ledtrig-gpio) vs. 00000083 (USER) leds red: request_irq failed with error -16

有人可以帮我吗?

And now when I tape [sic] ./target_bin button It shows me an error :

nirq: Flags mismatch irq 80. 00002083 (ledtrig-gpio) vs. 00000083 (USER) leds red: request_irq failed with error -16

错误 16 是“设备或资源繁忙”。
有问题的设备或资源是按钮的 gpio_key。
请注意,错误消息提到“USER”,恰好是分配给设备树文件 .

中按钮的 gpio_key 的 label
gpio_keys {
    ...
    pb4 {
        label = "USER";
        gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>;
        ...
    };
};

为了将 GPIO 29 用作 LED 触发器,它必须是可用的,即未使用的 GPIO。
然而,默认的 dts 文件将 GPIO 29 配置为 gpio_key,因此该 GPIO 由 gpio_key 驱动程序拥有。
GPIO 29 不是未使用的引脚,不能用作 LED 触发器(即所有权不能转移到 ledtrig-gpio 驱动程序)。

您可以将按钮 gpio_key 用作当前配置的 ,或者重新配置 GPIO 29,使其不是 gpio_key 并可用作一个 LED 触发器。


附录
[对评论的回应]

But when i search for the devices which are " USED " on my board with gpioinfo | grep "[used]" command I find that RED led is used before I run my program : line 10: "PA10" "red" output active-high [used] but my code does not show an error for it.

您是在抱怨没有收到 LED 错误吗?
我不明白你想表达什么观点。

Why would it show an error for BUTTON ...

正如我已经解释过的,dts 文件将 GPIO 29(即按钮)配置为 gpio_key,并将 GPIO 29 分配为 LED 触发器 会导致冲突。

更具体地说,LED 触发驱动器 (ledtrig-gpio) 要求将中断配置为“单次”模式。

 * IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
 *                Used by threaded interrupts which need to keep the
 *                irq line disabled until the threaded handler has been run.
 ...
#define IRQF_ONESHOT        0x00002000

此(新)中断模式(即 0x00002083)与 gpio_keys 驱动程序建立的现有 mode/flags(即 0x00000083)冲突。
此冲突意味着此 GPIO 不能同时用于 gpio_key(输入事件)和 LED 触发器。
因此,您必须选择此 GPIO 将在哪种模式下运行。

... and not for LED ?

您是说您希望 LED 出现错误?
当您执行特定操作时,您无法选择哪个设备会导致错误。

您请求的操作,即分配一个特定的 GPIO(已安装为 gpio_key)作为 LED 触发器,在分配期间失败gpio_key.
的(新)中断处理程序 因此报告的错误是 gpio_key,而不是 LED。


进一步确认以消除您的疑虑:
由于错误消息提到 "irq 80",您应该在 /proc/interrupts 中查找此 "irq 80" ] 文件在你的板上。
该文件应表明 "irq 80" 与“GPIO 29”相关联(根据 DT 是 gpio_key)。

还有一个程序可以消除您的疑虑:
找到一个可访问且未使用的未使用 PIO 引脚(由任何外设或任何 driver/process 作为 gpio)。
将该引脚指定为 LED 触发器。
应该不会出现错误(假设您选择了一个未使用的引脚)。
将引脚接地或 VDD_3V3 以更改 LED 的(默认)状态。


How can I reconfigure the button USER so that it is not a gpio_key and be available for use as a LED trigger ?

正如我已经写过的,设备树文件 at91-sama5d27_som1_ek.dts 是将带有按钮的 GPIO 声明为 gpio_key 的地方,我还发布了该节点的突出部分的片段。
如果您不希望将该 GPIO 配置为 gpio_key,则需要通过删除该节点来修改设备树文件(当然还要重新编译成 dtb) .