0

I'm writing a simple UART driver in linux for ARM926EJ-S. Inside the read function of the driver. If enter key (carriage return) was pressed, I want it to return the no. of bytes read till that point.

uart_data = (unsigned char)ioread8((void*)UART_DR(uart0_addr));
printk(KERN_ERR " %d ",(unsigned int)uart_data ); //prints 13 when pressing enter key
if ((unsigned char)13 == uart_data) //if carriage return 
{
    printk(KERN_ERR "Carriage Return\n");
    goto out;
}

When I press enter key on the UART terminal, it receives it as a carriage return, but the control flow never gets inside the if block. Please help.

balajimc55
  • 2,192
  • 2
  • 13
  • 15
  • Nice. Why do you print "Line feed" when you're receiving a "Carriage Return"? – tofro Apr 22 '16 at 15:33
  • ^^^^ Linux programmer; they don't understand CR :) – Martin James Apr 22 '16 at 15:35
  • 'control flow never gets inside the if block' - does the printk() return? If you break on the 'if', is it hit? – Martin James Apr 22 '16 at 15:36
  • My bad! It was for debugging purpose anyway!! – balajimc55 Apr 22 '16 at 15:36
  • @MartinJames Yes, printk() returns and the code following this above blockworks fine! – balajimc55 Apr 22 '16 at 15:37
  • Well, if you break on the 'if', inspect uart_data and it's still 13, I have to say that I'm just as stuck as you are. All I can suggest is that you stop on the if and trace through the generated assembler, instruction-by-instruction, to find out why the thing fails:( – Martin James Apr 22 '16 at 15:45
  • Umm.. printk() might be a bit greedy - how much interrupt stack have you allocated? – Martin James Apr 22 '16 at 15:46
  • Could be something *very* trivial - Printk uses a ring buffer in the kernel. If reading the UART register triggers a lot of other printk messages (Maybe, because the FIFO now allows further reading, whatever), the ring buffer might run-around and drop your message for the benefit of others. You could try and increase that buffer by re-compiling the kernel. Your code looks pretty much O.K to me. – tofro Apr 22 '16 at 17:59
  • And you are not telling us whether you have proof you can receive *any character at all* - Can you elaborate on that? Otherwise something else might be wrong. The UART data register is actually a 16-bit register. Not sure if it is valid on your hardware to read only the lower half. – tofro Apr 22 '16 at 18:12
  • Following this code, I use copy_to_user() to copy the value in 'uart_data' to a user-space buffer and the user process always receives correct data when it reads from this buffer. So I'm sure the printk() isn't causing any stack corruption. And besides, I also tried commenting out printk() and ran it, but still doesn't fix the problem. – balajimc55 Apr 23 '16 at 00:58
  • And not just for carriage return, even when I use 'a' as a delimiter, as in `if('a' == uart_data)` , it still doesn't get inside the if block though I entered 'a' in uart terminal. – balajimc55 Apr 23 '16 at 01:00

0 Answers0