[En-Nut-Discussion] NutOS Bug with ICCAVR
Jean Pierre GAUTHIER
jp.gauthier at wanadoo.fr
Tue Sep 4 17:18:23 CEST 2007
Hello,
NutOS (ATMEGA128, ATMEGA2561, ICCAVR AVR 7.13A Compiler) "inlines"
NutEnterCritical & NutExitCritical functions as a suite of asm instructions.
Unfortunately, the register R0 is destroyed by these functions and the
compiler ICCAVR uses R0 to memorize variables without see that R0 contains
erroneous value after NutEnterCritical & NutExitCritical calls.
The "ICC AVR 7.13A Compiler Bug" described in my previous email (below) was
due to that.
Add an empty function NutDoNothing()in NutEnterCritical & NutExitCritical
permits to quickly avoid this, (because the compiler takes into account
this call and considers R0 as modified by the function?)
My current application (NutOS 3.9.1, ICCAVR 7.05, ATMEGA128/ Ethernut 1.3F)
works perfectly without hang and never reboot.
But migration to NutOs 4.3.99 (ICCAVR 7.13A, Ethernut 1.3F with ATMEGA2561)
isn't so simple. The system reboots sometimes (1 to 3 times / day) during
TCP/IP calls. Even with NutEnterCritical & NutExitCritical modifications...
Somebody has experience with ATMEGA2561 migration / ICCAVR?
Best regards,
Jean Pierre
-----Message d'origine-----
De : en-nut-discussion-bounces at egnite.de
[mailto:en-nut-discussion-bounces at egnite.de] De la part de Jean Pierre
GAUTHIER
Envoyé : vendredi 31 août 2007 16:57
À : 'Ethernut User Chat (English)'
Objet : [En-Nut-Discussion] ICC AVR 7.13A Compiler Bug
Hello,
With the ATMEGA2561, nut/dev/usart.c seems to be bad compiled with ICCAVR
(version 7.13A). (tested with NUTOS 4.2.1 and 4.3.99)
At the end of the UsartRead(NUTFILE * fp, void *buffer, int size) function,
for exemple, when 1 char must be read (size=1), rbf->rbf_cnt is decremented
by 128 instead 1!
To avoid this, insert dummy instruction(s) as below.
Of course other instructions, upon your imagination, should be inserted ;-)
Best regards,
Jean Pierre
End of Nut/dev/usart.c/UsartRead()function :
/*
* Get raw characters from receive buffer.
*/
else {
if ((rc = size) > avail)
rc = avail;
for (taken = 0; taken < rc; taken++) {
*cp++ = *rbf->rbf_tail++;
if (rbf->rbf_tail == rbf->rbf_last) {
rbf->rbf_tail = rbf->rbf_start;
}
}
}
if (taken) {
taken++; // <----------- insert dummy instruction
taken--; // <----------- insert dummy instruction
NutEnterCritical();
rbf->rbf_cnt -= taken ; // a compiler bug was here!!!
NutExitCritical();
if (rbf->rbf_cnt < rbf->rbf_lwm) {
(*dcb->dcb_rx_start) ();
}
}
return (int) rc;
}
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion
More information about the En-Nut-Discussion
mailing list