I've tried a variety of devices with the software serial. Â Originally I started testing with connecting to a APC SmartUPS at 2400 baud through a MAX232. Â When I was getting the unexplained lockups, I connected next to a PC serial port (again through the MAX232) so I could manually send data to the software serial. Â Trying to eliminate the MAX232 as the possible problem, I next connected directly to a ID-12 RFID module which outputs TTL-level serial (at 9600 baud). Â In all cases the results were the same and the software serial locks up after a few rapid characters. Â It's random as to how many characters make it before the lock.
I tried AFSoftSerial and get the same lockups.
I did some digging in the source and was able to confirm the problem is somewhere in the recv() called by the interrupts. Â Commenting out the code (but leaving the definition) in NewSoftSerial::recv() stops the lockups - but obviously also stops any data. Â In playing with the code I find that if I leave any more code then the initial digitalRead if, I get lockups. Â So this code doesn't lock up (but also obviously doesn't return any data).
void NewSoftSerial::recv()
{
 char i, d = 0;
 if (digitalRead(_receivePin))
  return;    // not ready!
/*
 tunedDelay(_bitDelay - 8);
 for (i=0; i<8; i++) {
  //PORTB |= _BV(5);
  tunedDelay(_bitDelay*2 - 6);  // digitalread takes some time
  //PORTB &= ~_BV(5);
  if (digitalRead(_receivePin))
   d |= (1 << i);
 }
 tunedDelay(_bitDelay*2);
 // buffer full?
 if ((_receive_buffer_tail + 1) % _NewSS_MAX_RX_BUFF == _receive_buffer_head)
  return;
 _receive_buffer[_receive_buffer_tail++] = d; // save new byte
 if (_receive_buffer_tail == _NewSS_MAX_RX_BUFF)
  _receive_buffer_tail = 0;
*/
}
I think the problem might either have something to do with calling the digitalRead function or simply having the code running during the interrupt taking too long. Â As a trivial case, I replaced the recv() function with:
void NewSoftSerial::recv()
{
 if (digitalRead(_receivePin))
  return;    // not ready!
}
While the code will obviously return no data, I also get no lockups. Â If I add one more digitalRead() like this:
void NewSoftSerial::recv()
{
 if (digitalRead(_receivePin))
  return;    // not ready!
 if (digitalRead(_receivePin))
  return;    // not ready!
}
Then I get the lockups.
Another probably unrelated weirdness that I stumbled across is with the tunedDelay() assembly. Â While commenting out different bits of code to test, I found that if I had two calls to tunedDelay() one after another, I would get the following compile errors:
/var/tmp//cc0RgyXU.s: Assembler messages:
/var/tmp//cc0RgyXU.s:940: Error: register r24, r26, r28 or r30 required
I don't know AVR assembly so I can't really debug further. Â Maybe there's a word alignment problem when the two assembly blocks are placed one after another?
I can't explain why your tests work fine and every test I try fails with lockups. Â I've tried an Arduino NG, an Adafruit Boardurino, and a bare ATmega 168 on a breadboard with the Diecimila bootloader and get the same results with each (all at 16MHz). Â I've even tried different pins for the software serial with no change.
Hopefully this info helps.
Thanks