Are there common causes for sprintf
to suddenly stop functioning as expected in an embedded environment?
Microcontroller: PIC24FJ128GB204
char temp[4];
sprintf(temp, "%d,", (uint8_t)98);
The code above ideally prints "98\0" to temp
array. However, once the problem starts, I see that temp is written as "0,\0\0".
My microcontroller has uart and is receiving from another microcontroller (micro2). The micro2 sends a large number of characters whenever its reset pin is toggled (really, just a string that tells the configurations, firmware version etc). The microcontroller (main) receives these string in uart via circular buffer.
I am able to replicate the problem by repeatedly resetting micro2 (via pushbutton). Once the problem occurs, I see that sprintf no longer behaves normally.
The receive buffer for the uart receive (from micro2) is handled in ISR.
void uart_rx_ring_write (void)
{
unsigned char dummy;
if(uart3_generic_rx_byte_cnt < UART3_BUFFER_SIZE)
{
uart3_generic_rx_buffer[uart3_generic_rx_tail] = U3RXREG;
uart3_generic_rx_tail++;
if(uart3_generic_rx_tail >= UART3_BUFFER_SIZE)
{
uart3_generic_rx_tail = 0;
}
uart3_generic_rx_byte_cnt++;
}
else if (uart3_generic_rx_byte_cnt > UART3_BUFFER_SIZE)
{
uart3_generic_rx_byte_cnt = UART3_BUFFER_SIZE;
dummy = U3RXREG;
}
else
{
dummy = U3RXREG; // new data will be disregarded if buffer is full
}
uart3_generic_rx_timer = 0;
}
void __attribute__((interrupt,auto_psv)) _U3RXInterrupt (void)
{
IFS5bits.U3RXIF = 0;
uart_rx_ring_write ();
interrupts_flags.uartrx_tmr_to = false;
interrupts_flags.uartrx_tmr_en = true;
}
The following shows the destination array's (actual application code) sample data for the case when problem has occurred. The value of the array was checked via PICKIT 5 programmer/debugger and the memory view in MPLAB X IDE.
GPIO 0000000000 2000-00-00 00:00:00.000\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
The date format is YYYY-MM-DD so 00-00 should be 11-13 (during normal operations) to correspond to November 13.
98
, or are you actually printing a single-byte variable? \$\endgroup\$sprintf()
and friends are not in general thread-safe, and if you're calling it from multiple threads or from an ISR, it will eventually fail. \$\endgroup\$