LINUX.ORG.RU

Прерывание от PCI


0

0

Здравствуйте, Появилась проблема следующего плана. Имеется плата PCI, построен на ПЛИСе SPARTANe II (своей разработки), на нем сделан PCI контроллер, сей девайс подключается к внешнему интерфесу ВВОДА-ВЫВОДА. Чтение, запись в канал ввода-вывода осуществляется через пространство I/O. Чтение, запись работают норм. При приходе из канала ввода-вывода некой команды, выставляется прерывание, INT#A опускается в 0, вызывается обработчик прерываний который, читает определенный регистр в котором отражено что прерывание выставило именно это устройство, прерывание сбрасывается и выполняется некая команда. Если через некоторое время из канала приедет опять команда... то мой контроллер опять выставит прерывание на линии но обработчик почему то не вызывается такое ощущение что он просто не видит его??? смотрю на контакт INT#A он в 0, ..... система не виснет... стоит пошевелить мышкой как мое прерывание обрабатывается, сбрасывается и команда проходит. (происходит четко через раз, один раз прошло нормально, второй раз нужно шевелить мышкой, третий раз опять норм. и.т.д.)

Как узнаю что не входит в обработку прерывания? вывожу на экран строчку типа "прерывание пришло" и вторую строчку вывожу после того как прочитаю регистр подтверждения прерывания "мое прерывание"... прерывание без шевеления мышки или нажатия клавиш на клавиатуре срабатывают ровно через раз.... вот такая ситуация...

anonymous

Забыл добавить, ОСЬ МСВС 3.0

anonymous
()

ytfyt

если вы делаете printk() из обработчика прерывания то ничего удивительного в этом ИМХО нет. Я бы на вашем месте устанавливал бы сигнальное значение в каком-нибудь ненужном регистре и ловил бы его осцилом.

int_0dh
()

> МСВС 3.0

Это всё равно, что ничего не сказать. Версия ядра какая?

Первым делом посмотри в логи. По описанию трудно понять, что происходит. Нашпигуй драйвер printk, и снова смотри в логи.

Возможно, ты не разрешаешь прерывание на устройстве, или не возвращаешь IRQ_HANDLED.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Версию ядра скажу попозже(((когда буду на работе) Драйвер и так нашпигован принтк(я не программист, а электроник) но все же постараюсь объяснить.

в драйвере вставил две строки печатающие текст

первая стоит сразу полсе строки обработчика прерывания(тем самым я хотел увидеть что по прерыванию я попадаю в обработчик), а вторая после чтения регистра в пространстве ввода-вывода в котором устанавливается бит признака что это мое прерывание т.е. читаю регистр 0х8 если там записанно 0х1 то это мое прерывание, выполняются некие действия .. и прерывание сбрасывается....

так вот эта схема работает четко через раз.. первый раз напечатал строку что попал в обработчик и строку что определил что мое прерывание... все прерывание сбросил, все люкс... приходит новая команда, прерывание выставил(в физическом смысле(осциллографом вижу сигнал на контакте)) но в обработчик не вызывается(не печатается первая отладочная строка)... стоит пошевелить мышкой, как тут же печатаются обе отладочный строки и прерывание сбрасывается.

anonymous
()
Ответ на: комментарий от tailgunner

Версия ядра 2.4.32-vniins42

В конф.пространстве прерывание разрешаю(ели бы не разрешал, как бы оно у меня проходило через раз)

А что за IRQ_HANDLED?? можно поподробнее?

anonymous
()
Ответ на: комментарий от anonymous

> схема работает четко через раз

Может, это аппаратная проблема?

> А что за IRQ_HANDLED?? можно поподробнее?

Я уже не очень хорошо помню, как там в ядре 2.4, но на 2.6 обработчик должен возвращать значение вроде "да, я обработал это прерывание" (IRQ_HANDLED) или "прерывание не мое, передайте дальше" (IRQ_NONE). Если ни один драйвер не обработал прерывание, в лог печатается что-то вроде IRQn: nobody cared", и прерывание запрещается.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Может, это аппаратная проблема?

Возникает справедливый вопрос? почему первое прерывание выставленное платой система отработала? а второе(которое тоже выставленно и держиться) она отработать не может? проблем со стороны платы я не вижу((

anonymous
()
Ответ на: комментарий от anonymous

>>Может, это аппаратная проблема?

>Возникает справедливый вопрос? почему первое прерывание выставленное платой система отработала? а второе(которое тоже выставленно и держиться) она отработать не может?

в аппаратуре тоже бывает разное :) попробуй (скриптом в цикле) смотреть /proc/interrupts во время работы со своей платой.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

скажите, как вы узнаете о том что вызван ваш обработчик? если только по printk() из обработчика прерывания - то описанная вами ситуация может быть и нормальной.

int_0dh
()
Ответ на: комментарий от int_0dh

Простите если что за программистскую неграмотоность если что(объясняю как могу, ну не программер я...((( ну что поделать :-D )

Узнаю так, примерный вид программы:

-- Строка обнаружения прерывания -- добавил первое принтк("вошли в обработчик") (на основании этой строчки говорю, обработчик прерываний вызвался)

-- Читаю регистр(мой внутренний, в котором выставляю бит признака прерывания)

-- Если прочитали нужное число(признак присутствует) -- принтк("мое прерывание") ... дальше идет какой то код в котором я не бум бум...

попозже(минут 40..50) постараюсь выложить этот участок

anonymous
()
Ответ на: комментарий от int_0dh

> если только по printk() из обработчика прерывания - то описанная вами ситуация может быть и нормальной.

Каким образом?

tailgunner ★★★★★
()
Ответ на: комментарий от int_0dh

>скажите, как вы узнаете о том что вызван ваш обработчик? если только по printk() из обработчика прерывания - то описанная вами ситуация может быть и нормальной.

Не только... Прерывание срабатывает по приходу команды с внешнего интерфейса ввода-вывода, время между командами минута. Так вот первая команда отрабатывается, а вторая нет... принтк вывели только уже потом, как увидели что прерывание не снимается...

anonymous
()
Ответ на: комментарий от tailgunner

>Каким образом? ну например сообщения могут элементарно отображатся уже после того как прерывание отработало. Печать же идет в буффер а не на физическую консоль

int_0dh
()
Ответ на: комментарий от int_0dh

> сообщения могут элементарно отображатся уже после того как прерывание отработало.

Ну, не с минутным же промежутком :)

tailgunner ★★★★★
()
Ответ на: комментарий от int_0dh

>Каким образом? ну например сообщения могут элементарно отображатся уже после того как прерывание отработало. Печать же идет в буффер а не на физическую консоль

Печать(о том что вошли в прерывание и его обработали) выводится сразу же после того как я пошевелю мышкой и физически снимается только после шевеления мышкой(смотрю осцилом)...

anonymous
()
Ответ на: комментарий от int_0dh

/*****************************************************************************/ //I?EOAIEA UAAA?E EIOIOAN AOAAO ?U?IIINOOON ?OIAA UA ?OAOU?AIEAI /* static struct tq_struct task1={ {}, 0, func_obrabotka, NULL }; */ ////////////////////////////////////////////////////////////////////////////// void d_mixa(int irq,void *dev_id,struct pt_regs *regs) { temp5=inb(reg0+8); //?OI?AOEA - O?IA IE ?OAOU?AIEA

printk("obrabotchik \n"); //(Первая строка от которой узнаем что вошли в обработчик)

if((temp5 & 0x1) != 0x1) return; outb(0x1,reg0+8); cli();

printk("MOE IRQ \n"); //(Вторая что узнаем что прерывание наше)

outb(0x33,reg0+3); //----------------------------------------------------------------------------- temp6=temp11=inb(reg0+6); temp11=temp11 & 0x07; /*IAOEA IA ?AO?UA 0,1,2 AEOU*/ switch(temp11) { /* iaoaaioea ?oaou?aien io eaiaia*/ case 0: /*oaoio oeooaiu*/ /*++++++++++++++++++++++++++++++++++*/ wyh=0x0; uuk=0; flag_n2=0; outb(0,reg0+6); outb(0x1,reg0+7); outb(0,reg0); kb[0]=0; pred_sost=0x2; kb[6]=0; m[0]=0; regim=0x1; wyh=0x1; kb[12]=255; plot=1; temp6=inb(reg0+3); if(wpk==0x1) {wpk=0x0; goto KON_M;} wpk=0; wyh=0x0; flag_sbr=1; for(temp90=0; temp90<16; temp90++) prm_bs[temp90]=0; goto SBROS; break; case 1: /*oaiaeoe?iue oaoio*/ /*++++++++++++++++++++++++++++*/ /****************************************************************************/ flag_n2=0; uuk=0; kb[0]=0x1; wyh=0; if((temp6 & 0x80) == 0x80) { kb[9]=inb(reg0+2); if(wpk == 0x1) { if(kb[9] == kb[1]) goto M1_12; else goto M877; } else { M877: pred_sost=0x2; outb(0,reg0+6); temp77=inb(reg0+3); kb[0]=0x6; goto KON_M; //M1_16; } } if(wpk != 0x1) kb[9]=adr_bs; else kb[9]=kb[1]; M1_12: wyh=0x1; wpk=0; outb(0x1,reg0+7); outb(0,reg0+6); outb(0,reg0); pred_sost=0x2; kb[12]=255; regim=0x1; //M1_16:; temp6=inb(reg0+3); flag_sel=1; goto SBROS; break; /****************************************************************************/ case 2: /*ioeia?aiea io eioao?aeoa*/ /*++++++++++++++++++++++*/ flag_n2=0; wyh=0x0; kb[0]=2; if((temp6 & 0x80) == 0x80) { if(wpk != 0x1) { kb[0]=0x6; kb[9]=inb(reg0+2); outb(0,reg0+6); pred_sost=0x2; temp6=inb(reg0+3); goto KON_M; } kb[9]=inb(reg0+2); goto M1_13; } if(wpk != 0x1) kb[9]=adr_bs; else kb[9]=kb[1]; M1_13: wyh=0x1; //wpk=0x0; regim=0x1; kb[0]=0x7; outb(0x1,reg0+7); outb(0,reg0+6); outb(0,reg0); pred_sost=0x2; temp6=inb(reg0+3); //flag_sel=1; goto SBROS; break;

Вашему вниманию... :) p.s. прошу прощения за кривые коменты

anonymous
()
Ответ на: комментарий от anonymous

у вас там в интересном месте cli() стоит что-то оно мне как-то не нравится.

попробуйте запостить с user line breaks

int_0dh
()
Ответ на: комментарий от tailgunner

Пасибо)))


/*-------eiiaa ioii?iie ?oicoaiiu------------------------------------------*/
/*****************************************************************************/

/*************** ?oieaen iooaaioee ?oaou?aien io aaa?oioa ********************/
/*****************************************************************************/

//I?EOAIEA UAAA?E EIOIOAN AOAAO ?U?IIINOOON ?OIAA UA ?OAOU?AIEAI
/*
static struct tq_struct task1={
                                {},
                                0,
                                func_obrabotka,
                                NULL
                                };
*/
                                //////////////////////////////////////////////////////////////////////////////
void d_mixa(int irq,void *dev_id,struct pt_regs *regs)
{
temp5=inb(reg0+8);      //?OI?AOEA - O?IA IE ?OAOU?AIEA
printk("obrabotchik \n");
if((temp5 & 0x1) != 0x1) return;
outb(0x1,reg0+8);
cli();

printk("MOE IRQ \n");

outb(0x33,reg0+3);
//-----------------------------------------------------------------------------

temp6=temp11=inb(reg0+6);
temp11=temp11 & 0x07;               /*IAOEA IA ?AO?UA 0,1,2 AEOU*/
switch(temp11) {
               /* iaoaaioea ?oaou?aien io eaiaia*/
               case 0: /*oaoio oeooaiu*/  /*++++++++++++++++++++++++++++++++++*/
wyh=0x0;
uuk=0;
flag_n2=0;
outb(0,reg0+6);
outb(0x1,reg0+7);
outb(0,reg0);
kb[0]=0;
pred_sost=0x2;
kb[6]=0;
m[0]=0;
regim=0x1;
wyh=0x1;
kb[12]=255;
plot=1;
temp6=inb(reg0+3);
if(wpk==0x1) {wpk=0x0; goto KON_M;}
wpk=0;
wyh=0x0;
flag_sbr=1;
for(temp90=0; temp90<16; temp90++) prm_bs[temp90]=0;
goto SBROS;
               break;
               case 1: /*oaiaeoe?iue oaoio*/ /*++++++++++++++++++++++++++++*/
/****************************************************************************/
flag_n2=0;
uuk=0;
kb[0]=0x1;
wyh=0;
if((temp6 & 0x80) == 0x80) {
                            kb[9]=inb(reg0+2);
                            if(wpk == 0x1)  {
                                             if(kb[9] == kb[1])  goto M1_12;
                                                 else goto M877;
                                           }
                                    else {
                                   M877:  pred_sost=0x2;
                                          outb(0,reg0+6);
                                          temp77=inb(reg0+3);
                                          kb[0]=0x6;
                                          goto KON_M;   //M1_16;
                                         }
                            }
if(wpk != 0x1) kb[9]=adr_bs; else kb[9]=kb[1];
M1_12: wyh=0x1;
wpk=0;
outb(0x1,reg0+7);
outb(0,reg0+6);
outb(0,reg0);
pred_sost=0x2;
kb[12]=255;
regim=0x1;
//M1_16:;
temp6=inb(reg0+3);
flag_sel=1;
goto SBROS;
               break;
/****************************************************************************/
               case 2: /*ioeia?aiea io eioao?aeoa*/ /*++++++++++++++++++++++*/
flag_n2=0;
wyh=0x0;
kb[0]=2;
if((temp6 & 0x80) == 0x80) {
                            if(wpk != 0x1)  {
                                             kb[0]=0x6;
                                             kb[9]=inb(reg0+2);
                                             outb(0,reg0+6);
                                             pred_sost=0x2;
                                             temp6=inb(reg0+3);
                                             goto KON_M;
                                             }
                            kb[9]=inb(reg0+2);
                            goto M1_13;
                            }
if(wpk != 0x1) kb[9]=adr_bs; else kb[9]=kb[1];
M1_13: wyh=0x1;
//wpk=0x0;
regim=0x1;
kb[0]=0x7;
outb(0x1,reg0+7);
outb(0,reg0+6);
outb(0,reg0);
pred_sost=0x2;
temp6=inb(reg0+3);
//flag_sel=1;
goto SBROS;
               break;

anonymous
()
Ответ на: комментарий от anonymous

Да, ты точно электронщик - только они пишут такие проги. /me бьется в истерике. Обещай, что ты хотя бы прогонишь текст через indent.

В начале функции у тебя стоит cli(). Это 1) не нужно 2) где sti()?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

у вас там совершенно левое cli(). И я не
вижу в коде соответствующего ему sti().
Кроме того в обработчике прерывания разрешены только более приоритетные прерывания 
так что это cli() похоже не нужно
уберите его и я на 99 % уверен что все
заработает

int_0dh
()
Ответ на: комментарий от execve

Господа, спасибо за критику.

Но программу пишу не я. это первое. второе то что это не весь код.. по некоторым соображениям я не могу дать полный код(к сожалению) это часть только та которая по моему мнению касается обработчика.

anonymous
()
Ответ на: комментарий от int_0dh

>Кроме того в обработчике прерывания разрешены только более приоритетные прерывания

Что это значит?? это вы в тексте увидели?? не могли бы показать??!

anonymous
()
Ответ на: комментарий от anonymous

>>Кроме того в обработчике прерывания разрешены только более приоритетные прерывания

>Что это значит?

У каждого прерывания есть приоритет, определяется контроллером прерываний;

> это вы в тексте увидели??

Это мы в учебнике прочитали :)

> не могли бы показать??!

Если ты читаешь по-английски, LDD2 ждет тебя. Там есть глава об обработке прерываний.

А пока что - убери cli(), и попробуй, что получится.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Спасибо учебник читали, по вашим словам подумал что что-то в коде написанно про приоритет...

STI() - в программе есть и не одно... но к чему оно...sorry не знаю.

p.s. ГОСПАДА!!! как выше было написанно данный драйвер, успешно работает с платой на керпиче PLX 9050(ПРОШУ ОБРАТИТЬ НА ЭТО ВНИМАНИЕ!!!)

anonymous
()
Ответ на: комментарий от anonymous

> STI() - в программе есть и не одно... но к чему оно...sorry не знаю.

разрешает прерывания на процессоре

можно попробовать убрать вообще все cli и sti. или поставить по printk рядом с каждым.

> данный драйвер, успешно работает с платой на керпиче PLX 9050

таки ошибка в железе? :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Знал бы прикуп был бы в Сочи... что и хочу узнать... но каким образом может быть ошибка в железе, прерывание моя плата выставляет...???

anonymous
()
Ответ на: комментарий от tailgunner

Не нашел где прочитать... почему в ДОСе в 8259 по портам 0х20 и 0хА0 нужно записывать данные, а в линуксе нет??

anonymous
()
Ответ на: комментарий от anonymous

> почему в ДОСе в 8259 по портам 0х20 и 0хА0 нужно записывать данные, а в линуксе нет??

В Линуксе тоже нужно, но это делает система, а не ты. DOS - это вообще не ОС в современном понимании слова.

Дружище, если ты взялся за программы - тебе придется несколько менять свои привычки, они у тебя "кондово электронные". Что читать, я уже сказал - Linux Device Drivers, 2nd edition. Именно 2 редакция, 3-я посвящена 2.6. Так же в коде ядра дофига примеров драйверов - возьми какой-нибудь несложный (мыши, rtc) и разберись с ним.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>В Линуксе тоже нужно, но это делает система, а не ты. DOS - это вообще не ОС в современном понимании слова.

Вообще то речь шла о том что нужны строчки или нет... :-)

>Дружище, если ты взялся за программы - тебе придется несколько менять свои привычки, они у тебя "кондово электронные". Что читать, я уже сказал - Linux Device Drivers, 2nd edition. Именно 2 редакция, 3-я посвящена 2.6. Так же в коде ядра дофига примеров драйверов - возьми какой-нибудь несложный (мыши, rtc) и разберись с ним.

Не брался и не собираюсь... просто пока программист на больничном ищу сам...

А код скорее всего вы его не полностью смотрите поэтому у вас такие впечатления...

anonymous
()
Ответ на: комментарий от anonymous

>> В Линуксе тоже нужно, но это делает система, а не ты. DOS - это вообще не ОС в современном понимании слова.

> Вообще то речь шла о том что нужны строчки или нет... :-)

Я вообще-то не заметил работы с 8259. Напрямую работать с ним не нужно.

> код скорее всего вы его не полностью смотрите поэтому у вас такие впечатления...

Не поэтому :/ Сам по себе приведенный фрагмент - основание для взыскания, если он написан профессиональным программистом.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.