[En-Nut-Discussion] Major source for crash discovered in UART

Michel Hendriks michel at stream-it.nl
Thu Nov 17 17:08:59 CET 2005


Hi all,
 
I would like to post an improvement I made to uartavr.c a really, really
long time ago. Yes, I know what you're thinking: why don't you use the uSart
routines? Well, i really dont need the added features, I just need to
control a modem and do some logging. Okee, so I didn't guess what you were
thinking but nevertheless here's my problem and fix:
 
We are porting our application from NutOS 3.9.2 to 3.9.8 and are hitting a
few problems. Our application does some streaming over prolonged periods of
time using both uarts extensively, 1 for the modem, the other for logging.
After a few hours NutOS locks up for apparently no reason. With my my fix,
it keeps on streaming non-stop, even for days! I can reproduce this bug
quite easily. If I use the original uartavr.c it locks up. If I use the
fixed version it keeps running.
 
But....I am a little uncertain about my fix as i cannot really explain on
*why* it fixes my problem. Anyway, I needed this fix just as hard on 3.9.2
as I do now on 3.9.8......
 
The fix adds a critical section in UartAvrOutput():

int UartAvrOutput(NUTDEVICE * dev)
{
    IFSTREAM *ifs = dev->dev_icb;
 
    if (ifs->if_tx_act == 0 && ifs->if_tx_idx != ifs->if_wr_idx) {
        /* Michel Hendriks. Do this in a critical section, although it
shouldn't be necessary.. */
        NutEnterCritical();
        ifs->if_tx_act = 1;
#ifdef UDR1
        if (dev->dev_base)
            UDR1 = ifs->if_tx_buf[ifs->if_tx_idx];
        else
#endif
            outp(ifs->if_tx_buf[ifs->if_tx_idx], UDR);
        ifs->if_tx_idx++;
        NutExitCritical();
    }
    return 0;
}


It is the 'although' that makes me a little uncertain about the fix ;-)
 
Greetings,
Michel



More information about the En-Nut-Discussion mailing list