I am dealing with a puzzling issue in my Arduino code, perhaps you can help. The setup is as follows:
I have an Arduino Uno communicating over Serial to a console program on OSX written using termios. For reference, the OSX application uses posix file descriptors and grand central dispatch to perform reads, though neither of these appears to be at fault. The baud rate is set at 460800 - lowering it has no effect on the problem.
The two devices use a packet structure to communicate over serial. Writes on the Arduino side are executed by taking data out of a buffer and writing it using Serial.write, like so:
uint8_t buffer[BUFFER_SIZE]; // BUFFER_SIZE has max value of 95 bytes
Serial.write(PREAMBLE); // PREAMBLE Is a constant that identifies new data
for (uint8_t i=0; i < BUFFER_SIZE; i++) {
Serial.write(buffer[i]);
}
During setup(), three packets are transmitted and are received without issue on the terminal. Once loop() has started, the terminal sends a packet to the device, which is received in a manner similar to:
void loop()
{
if (Serial.available())
{
// do Serial.read() until we detect the end of the packet (~10 bytes in this case), then stop
// write a response here
}
}
I should note that Serial.read() is only called until the end of the meaningful data is received, NOT until Serial.available() is false. The response is written in the form described above. serialEvent() is not used in this program.
The issue arises when the response is written - specifically the arduino stalls completely. I have managed to figure out (using LEDs) that the lock up takes place in HardwareSerial.cpp on line 390:
size_t HardwareSerial::write(uint8_t c)
{
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
// ???: return 0 here instead?
while (i == _tx_buffer->tail) // <-- PROGRAM STALLS HERE
;
_tx_buffer->buffer[_tx_buffer->head] = c;
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
return 1;
}
The comments suggest that the necessary interrupt is not getting triggered. Even after googling around, I am at a loss as to how this could happen. A possible explanation is presented here: http://bleaklow.com/2012/02/29/why_im_ditching_the_arduino_software_platform.html
Any idea why the interrupt is not being triggered, or how Serial.write could be stalling indefinitely?
Cheers,
gcross2