[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] Uart lite hanging



Greetings,

I recently wrote to this mailing list asking for help about the same
subject. I think I might be suffering from something similar to the flip
buffer bug in xmbserial.

I'm using kernel 2.6 (found in petalinux v0.30-rc1) and uartlite driver
on a Spartan3 1600E Microblaze edition evaluation board.

In my test program I simply send out a chunk of 100 bytes continuously
to serial 0, write 100 lines of debug strings to stderr and toggle two
leds.

I run it with "test 2> test.err" so to not overload the telnet console
with stderr data.

If I copy and paste a big block of data (I used a 64K file) in minicom
the microblaze application hangs on istruction RAM_BASE + 0x1e08.

I have disabled console on uart 0, but tried the application on uart1
(the DCE connector on the evaluation board), too with the same results.
Also tried with uart 16550 driver (thanks to john for his post
http://developer.petalogix.com/changeset/4475)
I always get the same results.

It seems harder to encounter the hang if the sprintf statements are
removed.

I would be very glad if somebody else could confirm this behaviour and
suggest me what to do to overcome this issue.

Please note that I encountered this issue in other ways (with no need to
do cut & paste), too, but this is the easiest path to trigger the
problem.

Many thanks for any help you could provide me,

Giulio Mazzoleni

---------------------------

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/autoconf.h>
#include <linux/types.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>

/***************************************************/
#define LED_BASEADDR	CONFIG_XILINX_GPIO_0_BASEADDR
/***************************************************/

#define LED_VALUE		*(volatile __u32 *)(LED_BASEADDR + 0x00)
#define LED_DIR			*(volatile __u32 *)(LED_BASEADDR + 0x04)

typedef enum {
	false,
	true
} bool;

int		uart_dev;
char	debug_str[100];

static unsigned char led_value;

void led_init (void) {
	LED_DIR = 0;
}

void led_on (unsigned int led_num) {
	led_value |= (1<<led_num);
	LED_VALUE = led_value;
}

void led_off (unsigned int led_num) {
	led_value &= ~(1<<led_num);
	LED_VALUE = led_value;
}

unsigned int led_toggle (unsigned int led_num) {
	led_value ^= (1<<led_num);
	LED_VALUE = led_value;

	return ((led_value & (1<<led_num)) >> led_num);
}

void uart_init ()
{
	struct termios 		t;

	if ((uart_dev = open ("/dev/ttyS0", O_WRONLY | O_NOCTTY)) < 0)
	{
		perror ("open");
		exit (1);
	}

    // Make the file descriptor asynchronous
	fcntl(uart_dev, F_SETFL, FASYNC);

    tcflush(uart_dev, TCOFLUSH);

	// Flush struct for port settings
	bzero(&t, sizeof(t));

	// set the serial port to : 115200, 8 bits of data, no parity
	t.c_cflag = CS8 | B115200 | CREAD;
	t.c_iflag = IGNPAR;
	t.c_oflag = 0;
	t.c_lflag = 0;
	t.c_cc[VTIME] = 1;   // inter-character timer
	t.c_cc[VMIN]  = 255; // blocking read until 1 char received

	cfmakeraw(&t);

	if (tcsetattr(uart_dev, TCSANOW, &t) < 0)
		perror("setAttr");
}

int main(int argc, char *argv[])
{
	int i;

	LED_DIR = 0;

	for (i=0; i<100; ++i)
		debug_str[i] = i;

	uart_init();

	while (1)
	{
		if (write(uart_dev, debug_str, sizeof(debug_str)) < 0)
			perror ("");

		led_toggle(1);

		for (i=0; i<100; ++i)
			fprintf (stderr, "Iteration %d\n", i++);

		led_toggle(0);
	}

	return 0;
}


___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/