如何通过连接到gpio的按钮控制背光?

时间:2019-04-17 12:11:50

标签: kernel-module yocto gpio backlight

我正在尝试通过连接到gpio的按钮来增加/减少嵌入式Linux(yocto)上的背光值

我一步一步地工作,因此,首先,我添加了一个内核模块,该模块在每次按下按钮时都会产生中断,其工作方式就像一个超级按钮(每次按下按钮时都是printk,该值也可以访问在用户空间中的/ sys / class / gpio / gpio133 / value)

可以在用户空间的/ sys / class / backlight / backlight / brightness中配置背光值。 我将设备树配置为具有8种不同的亮度级别,最大值为0,这也可以工作

然后,我尝试通过添加gpio_request和gpio_get_value来获取内核模块中的背光值,但它始终返回值:0。我认为内核模块无法访问gpio,因为驱动程序已经在使用它负责背光照明,对吗?

由于可以在用户空间中访问gpio和背光的值,因此我编写了一个带有无限循环的shell脚本,该脚本读取gpio状态,如果更改,我将获得背光值并减小背光值。它可以正常工作,但使用了10%以上的CPU。我也有一个带有声音的正在运行的Qt应用程序,当脚本运行时,声音会嘎吱作响。因此,我在其中添加了一个睡眠,以降低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,一个用于降低背光值,另一个用于增加背光值,所以我正在寻找更好的解决方案 任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

gpio-watch正是我想要的。我创建了一个配方,将其添加到我的图层中,并成功交叉编译了该包。但是由于它是一个基于makefile的程序包,因此我很难将其直接安装在映像中。

感谢:https://www.yoctoproject.org/docs/1.8/mega-manual/mega-manual.html#new-recipe-makefile-based-package 我终于设法通过在我的食谱中添加此包来安装该软件包:

 EXTRA_OEMAKE = "'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'CFLAGS=${CFLAGS} -I${S}/include -DWITHOUT_XATTR' 'BUILDDIR=${S}'"

 do_install () {
         oe_runmake install DESTDIR=${D} SBINDIR=${sbindir} MANDIR=${mandir} INCLUDEDIR=${includedir}
 }

再次感谢您的帮助