[En-Nut-Discussion] Weird problem...

Radek Podgorny radek at podgorny.cz
Mon Aug 2 16:03:27 CEST 2004


Hi,

I'm experiencing strange behaviour of my program with the latest NutOS 
(3.4.2), in 3.3.3 everything works just fine...

The program execution suddenly stops (only within a thread) but I cant figure 
out why... :-(

See tha attached program. Place that doesnt get executed marked 
with !!!***!!!, last line executed with ---***---. Thread input_thread.

Thanks in advance for any help or ideas what has changed since 3.3.3...
Radek Podgorny

P.S.: Sorry for such a long listing but I dont know what code could be useful 
for you...
P.P.S.: Another weird thing. When I add a printf() at the beginning of each 
thread, all gets written fine but none of the threads seem to continue 
running... :-(

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

#include <stdio.h>
#include <string.h>
#include <io.h>
#include <stdlib.h>

#include <dev/nicrtl.h>
#include <dev/uartavr.h>

#include <sys/version.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/heap.h>
#include <sys/confnet.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#include <pro/dhcp.h>


#define HEAD	0x55
#define HEAD2	0xAA
#define TAIL	0xCC

#define INSIZE	70
#define OUTSIZE	24


unsigned long addr;

unsigned char counters_offset;
unsigned char counters_reset;
int counters[8];

unsigned char errors;

unsigned char oldseq;

unsigned char firstparse;


void GenPacket(unsigned char *buf)
{
	buf[0] = HEAD;
				
	// Sequence
	buf[1]++;
			
	buf[2] = HEAD2;

	// PC -> nut errors
	buf[3] = errors;

	// Counters here
	memcpy(buf+4, &counters, 16);

	// Digital inputs
	memcpy(buf+20, (void *)0xe000, 16);

	// Analog inputs
	void *abuf = buf+36;
				
	unsigned char c = 0;
	for (c = 0; c < 2; c++) {
		// Board not present, no others expected
		if (*((unsigned char *)(0xe0a2+c*4)) & 0x01)
			break;
					
		unsigned char subc = 0;
		for (subc = 0; subc < 8; subc++) {
			unsigned char cb = 0x40 | 0x18 | subc;
						
			// First measuring
			*((unsigned char *)(0xe0a0+c*4)) = cb;
			NutSleep(1);
			memcpy(abuf+(c*8+subc)*2, (void *)(0xe0a0+c*4), 2);
					
			// Adjust the range and polarity
			unsigned char tmp = *((unsigned char *)(0xe0a1+c*4)) & 0x0c;
			if (tmp == 0x00) cb &= 0xe7;
			else if (tmp == 0x04) cb &= 0xf7;
			else if (tmp == 0x0c) cb &= 0xef;

			// Second measuring
			*((unsigned char *)(0xe0a0+c*4)) = cb;
			NutSleep(1);
			memcpy(abuf+(c*8+subc)*2, (void *)(0xe0a0+c*4), 2);
						
			// Modify the result according to range adjustments
			if (cb & 0x10) *((int *)(abuf+(c*8+subc)*2)) *= 2;
			if (cb & 0x08) *((int *)(abuf+(c*8+subc)*2)) *= 2;
		}
	}
	// End of analog inputs

	// Fake checksum
	buf[INSIZE-2] = 0;

	buf[INSIZE-1] = TAIL;
}

void ParsePacket(unsigned char *buf)
{
	if (firstparse) {
		oldseq = buf[1]-1;
		firstparse = 0;
	}

	// Sequence (error counts)
	if (buf[1] != ++oldseq)
		errors++;
	oldseq = buf[1];
	// End of sequence

	// Output relay
	if (buf[3] == 1)
		outp(inp(PORTD) & ~0x02, PORTD);
	else
		outp(inp(PORTD) | 0x02, PORTD);
	// End of output relay

	// Counters offset
	counters_offset = buf[4];

	// Conters reset
	counters_reset = buf[5];

	// Digital outputs
	memcpy((void *)0xe000, buf+6, 16);
	

	// LED blinking
	if (buf[1] & 0x40)
		outp(inp(PORTD) & ~0x01, PORTD);
	else
		outp(inp(PORTD) | 0x01, PORTD);
}

THREAD(counters_thread, arg)
{
	unsigned char old = 0;

	for (;;) {
		if (counters_offset != 255) {
			int b = 1;
			int c = 0;
			for (c = 0; c < 8; c++) {
				// Changes
				if ((*(unsigned char *)(0xe000+counters_offset) & b) != (old & b))
					counters[c]++;

				// Resets
				if (counters_reset & b)
					counters[c] = 0;

				b*=2;
			}

			old = *(unsigned char *)(0xe000+counters_offset);
		}
		
		NutSleep(10);
	}
}

THREAD(input_thread, arg)
{
	UDPSOCKET *sock;
	
	while ((sock = NutUdpCreateSocket(0)) == 0) {
		printf("[input] Creating socket failed\n");
		NutSleep(500);
	}

	// Wait for the PC to start
	while (addr == 0)
		NutSleep(100); ---***---
!!!***!!!

	unsigned char *buf = (unsigned char *)malloc(INSIZE);
	memset(buf, 0, INSIZE);
	buf[1] = 255;

	// The measuring loop
	for (;;) {
		GenPacket(buf);

		// Send the packet now
		unsigned short port = 2000;
		NutUdpSendTo(sock, addr, port, buf, INSIZE);

		NutSleep(30);
	}
			
	free(buf);

	NutUdpDestroySocket(sock);
}


THREAD(output_thread, arg)
{
	UDPSOCKET *sock;

	while ((sock = NutUdpCreateSocket(2000)) == 0) {
		printf("[output] Creating socket failed\n");
		NutSleep(500);
	}
	
	unsigned char *buf = (unsigned char *)malloc(OUTSIZE);
	memset(buf, 0, OUTSIZE);
	
	for (;;) {
		// Wait for data
		unsigned short port = 0;
		while (NutUdpReceiveFrom(sock, &addr, &port, buf, OUTSIZE, 0) <= 0)
			NutSleep(1);

		ParsePacket(buf);

		// Ask the watchdog not to kill us
		outp(inp(PORTD) | 0x04, PORTD);
		NutSleep(10);
		outp(inp(PORTD) & ~0x04, PORTD);
		// End of watchdog
	}
		
	free(buf);

	NutUdpDestroySocket(sock);
}

int main(void)
{
	// Init globals
	addr = 0;

	counters_offset = 255;
	counters_reset = 0;
	int c = 0;
	for (c = 0; c < 8; c++)
		counters[c] = 0;
	
	firstparse = 1;
	oldseq = 255;
	// End of globals init
	
	// Set port D pins 1 and 2 (counting from 0) to output and reset them
	outp(0x00, PORTD);
	outp(0x07, DDRD);
	outp(inp(PORTD) | 0x02, PORTD);
	
	
	unsigned long baud = 38400;

	NutRegisterDevice(&devUart0, 0, 0);
	freopen("uart0", "w", stdout);
	_ioctl(_fileno(stdout), UART_SETSPEED, &baud);
	NutSleep(200);
	printf("\n\nNut/OS %s - Asterix NUT-1 (20040607)\n\n", NutVersionString()); 

	if (NutRegisterDevice(&devEth0, 0x8300, 5)) 
		puts("Registering device failed");

//	if (NutDhcpIfConfig("eth0", 0, 60000)) {
		unsigned char mac[] = { 0x00,0x06,0x98,0x00,0x00,0x00 };
		unsigned long ip_addr = inet_addr("192.168.0.200");
		unsigned long ip_mask = inet_addr("255.255.255.0");

//		puts("EEPROM/DHCP/ARP config failed");
		NutNetIfConfig("eth0", mac, ip_addr, ip_mask);
//	}
	printf("%s ready\n", inet_ntoa(confnet.cdn_ip_addr));


	NutThreadCreate("counters", counters_thread, NULL, 640);
	NutThreadCreate("input", input_thread, NULL, 640);
	NutThreadCreate("output", output_thread, NULL, 640);


	NutThreadSetPriority(254);

	for (;;) 
		NutThreadYield();
}

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

-- 
GnuPG key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x98E56D84
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: signature
URL: <http://lists.egnite.de/pipermail/en-nut-discussion/attachments/20040802/5a2b10c3/attachment-0001.pgp>


More information about the En-Nut-Discussion mailing list