nirq:标志不匹配irq80.00002083(ledtrig-gpio)对00000083(USER)

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

本文关键字:ledtrig-gpio 00000083 USER 00002083 标志 不匹配 irq80 nirq      更新时间:2023-10-16

我正在SAMA5D27-SOM1-EK1板上做一些实验。我使用的是Linux操作系统。我正在利用我的板GPIOS。在GPIO 10处定义了RED LED,在GPIO 29中定义了USER按钮。我写了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:标志不匹配irq80。00002083(ledtrig gpio)对00000083(用户)指示灯红色:request_irq失败,错误为-16

有人能帮我吗?

现在当我录制时[原文如此]/target_bin按钮它显示了一个错误:

nirq:标志不匹配irq80。00002083(ledtrig gpio)与00000083(USER)led红色:request_irq失败,错误-16

错误16是";设备或资源繁忙">
有问题的设备或资源是按钮的gpio_key
请注意,错误消息中提到";用户";,恰好是分配给设备树文件at91-sama5d27_som1_ek.dts中按钮的gpio_key的label

gpio_keys {
...
pb4 {
label = "USER";
gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>;
...
};
};

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

您可以使用按钮gpio_key作为当前配置的输入事件设备,也可以重新配置gpio 29,使其不是gpio_key并可用作LED触发器。


附录
[对评论的回应]

但是当我搜索设备时;USED";用gpioinfo|grep"[已使用]";命令我发现在我运行程序之前使用了RED led:第10行:";PA10"红色";输出活动高[已使用],但我的代码没有显示错误。

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

为什么它会显示BUTTON的错误。。。

正如我已经解释过的,dts文件将GPIO29(即按钮)配置为GPIO_key,并且将GPIO28分配为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驱动程序建立的现有模式/标志(即0x00000083)冲突
此冲突意味着此GPIO不能同时用于GPIO_key(输入事件)和LED触发器
因此,您必须选择此GPIO的操作模式。

。。。而不是LED?

您的意思是希望错误发生在LED上
执行特定操作时,您无法选择哪个设备会导致错误。

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


为了进一步确认以消除您的疑虑:
由于错误消息提到"irq80〃,您应该查找此"irq80〃在板上的/proc/interrupts文件中
该文件应指示"irq80〃与";GPIO 29〃;(每个DT是gpio_key)。

对于另一个消除疑虑的过程:
找到一个可访问和未使用的未使用PIO引脚(由任何外围设备或任何驱动程序/进程作为gpio)
将该引脚指定为LED触发器
不应出现任何错误(假设您选择了一个未使用的引脚)
将引脚短接至地或VDD_3V3以更改LED的(默认)状态。


如何重新配置按钮USER,使其不是gpio_key并可用作LED触发器?

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