реклама на сайте
подробности

 
 
> AT91SAM9260 + Linux + INT0, Большие задержки по прерыванию
MTh
сообщение May 22 2008, 01:33
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 28-02-06
Из: Иркутск
Пользователь №: 14 771



Сделал модуль ядра под линукс 2.6.22.10. Смог инциализицровать прерывание:
Код
printk("Setting up IRQ: ");
interrupt_return = request_irq(IRQ_NUMBER, (void*) m_irq, IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL);
if (interrupt_return != 0) {
    printk("request IRQ return = %d ", interrupt_return);
}
printk("ok\n");

Обработчик прерывания выглядит след. образом:
Код
irq_handler_t m_irq(void) {    
    char ret_int;
    BYTE DIG_DAT;
    
    ret_int = FPGA_MEMORY_REGION[ADR_INTERRUPTS_REG];
    printk("ret_int = %X", ret_int);  //дебаг
    
    if (ret_int == INT_DIGITAL_DATA) {
        ///// Interrupt for digital data
        
        #ifdef DEBUG_MSG
            printk("DIGITAL DATA Interrupt\n");
        #endif
        DIG_DAT = FPGA_MEMORY_REGION[ADR_DIG_STATE_LU_REG];
                COUNT_DIGITAL_SENSOR(DIG_DAT);
    }
}


ПРерывание генерирует ПЛИС, по чтению с регистра ADR_INTERRUPTS_REG (это адрес регистра в ПЛИС, читается при помощи SMC), ПЛИС возвращает INT0 в высокий уровень после чтения регистра ADR_INTERRUPTS_REG, после чего (если прерывание было то, какое я ожидаю - INT_DIGITAL_DATA), мне нужно прочитать еще 1 регистр - ADR_DIG_STATE_LU_REG. Т.е. грубо говоря на осциллографе я должен увидеть провал напряжения (прерывание по INT0), и где-то следом чтение из регистров.
Вообщем-то эту картину я и наблюдаю, однако задержка между прерыванием и чтением около 2-4
мкСек, что непомерно много для АРМ9. Что я делаю не так?

Кроме всего прочего посмотрел исходники ядра и поправил приоритет INT0 с 0 на 7. Т.е. оно сейчас имеет высший приоритет.

Быстрая обработка - критична - данных много и идут они довольно часто.

Также еще одна проблема - после вызова нескольких прерываний ядро валится в стэк (но остается работоспособным) с сообщением что за прерыванием никто не следит и надо бы загрузиться с опцией irqpoll. В чем тут может быть проблема?

Заметил еще один момент: если чтение с регистров идет друг за другом - то выполняется только последнее, если между чтениями натыкать cpu_relax(); то все хорошо... ПОчему так?

З.Ы. Бьюсь уже несколько дней - идей кончились... помогите!!!

Сообщение отредактировал MTh - May 22 2008, 01:46
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 2)
MTh
сообщение May 23 2008, 03:56
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 28-02-06
Из: Иркутск
Пользователь №: 14 771



Еще один момент (очень смешной кстати):

После "нескольких" прерываний вываливается вот такое сообщение

# <3>irq 30: nobody cared (try booting with the "irqpoll" option)
[<c0277128>] (dump_stack+0x0/0x14) from [<c02abbec>] (__report_bad_irq+0x38/0x88)
[<c02abbb4>] (__report_bad_irq+0x0/0x88) from [<c02abeb0>] (note_interrupt+0x274/0x2c8)
r4:00000000
[<c02abc3c>] (note_interrupt+0x0/0x2c8) from [<c02accd4>] (handle_level_irq+0xd0/0x15c)
[<c02acc04>] (handle_level_irq+0x0/0x15c) from [<c0272044>] (__exception_text_start+0x44/0x6c)
r6:00000000 r5:c047f78c r4:0000001e
[<c0272000>] (__exception_text_start+0x0/0x6c) from [<c0272ab8>] (__irq_svc+0x38/0x64)
Exception stack(0xc0479f4c to 0xc0479f94)
9f40: 00000000 0005317f 0005217f 60000013 c0274068
9f60: c0478000 c0274068 c04926e8 2001cdb4 41069265 2001cd80 c0479fa0 c0479fa4
9f80: c0479f94 c02740ac c02740b8 60000013 ffffffff
r6:0000001e r5:fefff000 r4:ffffffff
[<c0274068>] (default_idle+0x0/0x58) from [<c0273e58>] (cpu_idle+0x3c/0x68)
[<c0273e1c>] (cpu_idle+0x0/0x68) from [<c040bdf0>] (rest_init+0x5c/0x6c)
r7:c04aae84 r6:c026ff20 r5:c04922a8 r4:c049af24
[<c040bd94>] (rest_init+0x0/0x6c) from [<c0008d2c>] (start_kernel+0x248/0x2b4)
[<c0008ae4>] (start_kernel+0x0/0x2b4) from [<20008030>] (0x20008030)
handlers:
[<bf000000>] (m_irq+0x0/0x4c [int_drv])
Disabling IRQ #30

Просмотрев файл /proc/interrupts увидел следующее:
Код
# cat /proc/interrupts
           CPU0
  1:      16212         AIC  at91_tick, atmel_serial
12:          0         AIC  atmel_spi.0
20:          0         AIC  ohci_hcd:usb1
21:        252         AIC  eth0
30:     100000         AIC  fpga_drv                                 ///Смотреть сюда :)
Err:          0


Т.е. если все упростить, как только набралось 100 000 прерываний, то вываливается вышеуказанное сообщение и блокируется запрошенное прерывание... Почему так?

UPD: В файле sprious.h нашел ограничитель на 100 000... Судя по тому что там написано - я не возвращаю из прерывания чего-то системе...
UPD2: Обработчик прерывания должен иметь тип irqreturn_t и по выходу возвращать IRQ_HANDLED, иначе оно считается необработанным. smile.gif

Сообщение отредактировал MTh - May 23 2008, 04:15
Go to the top of the page
 
+Quote Post
MTh
сообщение Jun 2 2008, 04:08
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 234
Регистрация: 28-02-06
Из: Иркутск
Пользователь №: 14 771



Ответ лежит здесь: http://marc.info/?l=linux-arm-kernel&m...6204467&w=2
Сам не пробовал... мозгов не хватает...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 11:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01912 секунд с 7
ELECTRONIX ©2004-2016