Как управлять подсветкой кнопкой подключения к gpio? - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь увеличить / уменьшить значение подсветки на встроенном linux (yocto) с помощью кнопки, подключенной к gpio

Я работал шаг за шагом, поэтому, во-первых, я добавил модуль ядра, который генерирует прерывание при каждом нажатии кнопки, это работает как чудо (printk при каждом нажатии кнопки, значение также доступно в пользовательском пространстве по адресу / sys / class / gpio / gpio133 / value)

Значение подсветки настраивается в пользовательском пространстве по адресу / sys / class / backlight / backlight / Brightness. Я настроил дерево устройств на 8 различных уровней яркости со значением 0 в качестве максимума, это также работает

Затем я попытался получить значение подсветки в моем модуле ядра, добавив gpio_request и gpio_get_value, но оно всегда возвращает значение: 0. Я думаю, что модуль ядра не может получить доступ к gpio, потому что он уже используется драйвером в зарядка подсветки, я прав?

Поскольку значения gpio и подсветки доступны в пользовательском пространстве, я написал сценарий оболочки с бесконечным циклом, который считывает состояние gpio, и, если оно меняется, я получаю значение подсветки и уменьшаю его. Это работает, но используется более 10% процессорного времени. У меня также есть работающее приложение 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 голосов
/ 24 апреля 2019

gpio-watch делает именно то, что я хотел. Я создал рецепт, чтобы добавить его в свой слой и успешно скомпилировать пакет. Но так как это пакет на основе make-файла, у меня возникли некоторые трудности с его установкой непосредственно в образ.

благодаря этому: 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}
 }

Еще раз спасибо за вашу помощь

...