Перейти к содержанию
    

AT91SAM9260+Linux, опрос пинов процессора

Нужно опрашивать пины процессора(предположим на них кнопки) из Linux.

Как это проще всего сделать? Где почитать про сие можно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

стандартно вот так: http://lxr.linux.no/#linux+v2.6.39/Documentation/gpio.txt

http://www.avrfreaks.net/wiki/index.php/Do...tion:Linux/GPIO

не уверен, есть ли драйвер для этого процессора

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо!

Не подскажете еще как лучше сделать - опрашивать пины как-то в "цикле" или разрешить прерывания по изменению пинов (3-8 пинов)?

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо!

Не подскажете еще как лучше сделать - опрашивать пины как-то в "цикле" или разрешить прерывания по изменению пинов (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

 

и получаете готовое стандартное устройство ввода

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ага,

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот пример управления пином к которому подключен светодиод с помощью системного вызова 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");

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...