Jump to content

    
Sign in to follow this  
Kris2007

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

Recommended Posts

Спасибо!

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

 

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

Share this post


Link to post
Share on other sites
Спасибо!

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

 

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

Share this post


Link to post
Share on other sites

ага,

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

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this