0

I'm using an Atmega168 in a project that involve using the ISRs from multiple sources. I have an ISR hooked up to an external button and a timer, to use it as a reset button after a predetermined hold time.

I'm also using an ISR hooked upto UART. The UART is connected to an external Linux based SoC. Upon receiving specific commands from the linux machine, the atmel will perform certain functions.

In very rare occasions, the linux hangs up during tranmission and is always sending out the UART commands. This saturates the ISR and it also prevents the reset button ISR to function.

Although this happens rarely, I would like to take measures for this. As far as I know, there are no way to set priority in avr ISRs. So what can I do if the UART ISR is always called and prevents the rest of the board from functioning?

EDIT: I think the problem arises when the linux machine sends an empty string to the atmel. the UART_receive() on the atmel gets stuck at: while ( !(UCSR0A & (1<<RXC0)) );

Any way I can avoid this?

unsigned char USART_Receive_string(unsigned char *x, unsigned char size)
{
unsigned char i = 0;

if (size == 0) return 0;            // return 0 if no space

while (i < size - 1) {              // check space is available (including additional null char at end)
    unsigned char c;
    while ( !(UCSR0A & (1<<RXC0)) );  // wait for another char - WARNING this will wait forever if nothing is received
    c = UDR0;
    if (c == '\0') break;           // break on NULL character
    x[i] = c;                       // write into the supplied buffer
    i++;
}
x[i] = 0;                           // ensure string is null terminated

return i + 1;                       // return number of characters written
}
9
  • What interrupt are you using that has lower priority than the USART interrupt? Nov 17, 2014 at 20:47
  • sorry if I wasn't clear. But there is no way I can set priorities. All the ISRs have equal priority. I'm using : (INT0_vect + TIMER1_COMPA_vect) for the push button, and USART_RX_vect for UART.
    – tsf144
    Nov 17, 2014 at 20:55
  • No, they don't. The ISR priorities are given by their addresses. Both of the button ISRs have priority over all the USART ISRs. Nov 17, 2014 at 20:56
  • It's hard to recreate the situation, but you are saying that even if the UART ISR is saturated with calls, the button isr and the corresponding timer should still work on it's own?
    – tsf144
    Nov 17, 2014 at 21:07
  • Provided interrupts aren't enabled during the ISR, yes. Nov 17, 2014 at 21:08

2 Answers 2

1

Any way I can avoid this?

I think the whole concept of reading "n" bytes is flawed. It will indeed hang if you don't get the number you expect.

Why not just do what normal serial comms does. Accept bytes as they arrive in an ISR, and put them in a buffer? Then use the line-terminator to know when you have enough to process.

So what can I do if the UART ISR is always called and prevents the rest of the board from functioning?

The UART ISR won't be called if there is no data, so it won't be "always called".

0
while ( !(UCSR0A & (1<<RXC0)) );  // wait for another char - WARNING this will wait forever if nothing is received

The comment hits the nail on the head.

It'll wait forever, but it's so because it has been "designed" in such a way.

You've got 2 options:

  • Re-think your "design":

Do not make your UART wait for an n-amount of characters. You could buffer the received characters, and handle/clear the buffer. There should be a lot of info about this on the web.

  • Quick and dirty fix:

Add a timeout to the waiting.

for (unsigned int timeout = 16000; (!(UCSR0A & (1<<RXC0))) && timeout > 0; timeout-- );

This isn't very efficient, but should work. Be sure to check for what reason the waiting stopped (if the timeout ran out, or if you actually received something), to avoid pushing in nonesense that's in the UDR0 at that moment (when you timeout).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.