我正在尝试使用连接到 gpio 的按钮来增加/减少嵌入式 linux (yocto) 上的背光值
我一步一步地工作,所以,首先,我添加了一个内核模块,每次按下按钮时都会产生一个中断,它的工作就像一个魅力(每次按下按钮时打印k,该值也可以在用户空间访问/sys/class/gpio/gpio133/值)
背光值可在用户空间中的 /sys/class/backlight/backlight/brightness 中配置。我将设备树配置为具有 8 个不同级别的亮度,最大值为 0,这也有效
然后我尝试通过添加 gpio_request 和 gpio_get_value 来获取内核模块中的背光值,但它总是返回值:0。我认为内核模块无法访问 gpio,因为它已被负责的驱动程序使用背光,我说的对吗?
由于 gpio 和背光的值可以在用户空间中访问,我编写了一个带有无限循环的 shell 脚本,它读取 gpio 状态,如果它改变了,我得到背光值并减少它。它可以工作,但它使用了超过 10% 的 cpu。我还有一个正在运行的带有声音的 Qt 应用程序,当脚本运行时,声音会噼啪作响。因此,我在其中添加了一个 sleep 以减慢 gpio 状态的读取速度,其持续时间刚好足以避免爆裂声,但是现在,有时,由于睡眠而错过了按钮按下。
这是没有任何尝试控制背光的工作内核模块:
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Button test management");
MODULE_VERSION("0.1");
static unsigned int GPIO_BUTTON_LUM_PLUS = 133;
static unsigned int irqNumber;
static irq_handler_t ebbgpio_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs);
static int __init ebbgpio_init (void)
{
int result=0;
printk(KERN_INFO "GPIO_TEST: Initializing the GPIO_TEST LKM\n");
if (!gpio_is_valid(GPIO_BUTTON_LUM_PLUS))
{
printk(KERN_INFO "GPIO_TEST: invalid Button GPIO LKM\n");
return -ENODEV;
}
gpio_request(GPIO_BUTTON_LUM_PLUS, "sysfs");
gpio_direction_input(GPIO_BUTTON_LUM_PLUS);
gpio_set_debounce(GPIO_BUTTON_LUM_PLUS, 200);
gpio_export(GPIO_BUTTON_LUM_PLUS, false);
printk(KERN_INFO "GPIO_TEST: the button state is currently: %d\n", gpio_get_value(GPIO_BUTTON_LUM_PLUS));
irqNumber = gpio_to_irq(GPIO_BUTTON_LUM_PLUS);
printk(KERN_INFO "GPIO_TEST: the button is mapped to IRQ: %d\n", irqNumber);
result = request_irq(irqNumber, (irq_handler_t) ebbgpio_irq_handler, IRQF_TRIGGER_RISING, "ebb_gpio_handler", NULL);
printk(KERN_INFO "GPIO_TEST: The interrupt request result is: %d\n", result);
return result;
}
static void __exit ebbgpio_exit(void)
{
printk(KERN_INFO "GPIO_TEST: The button state is currently: %d\n", gpio_get_value(GPIO_BUTTON_LUM_PLUS));
gpio_unexport(GPIO_BUTTON_LUM_PLUS);
free_irq(irqNumber, NULL);
gpio_free(GPIO_BUTTON_LUM_PLUS);
}
static irq_handler_t ebbgpio_irq_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_INFO "GPIO_TEST: Interrupt! (button state is %d)\n", gpio_get_value(GPIO_BUTTON_LUM_PLUS));
return (irq_handler_t) IRQ_HANDLED;
}
module_init(ebbgpio_init);
module_exit(ebbgpio_exit);
将来我将需要读取 2 gpio,一个用于降低背光值,另一个用于增加值,所以我正在寻找更好的解决方案任何帮助将不胜感激