Hardfault in interrupt driver

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hardfault in interrupt driver

723 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fentechnt on Mon Feb 15 06:03:02 MST 2010
I've been porting my serial port driver across from LPC21xx and it randomly causes a hard fault.  I've been debugging it by removing lines in the interrupt handler and the fault disappears if I remove the line that writes the incoming serial data to a buffer.

#define SERIAL_BUFFER_SIZE           ( 64 )
#define SERIAL_BUFFER_LENGTH_MASK    ( SERIAL_BUFFER_SIZE - 1 )

typedef struct tSerialBufferTag
{
  int iPutPtr;
  int iGetPtr;
  byte abBuffer[ SERIAL_BUFFER_SIZE ];
} tSerialBuffer;

static volatile tSerialBuffer sInputBuffer;
static volatile tSerialBuffer sOutputBuffer;
static volatile bool boTHRE = TRUE;

void UART_IRQHandler( void )
{
  static char cChar;
  static byte bIIR;

  // What caused the interrupt?
  bIIR = LPC_UART->IIR;
  switch( bIIR & UART_INTERRUPT_SOURCE_MASK )
  {
    case UART_SOURCE_RLS:
      // Not handling this, but clear the interrupt.
      cChar = LPC_UART->LSR;
      break;

    case UART_SOURCE_THRE:
      // The THR is empty.  If there is another character in the Tx
      // buffer, send it now.
      if ( sOutputBuffer.iGetPtr != sOutputBuffer.iPutPtr )
      {
#if 0
        cChar = sOutputBuffer.abBuffer[ sOutputBuffer.iGetPtr & SERIAL_BUFFER_LENGTH_MASK ];
#endif
        sOutputBuffer.iGetPtr++;
        LPC_UART->THR = cChar;
      }
      else
      {
        // nothing to send, indicate transmitter-empty to driver
        boTHRE = TRUE;
      }
      break;

    case UART_SOURCE_RX_TIMEOUT:
    case UART_SOURCE_RX:
      // A character was received.  Place it in the queue of received characters.
      cChar = LPC_UART->RBR;
      if ( sInputBuffer.iPutPtr + 1 != sInputBuffer.iGetPtr )
      {
#if 0
        sInputBuffer.abBuffer[ sInputBuffer.iPutPtr & SERIAL_BUFFER_LENGTH_MASK ] = cChar;
#endif
        sInputBuffer.iPutPtr++;
      }
      break;

    case UART_SOURCE_MSR:
      // @TODO: deal with this properly - for now just clear it
      cChar = LPC_UART->MSR;
      break;

    default:
      // There is nothing to do, leave the ISR.
      break;
  }
}


In the code above, I've commented out the lines that make the hardfault happen.

The fault sometimes happens on the first few characters sent or recieved, other times it happens after several hundred characters.  So it doesn't seem related to the buffer size.

Only other interrupt running is the SysTick interrupt which is handled elsewhere (and only increments a counter for debug).

Any suggestions, anyone?
0 Kudos
Reply
2 Replies

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fentechnt on Mon Feb 15 06:30:37 MST 2010
I did wonder about this, but I don't that is it.

The map file shows that the stack top (_vStackTop) is at 0x10001ff0 and the last variables are at 0x10000710.  There is no dynamic allocation used, so the heap should be unused (starts at 0x10000710).

So there should be plenty of stack available, although I must confess I have no idea whether the interrupt stack is allocated separately or what...

When stepping through the code, the stack pointer is typically somewhere around 0x10001f50 - again indicating that there is plenty stack available.
0 Kudos
Reply

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Mon Feb 15 06:09:33 MST 2010
stack overflow?
0 Kudos
Reply