annjer |
04-27-2017 02:27 AM |
Coding serial ISR for UART 16550 under Linux kernel 3.18
Hello,
I have a problem with my ISR made on the basis of http://http://www.linuxquestions.org...-linux-763595/Coding an Interrupt Service Routine for the serial port in Linux !! post. Here is my code:
Code:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/signal.h>
#include <linux/irq.h>
#define PORT 0x3F8
void delayedOp (unsigned long currentlyUnused);
DECLARE_TASKLET (rs232Tasklet, delayedOp, 0);
static int times;
static unsigned char znak;
unsigned char status, intr_identify;
irq_handler_t isrSerialPort (int irq, void *dev_id, struct pt_regs *regs)
{
times++;
printk (KERN_ALERT "\nisrSerialPort called %d ", times);
intr_identify = inb( PORT + 2 ) & 0x0F;
if ( intr_identify == 0x01 ) return IRQ_NONE;
if ( intr_identify == 0x04 ) // a new character has arrived
znak=inb( PORT );
printk (" irq = %x, intr = %x ", znak,intr_identify);
outb(znak,PORT);
tasklet_schedule (&rs232Tasklet);
outb(0x20,0x20);
return (irq_handler_t) IRQ_HANDLED;
}
int init_module ()
{
int status;
int result = request_irq (4, (irq_handler_t) isrSerialPort, IRQF_DISABLED, "softbrainISR", NULL);
outb(0x0b,PORT+4); //ster_modem - DTR,RTS,OUT2
outb( 0x07, PORT + 2 ); // turn off FIFO-mode
inb(PORT+6); //stan_modem
inb(PORT+5); //status_port
inb(PORT); //dane
outb(0x8b,PORT+3); //LCR=1, param_trans = 0x0b - parity even (b3-b5), 1 bit stopu(b2), 8 bitów danych (b0,b1)
//03 - dla parity none
outb(0x0c,PORT); //9600 bodów
outb(0x0b,PORT+3); //LCR=0
outb(01,PORT+1); //przerwanie od odbiornika aktyw_przerw=1
status=inb(PORT+5);
if(status&01)inb(PORT);
inb(PORT);
printk (KERN_INFO "\ncinit_module called\n");
return result;
}
void delayedOp (unsigned long currentlyUnused)
{
printk ("\nznak = %x ", znak);
}
void cleanup_module ()
{
free_irq (4, NULL);
printk (KERN_INFO "\ncleanup_module called\n");
}
The problem is that the first interrupt doesn't come - the first character I send comes after I send the next character and so on... In effect I never get the last one - It waits for interrupt until next character.
Where is the problem?
Please help me
Anna
|