All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomas Kalibera <kalibera@domain.hid>
To: xenomai@xenomai.org
Subject: [Xenomai-help] Loosing serial interrupt
Date: Mon, 05 May 2008 16:22:21 -0400	[thread overview]
Message-ID: <481F6C7D.1050908@domain.hid> (raw)

[-- Attachment #1: Type: text/plain, Size: 1461 bytes --]

Hi,

I am having problems with lost serial interrupts. Could you please 
explain to me why this happens ? I am probably missing something 
regarding scheduling in Xenomai...
I prepared a program that triggers the problem, at least on my system.

Thanks,

Tomas

The program works on my system as follows:

1. I run the program, it prints

In interrupt, LStatus: 96
In interrupt, read char, LStatus: 96

[which means that it received a serial interrupt, because the 
transmitter receiver is empty]

2. I send a single character to the program over serial line

3. the program wakes up (10 seconds after (1))

4. the program prints

I-NFO irq=4 hits=1
PIC-ISR:0 PIC-IRR:0 PIC-IMR:128 UART-IIR:4 UART-LSR:97 UART-MSR:176

[which means the interrupt at Xenomai level hit only once, although it 
should have twice, second time because of the received character
  these too lines that repeat indefinitely, the interrupt not coming. 
although interrupts are enabled at PIC level]

I use the "XT-PIC-XT" (8259A) interrupt controller. As far as I know, 
Linux sets up the controller to "edge triggering", but uses 
"handle_level_irq" for it. When received by Xenomai, the interrupt is 
masked and acked at PIC level ( "ack" means EOI at 8259A). When the 
interrupt handling in the program finishes, it unmasks the interrupt. I 
verified  that my 8259A has a latch that can detect the UART interrupt 
even if masked, so that when unmasked again, it can be delivered.





[-- Attachment #2: xloopback.c --]
[-- Type: text/plain, Size: 2303 bytes --]

#include <stdio.h>
#include <sys/io.h>
#include <unistd.h>

#include <native/task.h>
#include <native/intr.h>
#include <sys/mman.h>

#define BASEPORT 0x3f8
#define IRQ_NUMBER 0x4

RT_INTR intr_desc;
RT_TASK sender_desc, task_main;

inline void nfo() {

  int isr, irr, imr;
  int iir, lsr, msr;
  
  outb(0x0b, 0x20);
  isr = inb(0x20);
  outb(0x0a, 0x20);
  irr = inb(0x20);
  imr = inb(0x21);
  
  iir = inb(BASEPORT +2);
  lsr = inb(BASEPORT +5);
  msr = inb(BASEPORT +6);
  
  fprintf(stderr, "PIC-ISR:%d PIC-IRR:%d PIC-IMR:%d UART-IIR:%d UART-LSR:%d UART-MSR:%d\n",
    isr, irr, imr, iir, lsr, msr);

}

void sender_task (void *cookie) {

  int res;
  
  for(;;) {


    res = rt_intr_wait(&intr_desc, TM_INFINITE);
    
    if (res<=0) {
      perror("rt_intr_wait: ");
      continue;
    }

    fprintf(stderr,"In interrupt, LStatus: %d \n", inb(BASEPORT +5));

    inb(BASEPORT);
    fprintf(stderr,"In interrupt, read char, LStatus: %d \n",
        inb(BASEPORT +5));

    rt_intr_enable( &intr_desc ); 
  }
}

RT_INTR_INFO intr_nfo;

int main(int argc, char **argv) {

  int res,i;
  
  if (iopl(3)) { 
    perror("iopl:");
    return 1;
  }

  mlockall(MCL_CURRENT|MCL_FUTURE);
  
  res = rt_intr_create(&intr_desc, NULL, IRQ_NUMBER, I_NOAUTOENA); 
//  res = rt_intr_create(&intr_desc, NULL, IRQ_NUMBER, 0); 

  if (res) {
    perror("rt_intr_create:");
    return 1;
  }
  
  res = rt_task_create(&sender_desc, NULL, 0, 99, 0);
  if (res) {
    perror("rt_task_create:");
    return 1;
  }
  
  rt_task_start(&sender_desc, &sender_task, NULL);


  outb( 0x00, BASEPORT + 1);
  outb( 0x80, BASEPORT + 3 );
  outb( 0x01, BASEPORT + 0 );
  outb( 0x00, BASEPORT + 1 );
  outb( 0x03, BASEPORT + 3 );

// FIFO on, interrupt after one byte
  outb( 0x7, BASEPORT + 2); 
  
// FIFO off 
  outb( 0x0, BASEPORT + 2); 
  
  outb( 0xb, BASEPORT + 4 ); // force rts on
//  outb( 0x9, BASEPORT + 4 ); // do not force rts

  
  rt_intr_enable( &intr_desc );    
  
  outb( 15, BASEPORT + 1 ); 

  rt_task_shadow( &task_main, NULL, 1, 0);

  while (1) {

      rt_task_sleep(10000000000ULL);
      
      rt_intr_inquire(&intr_desc, &intr_nfo);
      fprintf(stderr,"I-NFO irq=%d hits=%d\n", intr_nfo.irq, intr_nfo.hits);

      nfo();
  }

  fprintf(stderr,"Main: no more characters to send...\n");  

}


             reply	other threads:[~2008-05-05 20:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-05 20:22 Tomas Kalibera [this message]
2008-05-05 22:21 ` [Xenomai-help] Loosing serial interrupt Jan Kiszka
2008-05-05 22:46   ` Karch, Joshua
2008-05-05 23:22     ` Tomas Kalibera
2008-05-05 23:41   ` Tomas Kalibera
2008-05-06  6:52     ` Jan Kiszka
2008-05-06 16:29       ` Tomas Kalibera

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=481F6C7D.1050908@domain.hid \
    --to=kalibera@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.