NB RunTime lib "Writeall()" not blocking release/NANO54415

Discussion to talk about software related topics only.
Post Reply
mstrzelczyk
Posts: 7
Joined: Fri Sep 05, 2014 6:51 am

NB RunTime lib "Writeall()" not blocking release/NANO54415

Post by mstrzelczyk »

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)
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by dciliske »

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 Ciliske
Project Engineer
Netburner, Inc
mstrzelczyk
Posts: 7
Joined: Fri Sep 05, 2014 6:51 am

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by mstrzelczyk »

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....
User avatar
pbreed
Posts: 1088
Joined: Thu Apr 24, 2008 3:58 pm

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by pbreed »

It returns true when the send is complete...
mstrzelczyk
Posts: 7
Joined: Fri Sep 05, 2014 6:51 am

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by mstrzelczyk »

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:

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) );
	}
}
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).

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;
}
Anyway, the test of the TXEMP bit of the USR (UART Status) fails:

Code: Select all

if ( Uarts[portnum]->usr & 0x08 )
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?
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by dciliske »

You are 100% correct. Currently investigating this...
Dan Ciliske
Project Engineer
Netburner, Inc
krastatter
Posts: 7
Joined: Thu Aug 13, 2015 1:00 pm

Re: NB RunTime lib "Writeall()" not blocking release/NANO544

Post by krastatter »

I just ran into this issue with a MOD5234, NNDK 2.6.2 .

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
Post Reply