Abnormal behavior using Ethernet_sendUDP. Possibly a bug.

General discussion on mikroC.
Post Reply
Author
Message
Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Abnormal behavior using Ethernet_sendUDP. Possibly a bug.

#1 Post by Rodney » 21 Sep 2011 12:04

Hello Fellow Programmers
I have noticed a strange behavior when using the Ethernet_sendUDP function.
When the MAC address of the PIC is set to FF FF FF FF FF FF the program hangs up when trying to send a UDP packet.
I have written a simple code to test this.
When the MAC address is set to a proper value I made my code send a UDP packet every 2 seconds and it works
When the MAC address is set to all F the program hangs up.
Is this a bug or the normal behavior of the function.
I understand that a device should never have a MAC of all Fs.
I want to know as I spent hours trying to figure out why my program hanged up.
The other ethernet libraries work when an all Fs MAC address is used. Only the Ethernet_sendUDP function does not work.
I can post my code if needed.
Cheers
Rodney

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#2 Post by janko.kaljevic » 22 Sep 2011 14:09

Hello,

It is not usual to set broadcast MAC address as address of your PIC.
Commonly this is used when the all nodes need to accept the packet.

I have tried this case, and it works fine.
Please check from where do you call send_UDP function.
Just as reminder: you can not call it from user_UDP or user_TCP

Best regards.

Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#3 Post by Rodney » 23 Sep 2011 09:22

Hi Janko
It is not the IP address which is set t0 255.255.255.255 but the MAC address, which is not related to broadcast addressing.
The MAC is a unique number assigned to each device. I know this should never be set to all 1s but if it actually happens the UDP library should not hang up the microprocessor.
Someone from the mikroelektonika team might be able to tell us about this as it is the library i believe is causing the PIC to stop working.
Thanks
Rodney

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#4 Post by janko.kaljevic » 23 Sep 2011 13:26

Hello,

Please tell me how did you use Ethernet_sendUDP function.
Also if you can post here project that describes this issue.

Best regards.

Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#5 Post by Rodney » 23 Sep 2011 13:40

Hi Again
This program works. It sends a UDP packet and a serial string every 2 seconds

Code: Select all

// Ethernet Addressing Variables
// These are the default addresses
unsigned char myMacAddr[6];
unsigned char myIpAddr[4];
unsigned char gwIpAddr[4];
unsigned char ipMask[4];
unsigned char dnsIpAddr[4];
unsigned char NMSIPAddress[4];
unsigned int x,y;

void interrupt ()
{
}
typedef struct {
  unsigned canCloseTCP: 1;  // flag which closes socket
  unsigned isBroadcast: 1;  // flag which denotes that the IP package has been received via subnet broadcast address (not used for PIC16 family)
} TEthPktFlags;

unsigned int Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, 
             unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
unsigned int    Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
void main()
{
  TRISA = 0b00000000;   PORTA = 0;   LATA = 0;
  TRISB = 0b00000000;   PORTB = 0;   LATB = 0;
  TRISC = 0b00000001;   PORTC = 0;   LATC = 0;
  TRISD = 0b00000000;   PORTD = 0;   LATD = 0;
  TRISE = 0b11111111;   PORTE = 0;   LATE = 0;
  TRISF = 0b00000000;   PORTF = 0;   LATF = 0;
  TRISG = 0b00000000;   PORTG = 0;   LATG = 0;
  TRISH = 0b00000000;   PORTH = 0;   LATH = 0;
  TRISJ = 0b00000000;   PORTJ = 0;   LATJ = 0;
  
  myIpAddr[0] = 192;
  myIpAddr[1] = 168;
  myIpAddr[2] = 8;
  myIpAddr[3] = 60;

  gwIpAddr[0] = 192;
  gwIpAddr[1] = 168;
  gwIpAddr[2] = 8;
  gwIpAddr[3] = 255;

  ipMask[0] = 255;
  ipMask[1] = 255;
  ipMask[2] = 255;
  ipMask[3] = 0;

  dnsIpAddr[0] = 192;
  dnsIpAddr[1] = 168;
  dnsIpAddr[2] = 8;
  dnsIpAddr[3] = 254;

  NMSIPAddress[0] = 192;
  NMSIPAddress[1] = 168;
  NMSIPAddress[2] = 8;
  NMSIPAddress[3] = 50;

  myMacAddr[0] = 1;
  myMacAddr[1] = 2;
  myMacAddr[2] = 3;
  myMacAddr[3] = 4;
  myMacAddr[4] = 5;
  myMacAddr[5] = 6;

  // Initialise USART
  Uart1_Init(9600);
  ADCON1 = 1;
  CMCON = 7;
  Ethernet_Init(myMacAddr, myIpAddr, 0) ;
  Ethernet_confNetwork(ipMask, gwIpAddr, dnsIpAddr) ;
  
  while (1)
  {
    delay_ms(2000);
    Ethernet_doPacket() ;
    UART1_Write_Text("Hello");
    Ethernet_sendUDP (NMSIPAddress, 25000, 162, "Hello", 46);
  }
}
This Program Does not work

Code: Select all

// Ethernet Addressing Variables
// These are the default addresses
unsigned char myMacAddr[6];
unsigned char myIpAddr[4];
unsigned char gwIpAddr[4];
unsigned char ipMask[4];
unsigned char dnsIpAddr[4];
unsigned char NMSIPAddress[4];
unsigned int x,y;

void interrupt ()
{
}
typedef struct {
  unsigned canCloseTCP: 1;  // flag which closes socket
  unsigned isBroadcast: 1;  // flag which denotes that the IP package has been received via subnet broadcast address (not used for PIC16 family)
} TEthPktFlags;

unsigned int Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, 
             unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
unsigned int    Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
void main()
{
  TRISA = 0b00000000;   PORTA = 0;   LATA = 0;
  TRISB = 0b00000000;   PORTB = 0;   LATB = 0;
  TRISC = 0b00000001;   PORTC = 0;   LATC = 0;
  TRISD = 0b00000000;   PORTD = 0;   LATD = 0;
  TRISE = 0b11111111;   PORTE = 0;   LATE = 0;
  TRISF = 0b00000000;   PORTF = 0;   LATF = 0;
  TRISG = 0b00000000;   PORTG = 0;   LATG = 0;
  TRISH = 0b00000000;   PORTH = 0;   LATH = 0;
  TRISJ = 0b00000000;   PORTJ = 0;   LATJ = 0;
  
  myIpAddr[0] = 192;
  myIpAddr[1] = 168;
  myIpAddr[2] = 8;
  myIpAddr[3] = 60;

  gwIpAddr[0] = 192;
  gwIpAddr[1] = 168;
  gwIpAddr[2] = 8;
  gwIpAddr[3] = 255;

  ipMask[0] = 255;
  ipMask[1] = 255;
  ipMask[2] = 255;
  ipMask[3] = 0;

  dnsIpAddr[0] = 192;
  dnsIpAddr[1] = 168;
  dnsIpAddr[2] = 8;
  dnsIpAddr[3] = 254;

  NMSIPAddress[0] = 192;
  NMSIPAddress[1] = 168;
  NMSIPAddress[2] = 8;
  NMSIPAddress[3] = 50;

  myMacAddr[0] = 255;
  myMacAddr[1] = 255;
  myMacAddr[2] = 255;
  myMacAddr[3] = 255;
  myMacAddr[4] = 255;
  myMacAddr[5] = 255;

  // Initialise USART
  Uart1_Init(9600);
  ADCON1 = 1;
  CMCON = 7;
  Ethernet_Init(myMacAddr, myIpAddr, 0) ;
  Ethernet_confNetwork(ipMask, gwIpAddr, dnsIpAddr) ;
  
  while (1)
  {
    delay_ms(2000);
    Ethernet_doPacket() ;
    UART1_Write_Text("Hello");
    Ethernet_sendUDP (NMSIPAddress, 25000, 162, "Hello", 46);
  }
}
The only thing that changed is the MAC address

Thanks for your help

Cheers
Rodney

Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#6 Post by Rodney » 01 Oct 2011 04:56

Hello
I believe this is a query that only someone of the mikroE support team will be able to answer as the problem probably is in the source code of the function.
After more work on this issue, I just realised it is not the MAC address which makes it hang up but if it does not find the recipient.
If the Ethernet_sendUDP function is executed and the recipient is not found on the first try the program hangs up.

I tried to run the program below and if a device with IP 192.168.8.50 is not found the program stops running.

This is the sequence of events of a successful run:
- The code was compiled and downloaded.
- A PC with IP address 192.168.8.50 was started up and wireshark run
- The microprocessor was restarted and the 'Hello' String was sent to the UART port and UDP packet received by wireshark
- The program kept running sending a UART string and a UDP packet every second
- SUCCESS

This is the sequence of events of a failed run:
- The PC's ethernet port was disabled making it unavailable to the network
- The microprocessor was restarted
- The 'Hello' String was successfully sent
- It is unknown if the UDP function was sent or not as there was no wireshark running but the program hanged up as no other UART packets were sent
- Program stops running
- FAILED

I would have expected the UDP packet to be sent, and whether there was a recipient or not, the program should still keep running and sending a "Hello" string on the UART port every second.

I tried to run these two steps repeatedly and they always produce the same results.

The UDP packet is just a packet sent on the network without expectation of the recipient being there. The program should not hang up if it is not available.
I have an application running SNMP and I am using the Ethernet_sendUDP function to send SNMP traps. I do not expect the program to hang up if the NMS PC is not on the network.

Is this function expecting any feedback from the network when ran ?
I would like to solve this problem ASAP as I need to finish this program.

Thanks for your help.
Code Below.
Thanks
Rodney

Code: Select all

// Ethernet Addressing Variables
// These are the default addresses
unsigned char myMacAddr[6];
unsigned char myIpAddr[4];
unsigned char gwIpAddr[4];
unsigned char ipMask[4];
unsigned char dnsIpAddr[4];
unsigned char NMSIPAddress[4];
unsigned int x,y;

void interrupt ()
{
}
typedef struct {
  unsigned canCloseTCP: 1;  // flag which closes socket
  unsigned isBroadcast: 1;  // flag which denotes that the IP package has been received via subnet broadcast address (not used for PIC16 family)
} TEthPktFlags;

unsigned int Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, 
             unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
unsigned int    Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags)
{
  return 0;
}
void main()
{
  TRISA = 0b00000000;   PORTA = 0;   LATA = 0;
  TRISB = 0b00000000;   PORTB = 0;   LATB = 0;
  TRISC = 0b00000001;   PORTC = 0;   LATC = 0;
  TRISD = 0b00000000;   PORTD = 0;   LATD = 0;
  TRISE = 0b11111111;   PORTE = 0;   LATE = 0;
  TRISF = 0b00000000;   PORTF = 0;   LATF = 0;
  TRISG = 0b00000000;   PORTG = 0;   LATG = 0;
  TRISH = 0b00000000;   PORTH = 0;   LATH = 0;
  TRISJ = 0b00000000;   PORTJ = 0;   LATJ = 0;
  
  myIpAddr[0] = 192;
  myIpAddr[1] = 168;
  myIpAddr[2] = 8;
  myIpAddr[3] = 60;

  gwIpAddr[0] = 192;
  gwIpAddr[1] = 168;
  gwIpAddr[2] = 8;
  gwIpAddr[3] = 255;

  ipMask[0] = 255;
  ipMask[1] = 255;
  ipMask[2] = 255;
  ipMask[3] = 0;

  dnsIpAddr[0] = 192;
  dnsIpAddr[1] = 168;
  dnsIpAddr[2] = 8;
  dnsIpAddr[3] = 254;

  NMSIPAddress[0] = 192;
  NMSIPAddress[1] = 168;
  NMSIPAddress[2] = 8;
  NMSIPAddress[3] = 50;

  myMacAddr[0] = 1;
  myMacAddr[1] = 2;
  myMacAddr[2] = 3;
  myMacAddr[3] = 4;
  myMacAddr[4] = 5;
  myMacAddr[5] = 6;

  // Initialise USART
  Uart1_Init(9600);
  ADCON1 = 1;
  CMCON = 7;
  Ethernet_Init(myMacAddr, myIpAddr, 0) ;
  Ethernet_confNetwork(ipMask, gwIpAddr, dnsIpAddr) ;
  
  while (1)
  {
    delay_ms(1000);
    Ethernet_doPacket() ;
    UART1_Write_Text("Hello");
    Ethernet_sendUDP (NMSIPAddress, 25000, 162, "Hello", 5);
  }
}

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#7 Post by janko.kaljevic » 03 Oct 2011 15:54

Hello,

From your code I do not see that you incremented Ethernet_userTimerSec variable every second.
Please check the help file for this library for more details.

When Ethernet_sendUDP function does not get response it will resend request for several seconds and then exit this routine.
If you do not increment this value, function will be locked waiting.
This could be cause of the behavior that you have experienced.

Best regards.

Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#8 Post by Rodney » 03 Oct 2011 18:25

Thanks for the feedback Janko
How is the Ethernet_userTimerSec variable used? This is only mentioned once in the help file, but there is no explanation how it should be used in conjunction with the other functions in the Ethernet Library.
Also, UDP is not a two way protocol, i.e. it should not wait for a response to work.
Cheers
Rodney

Rodney
Posts: 82
Joined: 10 Mar 2007 06:47
Location: New Zealand

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#9 Post by Rodney » 04 Oct 2011 07:57

Hi
How is the Ethernet_userTimerSec supposed to be used. Should it be reset before the UDP function is invoked, or just kept running until it rolls over ?
Cheers
Rodney

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Abnormal behavior using Ethernet_sendUDP. Possibly a bug

#10 Post by janko.kaljevic » 04 Oct 2011 13:32

Hello,

Ethernet_userTimerSec needs to be changed every second (you may choose different time period). You do not need to worry about it's initial value or when it will roll over.
You can increment it in interrupt routine, for example.

In SendUDP function will invoke SPI_Ethernet_24j600_arpResolve function which will resolve MAC address. This will take 5 seconds every time while the MAC address is not resolved. When you get MAC address for the first time it will be stored in ARP cash structure, and it will not wait for 5s again.

Please check this function in help file for more details.

Best regards.

Post Reply

Return to “mikroC General”