Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71622
  • 博文数量: 10
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 151
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-15 16:45
个人简介

多动脑,少走路。

文章分类
文章存档

2015年(4)

2014年(2)

2013年(4)

分类: LINUX

2015-03-05 13:41:51

关于LINUX对926X中断的实现(LINUX2.6.24中试用)
一,926X中断的描述
对于926X有先进中断控制器控制中断具体对应的中断有0~310为FIQ,1为系统,2~31对应设备.见DATASHEET
二,926X中断的LINUX实现
1,PIO的输入中断问题,手册描述了
PIOA         2
PIOB         3
PIOC         4
LINUX中AT91SAM926X.H定义了所有的中断分配号:
*
* Peripheral identifiers/interrupts.
*/
#define AT91_ID_FIQ             0       /* Advanced Interrupt Controller (FIQ) */
#define AT91_ID_SYS             1       /* System Peripherals */
#define AT91SAM9260_ID_PIOA     2       /* Parallel IO Controller A */
#define AT91SAM9260_ID_PIOB     3       /* Parallel IO Controller B */
#define AT91SAM9260_ID_PIOC     4       /* Parallel IO Controller C */
#define AT91SAM9260_ID_ADC      5       /* Analog-to-Digital Converter */
#define AT91SAM9260_ID_US0      6       /* USART 0 */
#define AT91SAM9260_ID_US1      7       /* USART 1 */
#define AT91SAM9260_ID_US2      8       /* USART 2 */
#define AT91SAM9260_ID_MCI      9       /* Multimedia Card Interface */
#define AT91SAM9260_ID_UDP      10      /* USB Device Port */
#define AT91SAM9260_ID_TWI      11      /* Two-Wire Interface */
#define AT91SAM9260_ID_SPI0     12      /* Serial Peripheral Interface 0 */
#define AT91SAM9260_ID_SPI1     13      /* Serial Peripheral Interface 1 */
#define AT91SAM9260_ID_SSC      14      /* Serial Synchronous Controller */
#define AT91SAM9260_ID_TC0      17      /* Timer Counter 0 */
#define AT91SAM9260_ID_TC1      18      /* Timer Counter 1 */
#define AT91SAM9260_ID_TC2      19      /* Timer Counter 2 */
#define AT91SAM9260_ID_UHP      20      /* USB Host port */
#define AT91SAM9260_ID_EMAC     21      /* Ethernet */
#define AT91SAM9260_ID_ISI      22      /* Image Sensor Interface */
#define AT91SAM9260_ID_US3      23      /* USART 3 */
#define AT91SAM9260_ID_US4      24      /* USART 4 */
#define AT91SAM9260_ID_US5      25      /* USART 5 */
#define AT91SAM9260_ID_TC3      26      /* Timer Counter 3 */
#define AT91SAM9260_ID_TC4      27      /* Timer Counter 4 */
#define AT91SAM9260_ID_TC5      28      /* Timer Counter 5 */
#define AT91SAM9260_ID_IRQ0     29      /* Advanced Interrupt Controller (IRQ0) */
#define AT91SAM9260_ID_IRQ1     30      /* Advanced Interrupt Controller (IRQ1) */

LINUX中AT91SAM926X.C分配中断分配号到PIOA,PIOB,PIOC中:

static struct at91_gpio_bank at91sam9260_gpio[] = {
      {
            .id             = AT91SAM9260_ID_PIOA,
            .offset         = AT91_PIOA,
             .clock          = &pioA_clk,
},
      {
  .id             = AT91SAM9260_ID_PIOB,
               .offset         = AT91_PIOB,
               .clock          = &pioB_clk,
       },
{
               .id             = AT91SAM9260_ID_PIOC,
               .offset         = AT91_PIOC,
               .clock          = &pioC_clk,
       }
};

这里调用允许中断函数

At91_gpio_irq_setup();他的定义在gpio.c:

static struct at91_gpio_bank *gpio;
void __init at91_gpio_irq_setup(void)
{
  unsigned        pioc, pin;
  for (pioc = 0, pin = PIN_BASE;
           pioc < gpio_banks;
               pioc++) {
               void __iomem    *controller;
               unsigned        id = gpio[pioc].id;
               unsigned        i;
               clk_enable(gpio[pioc].clock);  
//处理/* enable PIO controller's clock */
                controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
               __raw_writel(~0, controller + PIO_IDR);
                set_irq_data(id, (void *) pin);
               set_irq_chip_data(id, controller);
                for (i = 0; i < 32; i++, pin++) {
  /*
  * Can use the "simple" and not "edge" handler since it's
  * shorter, and the AIC handles interupts sanely.
  */
                       set_irq_chip(pin, &gpio_irqchip);
                       set_irq_handler(pin, handle_simple_irq);
                       set_irq_flags(pin, IRQF_VALID);
               }
                set_irq_chained_handler(id, gpio_irq_handler);
       }
如果使用PIO IO:
直接用int at91_get_gpio_value(unsigned pin)
int at91_set_gpio_value(unsigned pin, int value)
就可以实现读写啦

如果使用PIO的中断呢?
一 设置为输入.
二 设置毛刺(也可以不设置)
三 调用 REQUEST_IRQ()
at91_set_gpio_input(AT91_PIN_PB5,1);
    result = request_irq(AT91_PIN_PB5, kirq_interrupt, SA_INTERRUPT,  "kirq", &kirq_dev);
     if (result < 0){
         printk("register irq fail.%d\r\n",result);
  return result;
     }

/************************************************************************************/
实验的结果(查看中断是否产生)
/teset/irq # cat /proc/interrupts
CPU0
  1:      72905         AIC  at91_tick, atmel_serial
10:          0         AIC  at91_udc
20:          0         AIC  ohci_hcd:usb1
21:       4754         AIC  eth0
69:          0        GPIO  kirq
101:          1        GPIO  at91_udc

at91_set_gpio_input(AT91_PIN_PA5,1);
    result = request_irq(AT91_PIN_PA5, kirq_interrupt, SA_INTERRUPT,  "kirq", &kirq_dev);
     if (result < 0){
         printk("register irq fail.%d\r\n",result);
  return result;
     }

实验的结果(查看中断是否产生)
/teset/irq # cat /proc/interrupts
           CPU0
  1:       3295         AIC  at91_tick, atmel_serial
10:          0         AIC  at91_udc
20:          0         AIC  ohci_hcd:usb1
21:       1801         AIC  eth0
37:          1        GPIO  kirq
101:          1        GPIO  at91_udc
Err:          0四 其他设备的调用就直接用request_irq(IRQ_NUMBER,…)
阅读(2335) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~