[En-Nut-Discussion] Ethernut on TI's Cortex-M3 (Stellaris LM3S...)

Philipp Burch phip at hb9etc.ch
Mon Nov 5 23:18:09 CET 2012


Hi Ole, hi all,

it looks like the UART driver is basically working, but now there is a 
very strange behaviour of the compiler/processor. My test application 
from the Wiki looks like this:

------ 8< -------- 8< ---------
#include <dev/board.h>
#include <stdio.h>
#include <io.h>
#include <sys/timer.h>
#include <string.h>

void PrintSomeMore(char *format, ...)
{
     char yet_another_string[256];
     va_list argument_list;

     va_start(argument_list, format);
     vsprintf(yet_another_string, format, argument_list);
     va_end(argument_list);

     puts(yet_another_string);
}

int main(void)
{
     unsigned long baud = 115200;
     char text[256];
     CONST char *some_other_text = "world";

     NutRegisterDevice(&DEV_UART, 0, 0);
     freopen(DEV_UART_NAME, "w", stdout);
     freopen(DEV_UART_NAME, "r", stdin);
     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);

     puts("\nNut/OS Printing to strings example");

     /* using printf with a fixed number of arguments */
     sprintf(text, "Hello %s!", some_other_text);
     puts(text);

     /* using vsprintf with an argument list */
     PrintSomeMore("Some numbers: %d, %d, %d", 21, 99, 4431);

     NutSleep(1000);

     printf("Type any key: ");
     char c = getchar();
     printf("\nYou typed %d.\n", c);
     int i;
     //scanf("%d", &i);

     for (;;) {
       NutSleep(2000);
       puts("More text\r\n");
     }
     return 0;
}
------ 8< -------- 8< ---------

When I run it, everything works well. The hello messages are printed, I 
am able to enter a character and it prints a line every two seconds. But 
as soon as I uncomment the scanf() line just before the endless loop, 
the program no longer does anything.
Digging through it with the debugger, I found out that the processor 
hangs in the IntDefaultHandler(). It gets there while it is executing 
the _ioctl() call and the offending interrupt (as mentioned in the xPSR 
register) is -- UART0. That's strange.

Ok, so I've stepped through the code to see what happens before and what 
I've seen there is even stranger: When NutRegisterDevice(...) is called, 
everything is fine until line 176 in devreg.c:

         if(dev->dev_init == 0 || (*dev->dev_init)(dev) == 0) {

After executing this line, the processor ends up in UsartIOCtl() instead 
of UsartInit()! When I print the devUartLm3s_0 structure (the NUTDEVICE 
structure for this UART), it looks like this:

------ 8< -------- 8< ---------
(gdb) print devUartLm3s_0
$1 = {dev_next = 0x74726175, dev_name = "0\000\000\000\000\005\000\000",
   dev_type = 192 '\300', dev_base = 5, dev_irq = 0 '\000',
   dev_icb = 0x20000120, dev_dcb = 0x294d, dev_init = 0x3049 <UsartIOCtl>,
   dev_ioctl = 0x2a2d <UsartRead>, dev_read = 0x2ea5 <UsartWrite>,
   dev_write = 0x2f51 <UsartOpen>, dev_open = 0x2ec9 <UsartClose>,
   dev_close = 0x3589 <UsartSize>, dev_size = 0x200001d4}
------ 8< -------- 8< ---------

Compared to this when scanf() is commented, which looks much more sensible:
------ 8< -------- 8< ---------
(gdb) print devUartLm3s_0
$2 = {dev_next = 0x0, dev_name = "uart0\000\000\000", dev_type = 5 '\005',
   dev_base = 1073790976, dev_irq = 5 '\005', dev_icb = 0x0,
   dev_dcb = 0x2000011c, dev_init = 0x293d <UsartInit>,
   dev_ioctl = 0x3039 <UsartIOCtl>, dev_read = 0x2a1d <UsartRead>,
   dev_write = 0x2e95 <UsartWrite>, dev_open = 0x2f41 <UsartOpen>,
   dev_close = 0x2eb9 <UsartClose>, dev_size = 0x3579 <UsartSize>}
------ 8< -------- 8< ---------

So obviously there is an offset of one pointer (4 bytes) in the 
structure. When comparing the map files, the structure is located at 
0x200001d0 for the working example (without scanf()) and at 0x200001d4 
when it's wrong.

What could cause such a behaviour? I'd like to do more debugging, but 
not today evening (in fact, not before Wednesday), so if someone has a 
hint, please drop me a note.

Thanks,
Philipp


More information about the En-Nut-Discussion mailing list