Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM9260+Linux, опрос пинов процессора
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Kris2007
Нужно опрашивать пины процессора(предположим на них кнопки) из Linux.
Как это проще всего сделать? Где почитать про сие можно?
Idle
стандартно вот так: http://lxr.linux.no/#linux+v2.6.39/Documentation/gpio.txt
http://www.avrfreaks.net/wiki/index.php/Do...tion:Linux/GPIO
не уверен, есть ли драйвер для этого процессора
Kris2007
Спасибо!
Не подскажете еще как лучше сделать - опрашивать пины как-то в "цикле" или разрешить прерывания по изменению пинов (3-8 пинов)?

Просто в linux не писал ничего низкоуровневого, а под микроконтроллеры с этим как-то вообще проблем не было(опрос+пауза для дребезга например).
sasamy
Цитата(Kris2007 @ Jun 24 2011, 15:34) *
Спасибо!
Не подскажете еще как лучше сделать - опрашивать пины как-то в "цикле" или разрешить прерывания по изменению пинов (3-8 пинов)?

Просто в linux не писал ничего низкоуровневого, а под микроконтроллеры с этим как-то вообще проблем не было(опрос+пауза для дребезга например).


http://lxr.free-electrons.com/source/arch/...am9260ek.c#L281

назнчаете вместо
Код
.code           = BTN_3,


любой код отсюда
http://lxr.free-electrons.com/source/include/linux/input.h

и получаете готовое стандартное устройство ввода
Idle
ага,
Цитата
Note that standard kernel drivers exist for common "LEDs and Buttons"
GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those
instead of talking directly to the GPIOs; they integrate with kernel
frameworks better than your userspace code could
xor.kruger
Вот пример управления пином к которому подключен светодиод с помощью системного вызова mmap

Код
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>

#define PC22   (1 << 22)
#define MAP_SIZE 4096Ul
#define MAP_MASK (MAP_SIZE - 1)
#define PIOA_BASE 0xFFFFF400
#define PIOB_BASE 0xFFFFF600
#define PIOC_BASE 0xFFFFF800
#define PIOD_BASE 0xFFFFFA00
typedef volatile unsigned int AT91_REG;
typedef struct _AT91S_PIO {
    AT91_REG PIO_PER;           /* PIO Enable Register */
    ...
    AT91_REG PIO_OWSR;          /* Output Write Status Register */
} AT91S_PIO, *AT91PS_PIO;

AT91S_PIO *pio_map(unsigned int piobase)
{
    int fd;      //дискриптор файла-псевдоустройства /dev/mem
    void *base; //начальный адрес области памяти,
             //в которую отображен /dev/mem
    AT91S_PIO *pio; //структура регистров порта GPIO
    off_t addr = piobase; //базовый адрес порта GPIO
    if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
    {
        fprintf(stderr, "Cannot open /dev/mem.\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stderr, "/dev/mem opened.\n");
    base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
                fd, addr & ~MAP_MASK);
    if (base == (void *) -1)
    {
        fprintf(stderr, "Cannot open /dev/mem.\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stderr, "Memory mapped at address %p.\n", base);
    pio = base + (addr & MAP_MASK); //«корректировка» адреса
                              //порта GPIO
    return pio;
}
void pio_enable(AT91S_PIO * pio, int mask)
{
    pio->PIO_PER = mask;        /* Enable PIO */
}
void pio_output_enable(AT91S_PIO * pio, int mask)
{
    pio->PIO_OER = mask;        
}
void pio_out(AT91S_PIO * pio, int mask, int val)
{
    if (val == 0)
        pio->PIO_CODR = mask;
    else
        pio->PIO_SODR = mask;
}
int pio_in(AT91S_PIO * pio, int mask)
{
    return (pio->PIO_PDSR & mask);
}
int main(void)
{
    int state = 0;
    unsigned int mask = PC22;
    AT91S_PIO *pioc;
    pioc = pio_map(PIOC_BASE);
    pio_enable(pioc, mask);
    pio_output_enable(pioc, mask);
    while (1)
    {
        pio_out(pioc, PC22, state);
        state = !state;
        usleep(1 * 1000 * 1000);
    }
  return 0;
}


А вот пример обработки нажатия кнопки через драйвер:

Код
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <mach/gpio.h>

#define LED AT91_PIN_PB7

static irqreturn_t btn_int(int irq, void *dev_id)
{
  if (at91_get_gpio_value(AT91_PIN_PA24) == 1)
  {
      printk(KERN_ALERT "111");
      at91_set_gpio_value(LED, 0);
  }
  else
  {
    at91_set_gpio_value(LED, 1);
  }

  return IRQ_HANDLED;
}

static __init int driver_init(void)
{
  printk(KERN_ALERT "driver init start...\n");
  at91_set_gpio_output(LED, 1);
  at91_set_gpio_value(LED, 0);
  at91_set_gpio_input(AT91_PIN_PA24, 1);
  at91_set_deglitch(AT91_PIN_PA24, 1);
  if (request_irq(AT91_PIN_PA24, btn_int, 0, "btn_int", NULL))
  {
    printk(KERN_ALERT "request_irq error\n");
    return -EBUSY;
  }
  return 0;
}

static __exit void driver_exit(void)
{
  free_irq(AT91_PIN_PA24, NULL);
  printk(KERN_ALERT "driver exit\n");
}

module_init(driver_init);
module_exit(driver_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("External Interrupt driver");

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.