System: Nano54415
I am using writeall() to block until a write to file descriptor is finished (not a great technique, but I need to toggle a line in my system when the UART transmission is complete). This works ok in debug build, but not a release build. It seems as though the function call returns as soon as the buffer write is completed. Have I goofed (i.e. is there a compiler switch disallowing blocking functions in release builds or something)?
I'm using NNDK 2.6.7 and have not rebuilt my system libraries ever. I would upgrade, but no release notes up to release 2.7.3 seem to indicate these issues discovered or fixed. I hope to not monkey with my development environment unless I must.
The file descriptor to UART1 is opened via SimpleOpenSerial(1, 115200)
NB RunTime lib "Writeall()" not blocking release/NANO54415
-
- Posts: 7
- Joined: Fri Sep 05, 2014 6:51 am
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
You'll need to poll SendSerialComplete after the writeall(). Writeall will return as soon as the data is queued to be sent out the serial port. SendSerialComplete will not return true until both the queue is empty and the transmitter has finished sending the last byte.
-Dan
-Dan
Dan Ciliske
Project Engineer
Netburner, Inc
Project Engineer
Netburner, Inc
-
- Posts: 7
- Joined: Fri Sep 05, 2014 6:51 am
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
Thank you, Dan.
The absence of this function in the Runtime Libraries documentation led me to believe the "blocking until complete" in writeall() meant pending on the physical UART transmitter. My apologies, I see it now in serial.h.
Buuut...I'm pending on its return value turning true...and I hang. I realize I need to be more thorough and have a timeout for robustness sake (not just a dumb while() loop)....is it possible this function has the opposite return value as advertised (true when BUSY rather than done)? THAT seems to work properly....
The absence of this function in the Runtime Libraries documentation led me to believe the "blocking until complete" in writeall() meant pending on the physical UART transmitter. My apologies, I see it now in serial.h.
Buuut...I'm pending on its return value turning true...and I hang. I realize I need to be more thorough and have a timeout for robustness sake (not just a dumb while() loop)....is it possible this function has the opposite return value as advertised (true when BUSY rather than done)? THAT seems to work properly....
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
It returns true when the send is complete...
-
- Posts: 7
- Joined: Fri Sep 05, 2014 6:51 am
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
Dan and "pbreed"
I apologize I had to continue with board bring-up, so I circumvented by using a hiResTimer. But, I wanted to circle back and let you know I still couldn't achieve the correct behavior for the SerialSendComplete() function. I ran the following snippet:
With the following results:
SerialSendComplete before: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
To dig a little deeper, I imported the serial.cpp file into my workspace and altered the source code of SerialSendComplete() a little bit.
(BTW, I had no idea this would compile, link and debug properly, but it seems fine I can single-step).
Anyway, the test of the TXEMP bit of the USR (UART Status) fails:
In the MCF54415 Reference Manual it states that this bit will be zero if the UART transmitter is disabled. Looking at the sim1->uarts->1 peripheral registers, it does seems as though the transmitter is disabled. I'm sorry I couldn't check any deeper, but perhaps the SimpleOpenSerial() mode of opening the serial port and drivers has a DMA interrupt that shuts off the transmitter when the buffer is drained under the hood?
I apologize I had to continue with board bring-up, so I circumvented by using a hiResTimer. But, I wanted to circle back and let you know I still couldn't achieve the correct behavior for the SerialSendComplete() function. I ran the following snippet:
Code: Select all
void tiaWrite(char* txbuf, char mask)
{
int numbytes = strlen(txbuf);
iprintf("SerialSendComplete before: %d\n", SerialSendComplete(fdTIA));
tiaMUXassert(mask);//This will be de-asserted later
writeall(fdTIA, txbuf, numbytes);//Note, this variant of write blocks only until buffer write complete
pTimer->pollingDelay( 1.0E-6 * (numbytes * 80.0 + 100.0) );
for(int i=0;i<10;i++){
iprintf("SerialSendComplete: %d\n", SerialSendComplete(fdTIA));
pTimer->pollingDelay( 1.0E-6 * (80.0 + 100.0) );
}
}
SerialSendComplete before: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
SerialSendComplete: 0
To dig a little deeper, I imported the serial.cpp file into my workspace and altered the source code of SerialSendComplete() a little bit.
(BTW, I had no idea this would compile, link and debug properly, but it seems fine I can single-step).
Code: Select all
BOOL SerialSendComplete(int fd)
{
int portnum = FdSerialMap(fd);
if ((portnum < 0) || (portnum > 9))
return FALSE;
if ((UartData[portnum].m_UartState & UART_INIT) == 0)
return FALSE;
#if 0
if ((UartData[portnum].m_UartState & UART_TX_EMPTY)
&& UartData[portnum].m_FifoWrite.Empty()
&& (Uarts[portnum]->usr & 0x08))
return TRUE;
else
#else
if ( UartData[portnum].m_UartState & UART_TX_EMPTY)
if ( UartData[portnum].m_FifoWrite.Empty() )
if ( Uarts[portnum]->usr & 0x08 )
return TRUE;
#endif
return FALSE;
}
Code: Select all
if ( Uarts[portnum]->usr & 0x08 )
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
You are 100% correct. Currently investigating this...
Dan Ciliske
Project Engineer
Netburner, Inc
Project Engineer
Netburner, Inc
-
- Posts: 7
- Joined: Thu Aug 13, 2015 1:00 pm
Re: NB RunTime lib "Writeall()" not blocking release/NANO544
I just ran into this issue with a MOD5234, NNDK 2.6.2 .
From c:\nburn\MOD5234\system\serial.cpp SerialSendComplete():
From c:\nburn\MOD5234\system\serial.cpp SerialSendComplete():
Code: Select all
if ((UartData[portnum].m_UartState & UART_INIT) == 0)
return FALSE; // Serial port is not open
else {
volatile uartstruct *ThisUart = &sim.uarts[portnum];
if ((UartData[portnum].m_UartState & UART_TX_EMPTY)
&& UartData[portnum].m_FifoWrite.Empty()
&& (ThisUart->usr & 0x08)) <-- this test always fails <---
return TRUE; // Tx registers are empty after sending out
else
return FALSE; // Tx registers are not empty, not yet sent out