[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