[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