TODOPIC

Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: planeta9999 en 22 de Julio de 2017, 07:59:59

Título: Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 07:59:59
.

hola.

Me han encargado un proyecto en el que tengo que usar Ethernet, y concretamente UDP. No conocía los detalles de UDP, pensaba que Ethernet requería definir una IP única por dispositivo y establecer un diálogo de comunicaciones master-esclavo.

El cliente me aclara que no, ellos ya tenían un diseño con Raspberry, pero dependiente de terceros, y quieren hacer algo propio, disponiendo de todo para poder fabricar la placa por si mismos cuantas veces necesiten.

He buscado informacion por interntet y entiendo que UDP permite que un dispositivo envíe paquetes de datos, sin necesidad de establecer comunicación con otros dispositivos de la red, que es justo lo que quiere el cliente, mi placa captura unas señales de una máquina, las procesa y debe de envíar por UDP paquetes de 4096 bytes, 2 a 4 veces por segundo.

Por lo que he entendido, el dispositivo que envíe datos debe de hacerlo a una dirección IP 255.255.255.255 (broadcast), o con los tres primeros números comunes a los dispositivos de la red, y el último a 255, para que sea accesible a todos.

También me comenta el cliente que se establece un puerto de comunicación, entiendo que ambos dispositivos deben de usar el mismo puerto para que la cosa funcione.

Voy a usar un Kinetis MK64 para hacer el desarrollo, así puedo probarlo todo con Teensy usando todas las librerías disponibles, que son muchas, aunque eso me obligue a trabajar desde el entorno de Arduino. Además para Teensy no hay librerías que usen el Ethernet que lleva el propio micro, hay librerías para usar un controlador WS5500 controlador por SPI.


Tengo algunas dudas de hardware y de software:

1.- ¿ Conocéis algún software para PC o Raspberry que permita ver el tráfico de datos UDP ?.
2.- En tema hardware, tengo dudas sobre el conector RJ45 a usar, entiendo que debe de integrar el transformador adaptador dentro del conector, ¿ O es prescindible y se puede usar un conector RJ45 pelao, sin nada dentro ?. Tampoco tengo claro si vale cualquier RJ45 con transformador interno, o debe de tener alguna característica concreta para el controlador a usar, en mi caso un WS5500.


He mirado en los polacos, y el RJ45 con transformador interno, más barato que encuentro es este:
http://www.tme.eu/es/details/lmj2018811130dl1t4/conectores-rj/amphenol/

(http://www.todopic.com.ar/foros/imgtiny/2w2euq8.jpg)


Este es el controlador Ethernet WS5500 por SPI, que tendré que usar, a menos que consiga alguna librería para trabajar directamente con el Ethernet que integra el micro MK64.

(http://www.todopic.com.ar/foros/imgtiny/2ufavzc.jpg)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 22 de Julio de 2017, 11:22:02
El UDP, a diferencia de TCP, no es orientado a conexión, es decir que envía datos pero no requiere recibir el ACK de recepción.

Para manejar el ethernet necesitas una librería que debe de estar en las librerías proporcionadas por Kinetis, y para manejar el stack UDP puedes usar uIP o LwIP. Todas estas librerías y los ejemplos correspondientes los debe de incluir en los archivos que proporciona NXP. Yo he estado usando LwIP.

Además de las librerías, requiere el PHY, para este están los LAN8720 (el más económico esta a 1.09 EUR en Mouser), el DP83848 (1.90 EUR), KSZ8081 (1.09 EUR). Hay más pero de estos son los que por el momento me acuerdo.

Hay dos formas con lo que lo puedes conectar: MII, RMII. Te recomiendo la última, ya que usa menos líneas del Microcontrolador.

Respondiendo a tus preguntas.

1.- Wireshark (es multiplataforma)
2.- Tienen que llevar transformador, este puede ser externo o interno, los que los tienen interno se les conoce como MagJack.

Otro apunte con respecto a LwIP, este incluye, no sólo soporte para el stack TCP y UDP, sino qe también incluye aplicaciónes como HTTP, SNTP, SMTP, MQTT.

https://savannah.nongnu.org/projects/lwip/

Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: xocas en 22 de Julio de 2017, 11:50:04
1.- Wireshark, sin duda. La distro de Kali Linux para RPi lo incluye, pero no va bien, hay pérdida de paquetes y una dificultad considerable para hacerlo funcionar en modo monitor.

Tiene una curva de aprendizaje mayor que otros sniffers de red pero creo que merece la pena. Incluye protocolo MQTT entre sus filtros y algo he leído recientemente para su uso con módulos ESP8266.

Otras alternativas para Windows podrían ser:
Microsoft Message Analyzer
https://www.microsoft.com/en-in/download/details.aspx?id=44226

SmartSniff
http://www.nirsoft.net/utils/smsniff.html

Free Network Analyzer
https://freenetworkanalyzer.com/

Capsa Free Network Analyzer
http://www.colasoft.com/capsa-free/

un saludo
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 22 de Julio de 2017, 12:16:51
1.- Wireshark, sin duda. La distro de Kali Linux para RPi lo incluye, pero no va bien, hay pérdida de paquetes y una dificultad considerable para hacerlo funcionar en modo monitor.

El modo monitor es independiente de wireshark, debes de colocar en modo monitor la interfaz wlan, es ahí la dificultad, debido a que no todos los adaptadores lo soportan (bueno al menos era así hace unos años).

Para la interfaz ethernet se le llama modo promiscuo, y yo creo que esta sería la interfaz a usar.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 13:18:43
 

Gracias, tsk y xocas.
Me he bajado Wireshark, y se ve muy bien, creo que es justo lo que andaba buscando. También tengo por aquí el software Hercules, que entre otras cosas veo que también puede trabajar sobre UDP.

LwIP lo ví hace unos días en el directorio de ejemplos de Freescale. El problema es que parto de unos fuentes que están hechos para Teensy/Arduino. Teensy instala micros Kinetis, MK20, MKL26, MK64 y MK66, lo complicado es meter en el entorno de Arduino una librería nativa de NXP.

Arduino, todavía me resulta bastante enrevesado, sobre todo su sistema de numerar los puertos que no guarda ninguna relación con los puertos reales del datasheet. Por algún sitio en los cores de Arduino, supongo que andará el vínculo entre los puertos reales y la numeración de pines de Arduino, el día que tenga controlado ese aspecto me resultará más fácil integrar librerías o portar el proyecto a KDS.

El proyecto actual que tengo que desarrollar, parte de unos fuentes que hacen uso de DMA para capturar datos por SPI, es algo que todavía no domino, si no podría tratar de llevarme todo el proyecto a KDS y dejar de usar el IDE de Arduino.

Creo que voy a seguir haciendo las pruebas con Teensy 3.5 (Kinetis MK64) y el módulo Ethernet con el controlador W5500, este controlador es más caro que un transceptor para la parte física usando el Ethernet que integra el MK64, pero ahora mismo me ofrece una solución más cómoda para hacer el firmware.

El W5500 se controla por SPI, como los ENCJ, y tengo librería para Teensy. El hardware me lo complica un poco (muchas resistencias y condensadores alrededor del chip), pero como al cliente solo le tengo que dar los Gerber y el HEX del micro, para que él se fabrique las placas, no me importa mucho la cantidad de componentes que lleve la placa.


Lo que no tengo claro del todo es lo de las IP y el Broadcast en UDP, el cliente me comentó lo siguiente:
" Eso si, se ha de preparar la placa para poder configurar una IP y un puerto determinados a los que enviar, para evitar hacerlo a través de Broadcast y tener problemas en el futuro con un sitio donde haya más de una máquina configuradas. "

¿ quiere esto decir que no se envíen los paquetes a la dirección 255.255.255.255, ni a otra dirección de la misma red, acabada en 255, para que los paquetes no lleguen a todos los dispositivos conectados en la misma red ?. Esto es lo que he entendido que es el Broadcast en UDP, enviar paquetes de datos sin destinatario concreto, todos los nodos de la misma red los pueden leer.


Otro tema que tengo que resolver, en Teensy/Arduino, es poder utilizar dos puertos SPI al mismo tiempo. No puedo compartir los dos dispositivos en el mismo SPI, porque uno de ellos usa DMA, y en cuanto accediese al segundo dispositivo por SPI, el primero se desactivaría y el DMA dejaría de funcionar.

Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: KILLERJC en 22 de Julio de 2017, 13:36:18
El paquete UDP posee direccion IP y puerto ( origen y destino )

https://es.wikipedia.org/wiki/User_Datagram_Protocol

Citar
¿ quiere esto decir que no se envíen los paquetes a la dirección 255.255.255.255, ni a otra dirección de la misma red, acabada en 255, para que los paquetes no lleguen a todos los dispositivos conectados en la misma red ?. Esto es lo que he entendido que es el Broadcast en UDP, enviar paquetes de datos sin destinatario concreto, todos los nodos de la misma red los pueden leer.

Eso quiere decir que vas a tener que tener en cuenta la posibilidad de guardar una lista de IP y puertos, para luego enviarselo a cada uno.
Terminara siendo responsabilidad de la persona que configura el dispositivo si decide realizar un broadcast o no, y a quien enviarselo.

Suponete que haces tu lista.
- Si solo cargan 255.255.255.255 se hara un broadcast a la red local
- Si se carga una IP en especial 192.168.0.255 con netmask 255.255.255.0, deberia hacer un broadcast a esa subnet
- Si cargan varios IPs especificos, que solo se envien a esos IPs.

Creo que es la solución mas simple y mas amoldable a cualquier situacion.

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

El W5500 parece tener stack TCP/IP dentro, asi que lo veria mas como un ESP que un ENC28J60, este ultimo requiere el stack TCP/IP en el micro, solo oficia de MAC/PHY.

PD: Pienso de parte de la persona que lo pidio que seria ideal agregarle PoE, especialmente si posee un buen switch y una cantidad de computadoras dando vueltas.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 13:49:46
.

¿ En UDP también se pueden especificar varias IP de destino ?. el broadcast más o menos ya lo voy teniendo claro, también configurar una sola IP, no sabía que también se pueden configurar varias IP de destino.

Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: KILLERJC en 22 de Julio de 2017, 13:53:11
Vos vas a tener una IP propia seguramente automatica dada por DHCP, Luego a quien le vas a enviar el paquete es al IP que vos quieras, y como dijo tsk como no es un protocolo orientado a la conexion, es enviar, si llega o no, a nadie le importa. Ya que no tenes acuse de recibo.

El puerto de origen es opcional y podes usar 0 para omitirlo, recuerdo que una persona tuvo problemas con eso, pero al ponerle 0 se soluciono, o no recuerdo si era algo de TCP.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 13:55:37
.

Tengo este fuente de ejemplo para implementar UDP con Teensy (Kinetis) y el controlador W5500 por SPI. Veo que se asigna una MAC y una IP, entiendo que la IP será la del dispositivo de destino y que se podría reemplazar por 255.255.255.255 para que puedan leer esos paquetes de datos todos los dispositivos de la red. Aunque al final, el cliente quiere poder configurar la IP para dirigir los paquetes a un dispositivo concreto de la red.

La MAC ni idea de que utilidad tiene. Y el puerto entiendo que debe de ser el mismo en el dispositivo que envía los paquetes y en los que lo reciban.


Código: [Seleccionar]
/*
 UDPSendReceiveString:
 This sketch receives UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the sender
 A Processing sketch is included at the end of file that can be used to send
 and received messages for testing with a computer.
 created 21 Aug 2010
 by Michael Margolis
 This code is in the public domain.
 */


#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged";        // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i=0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}


/*
  Processing sketch to run with this example
 =====================================================
 // Processing UDP example to send and receive string data from Arduino
 // press any key to send the "Hello Arduino" message
 import hypermedia.net.*;
 UDP udp;  // define the UDP object
 void setup() {
 udp = new UDP( this, 6000 );  // create a new datagram connection on port 6000
 //udp.log( true ); // <-- printout the connection activity
 udp.listen( true );           // and wait for incoming message
 }
 void draw()
 {
 }
 void keyPressed() {
 String ip       = "192.168.1.177"; // the remote IP address
 int port        = 8888; // the destination port
 udp.send("Hello World", ip, port );   // the message to send
 }
 void receive( byte[] data ) { // <-- default handler
 //void receive( byte[] data, String ip, int port ) { // <-- extended handler
 for(int i=0; i < data.length; i++)
 print(char(data[i]));
 println();
 }
 */
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 14:03:31
Vos vas a tener una IP propia seguramente automatica dada por DHCP, Luego a quien le vas a enviar el paquete es al IP que vos quieras, y como dijo tsk como no es un protocolo orientado a la conexion, es enviar, si llega o no, a nadie le importa. Ya que no tenes acuse de recibo.

Vale, entiendo que puedo especificar una IP concreta como destino, o una IP 255.255.255.255 para que los paquetes lleguen a todos los dispositivos de la red.

Citar
El puerto de origen es opcional y podes usar 0 para omitirlo, recuerdo que una persona tuvo problemas con eso, pero al ponerle 0 se soluciono, o no recuerdo si era algo de TCP.

Lo probaré, aunque al final el cliente quiere poder configurar el puerto y la IP. Le dejaré que lo configure todo en un fichero de texto almacenado en tarjeta micro SD, y que él se lo pueda cambiar cuando quiera. Con que pueda configurar IP, puerto y cantidad de paquetes a enviar por segundo, ya le vale.

Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: KILLERJC en 22 de Julio de 2017, 14:33:19
En el ejemplo que pasaste, el IP es fijo. Es decir no es una asignacion automatica de IP como con DHCP. Si quiere elegir el IP, imagino que lo va a apagar, o piensa hacerlo mientras este activo la placa?.

El MAC es fijo de por si e identifica a cada modulo, cada modulo deberia tener su propio MAC, distinto de los otros en la Red, para que lo vayas pensando si es que tenes 2 o mas modulos en la misma red.

Respecto de enviar los datos UDP a otras IP, deberias hacer un for con esto:

Código: C
  1. // send a reply to the IP address and port that sent us the packet we received
  2.     Udp.beginPacket("ACA_IP", "ACA_PUERTO");
  3.     Udp.write("ACA_DATOS");
  4.     Udp.endPacket();

Y respecto a enviarlo seria algo asi, como siempre:

Código: C
  1. typedef struct IPList
  2. {
  3.   IPAddress ip;
  4.   unsigned int port;
  5. } IPList;
  6.  
  7. uint8_t Data[4096] = {0};
  8.  
  9. // Este parametro va a ser variable, y va a indicar la cantidad de IP que hay
  10. // Lo vas a actualizar cuando lo leas desde una EEPROM/FLASH/SD
  11. unsigned int IPAmount = 3;
  12.  
  13. // Este va a tener un maximo definido por vos, es decir cuantas IPs se puede configurar aca
  14. // Inicialmente no vas a tener nada y lo vas a recuperar deste tu EEPROM/FLASH/SD
  15. IPList IPArray[10] = {
  16.     {{192,168,1,10},8888},
  17.     {{192,168,1,20},8888},
  18.     {{192,168,1,25},8888}
  19. };
  20.  
  21.  
  22. // En tu while
  23. for(unsigned int i=0;i<IPAmount;i++)
  24. {
  25.   Udp.beginPacket(IPArray.ip, IPArray.port);
  26.   Udp.write(Data);
  27.   Udp.endPacket();
  28. }
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 22 de Julio de 2017, 14:55:29
De hecho LwIP no es parte de NXP, es totalmente independiente de la plataforma, por lo que podrías usarlo con arduino, y sólo crear el driver correspondiente usando las librerías propias del Arduino.

http://lwip.wikia.com/wiki/Writing_a_device_driver

https://github.com/matwey/lwip-enc28j60 (un ejemplo aunque viejo puedes ver que es lo que tuvieron que hacer)

La dirección MAC is una dirección única que representa al adaptador de Red (NIC), de esta no puede haber duplicados en tu red. Esta puede ser manejada de forma local o universal. En la local tu le asignas la dirección siguiendo ciertos patrones, y en la Universal compras los rangos de direcciones.

Si quieres obtener una dirección MAC valida, existen unas memorias eeprom que salen bastante económicas que contienen una dirección MAC, uno de ellos es el 25aa02e48 y se conecta por SPI, con esta memoria tienes el espacio suficiente para almacenar la IP, el puerto y algunas otras configuraciones.

También te recomiendo que le des un vistazo al proyecto de tu cliente, tal vez existan mejores y más robustas formas de resolver su proyecto. Por ejemplo existe CoAP(UDP) y MQTT(TCP). Estos son protocolos enfocados a la comunicacion Máquina a Máquina, por lo que podrías implementar sistemas más complejos que el que podrías al usar sólamente UDP. A mi me gusta usar más MQTT, pero es sólo cuestion de gustos.

http://coap.technology/
http://mqtt.org/
https://eclipse.org/community/eclipse_newsletter/2014/february/article2.php
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 22 de Julio de 2017, 16:45:00
La dirección MAC is una dirección única que representa al adaptador de Red (NIC), de esta no puede haber duplicados en tu red. Esta puede ser manejada de forma local o universal. En la local tu le asignas la dirección siguiendo ciertos patrones, y en la Universal compras los rangos de direcciones.

Si quieres obtener una dirección MAC valida, existen unas memorias eeprom que salen bastante económicas que contienen una dirección MAC, uno de ellos es el 25aa02e48 y se conecta por SPI, con esta memoria tienes el espacio suficiente para almacenar la IP, el puerto y algunas otras configuraciones.

La pondré configurable, y que el cliente ponga la que quiera, igual que la IP y el puerto.

Citar
También te recomiendo que le des un vistazo al proyecto de tu cliente, tal vez existan mejores y más robustas formas de resolver su proyecto. Por ejemplo existe CoAP(UDP) y MQTT(TCP). Estos son protocolos enfocados a la comunicacion Máquina a Máquina, por lo que podrías implementar sistemas más complejos que el que podrías al usar sólamente UDP. A mi me gusta usar más MQTT, pero es sólo cuestion de gustos.

http://coap.technology/
http://mqtt.org/
https://eclipse.org/community/eclipse_newsletter/2014/february/article2.php


Para este caso, no puedo cambiarlo, porque el cliente ya tiene hecha la aplicación que recibe los datos y va por UDP. Si se lo doy todo configurable, no tendrá problemas.

Ahora voy a probar lo del UDP, compilando el sketch de Teensy y lo comprobaré conectando mi placa al PC por Ethernet para visualizar los paquetes de datos que se reciban. Si eso me va bien, ya integro mi aplicación, que recibe datos de una máquina, con las comunicaciones UDP, para enviar esos datos en paquetes de 4096 bytes, 2-4 veces por segundo, y proyecto acabado.

Si tengo suerte, este mes de Agosto, quiero terminar este proyecto y otro que tengo pendiente desde hace bastante tiempo, y a cobrar. Con parte de lo que ingrese, ya me gustaría plantearme comprar la máquina de Pick and Place, para poder encarar nuevos proyectos de cosecha propia. Tengo unos cuantos diseños de placas que instalan decenas y centenares de leds digitales APA102, y solo los puedo echar adelante subcontratando el ensamblaje o teniendo mi propia máquina de Pick and Place, prefiero lo segundo porque no me gusta depender de nadie.


Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 13:45:37
 

Ya puse en marcha mi placa con UDP, también instalé Wireshark.

He compilado mi aplicativo sobre un Kinetis MK64 que controla por SPI un módulo Ethernet W5500. La librería para UDP es la que usan los Teeensy con Arduino.

En mi placa he cometido un pequeño error, aunque eso no debería impedir que funcione, he conectado al revés uno de los dos led testigos del conector RJ45.

De momento no veo el tráfico en el Wireshark, no se si requiere alguna configuración especial, simplemente en la ventana principal he tecleado udp para filtrar.

Como no tenía claro si mi placa estaba funcionando, simplemente le he hecho un ping desde linea de comandos de mi PC a la IP que le conf¡guré, la 192.168.1.177 y responde, luego la he cambiado a la 192.168.1.189, y también responde. No hay respuesta si tecleo otras IPs, osea que el módulo Ethernet W5500 ha sido configurado desde el Kinetis por SPI y parece funcionar.

También entré al modem router para abrir el puerto 8888, que es el que tengo configurado en el aplicativo que rueda en el Kinetis. En el programa he configurado que se envíe el paquete UDP a la dirección 192.168.1.255, por lo del broadcast, aunque también lo probé con la dirección IP local de mi PC, la 192.168.1.3.

Ahora mismo no se si tengo algo mal en la configuración UDP de mi programa o es que no estoy configurando bien Wireshark. Una cosa rara, si conecto mi placa directo al PC con el cable Ethernet, el ping no responde, pero si conecto la placa a través del modem router si que responde.


Este es el fuente del programita que estoy rodando en el Kinetis:

Código: [Seleccionar]
//******************************************************************************
//******************************************************************************
//******** Programa TEST UDP Kinetis MK64 **************************************
//******************************************************************************
//******************************************************************************

#include <SPI.h>       
#include <Ethernet2.h>
#include <EthernetUdp2.h>
#include "Watchdog.h" // Watchdog, añadido

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 1, 189); // La IP de esta placa
IPAddress IP_Remote(192, 168, 1, 255); // IP para Broadcast
unsigned int localPort = 8888;      // local port to listen on

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

// Patilla Chip Select en 6 (PTD4)
  #define W5500_CS  6

//*** Leds DEBUG y test actividad **
    int Led1 =  37; // PTC10, DEBUG
    int Led2 =  38; // PTC11, DEBUG
    int state = 0; // Variable para parpadear LED (toggle)
   

//**********************************************************
//**********************************************************
//********** Configuracion inicial  ************************
//**********************************************************
//**********************************************************
void setup() {

// Inicializa pines PTC10 y PTC11, para leds rojo y verde en placa
  pinMode(Led1, OUTPUT); // pin37 de Arduino/Teensy, LED ROJO en PTC10
  pinMode(Led2, OUTPUT); // pin38 de Arduino/Teensy, LED VERDE en PTC11
 
// Configuro pines alternativos SPI
  SPI.setMOSI(7);
  SPI.setMISO(8);
  SPI.setSCK(14);
  Ethernet.init(W5500_CS); //Configuro el chip select alternativo en pin6 (PTD4) 
 
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

//**********************************************************
//**********************************************************
//********** Bucle Principal  ******************************
//**********************************************************
//**********************************************************
void loop() {

// Añado control de Watchdog
   kickWatchdog();
     
// DEBUG Parpadeo LED en PC11, led verde en placa
   state++;
   if (state==1) digitalWriteFast(Led2, HIGH);     
   if (state==15) {digitalWriteFast(Led2, LOW);}
   if (state== 30) state=0; 

// DEBUG, envia un paquete UDP, puerto 8888
//  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.beginPacket(IP_Remote, localPort);
  Udp.write("hello");
  Udp.endPacket();
   
  delay(10);
}

Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 19 de Septiembre de 2017, 14:45:21
Que librería estas usando, porque vi una en la que a Udp.write se le indica el tamaño del paquete

Código: C
  1. Udp.write(packetBuffer, NTP_PACKET_SIZE);

Con respecto al Wireshark ¿Ves otro tipo de tráfico en el wireshark?, sino quiere decir que elegiste la interfaz de captura incorrecta y lo que tienes que ver es si tu PC esta conectada por RJ45 o Wifi y seleccionar la interfaz de acuerdo a la que tenga conexión.

Si vés otro tráfico como HTTP/HTTPS/MDNS/DNS/UDP podría ser que el firewall del tu PC esté bloqueando la entrada de ciertos paquetes en ciertos puertos que le son desconocidos para el.

Puedes probar con el siguiente script.

Código: Python
  1. import SocketServer
  2.  
  3. class MyUDPHandler(SocketServer.BaseRequestHandler):
  4.     """
  5.    This class works similar to the TCP handler class, except that
  6.    self.request consists of a pair of data and client socket, and since
  7.    there is no connection the client address must be given explicitly
  8.    when sending data back via sendto().
  9.    """
  10.  
  11.     def handle(self):
  12.         data = self.request[0].strip()
  13.         socket = self.request[1]
  14.         print "{} wrote:".format(self.client_address[0])
  15.         print data
  16.         #socket.sendto(data.upper(), self.client_address)
  17.  
  18. if __name__ == "__main__":
  19.     HOST, PORT = "0.0.0.0", 8888
  20.     server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
  21.     server.serve_forever()

Si ves aquí lo que estas enviando desde la tarjeta entonces es algo con la configuración de Wireshark, si no lo ves, entonces hay dos opciones:

1.- Firewall de tu PC
2.- Problema con la placa

Pero mencionas que tu placa responde así que podría ser algo con el firewall, por lo que el primer paso que seguiría sería desactivarlo para descartar que sea esto.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 15:33:11
 

Si, al final era el cortafuegos, lo he desactivado y los paquetes UDP han entrado como un tiro. Que maravilla, me temía lo peor, un error de diseño de mi placa, y el cliente está que echa chispas porque le envíe mañana mismo la placa.

Por cierto el broadcast con la 255.255.255.255 funciona de fábula, luego probaré con la 192.168.1.255 a ver si también funciona, y finalmente con la IP local de mi PC, la 192.168.1.3.

También he tenido y sigo teniendo problemas con el bootloader de uTastker, con este me pasa una cosa muy rara, no me carga firmware sin son archivos pequeños, probado con ficheros de 10K hasta 24K, sin embargo me los carga sin problemas para tamaños mayores, probado con uno de 67K. Creo que es algún parámetro de la encriptación, ya le he preguntado al autor en los foros de NXP a ver si me echa un cable.

De momento mañana mismo le envío al cliente la placa con el bootloader cargado, y por email ya le enviaré el firmware. Si no consigo que cargue ficheros pequeños, tendré que engordar artificialmente el tamaño del firmware. ¿ Se os ocurre como hacerlo ?, en principio puse una matriz gorda para que se almacene en Flash, pero se ve que la optimización de GCC no se deja engañar y me deja el objeto igual de tamaño.


(https://i.imgur.com/Eu6g4Wr.jpg)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 15:47:12


Lo que no se ahora mismo es como configurar el puñetero cortafuegos, para que me deje pasar el tráfico sin necesidad de desactivarlo, por cuestiones de seguridad.


(https://i.imgur.com/l5SeC5U.jpg)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 16:01:53

Ya está, arreglado, configuré, en el cortafuegos, una regla para permitir el tráfico entrante desde 192.168.1.189, y ya va perfecto sin desactivar el cortafuegos.

Lo que no veo es que se me encienda ninguno de los dos led de actividad del RJ45, uno ya detecté según el datasheet, que lo he conectado al revés, y el otro no se porque no da señales de vida. Es un mal menor, que no impide que funcione, pero queda bonito que parpadeen los leds de actividad, seguramente el otro también estará al revés.



(https://i.imgur.com/cO98ZUX.jpg)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 19:02:34
 

He seguido con las pruebas y hay algo que no se como interpretarlo.

Modifico el fuente para que envíe por UDP una matriz char con 4096 carácteres, ejecuto WireShark y me recibe el envío en dos trozos, uno de 1514 bytes y el otro de 618 bytes.

No me salen las cuentas, aunque los paquetes UDP salgan troceados, me faltan bytes, no se si hay alguna limitación en el tamaño de los paquetes a enviar, envío 4096 bytes y recibo solo 2132 bytes en dos trozos (1514+618).

Buscando por Google, me encuentro con esta parrafada sobre UDP y el tamaño de los paquetes, entiendo que hay que enviar paquetes de un máximo de 1472 bytes de datos, pero no entiendo porque estoy recibiendo dos trozos de datos, cuya suma supera los 1472 bytes pero no llega a los 4096 bytes enviados:

" El campo de longitud se refiere a la longitud total, en bytes, de la cabecera y los datos. La aplicación que utiliza UDP, debe controlar el tamaño del paquete UDP (la cantidad de bytes enviados en un mismo paquete UDP) si quiere evitar que el nivel IP fragmente el paquete UDP porque se ha excedido el MTU (Maximum Transmission Unit) del medio físico. Por ejemplo, si el medio físico es una Ethernet con tramas Ethernet II, el campo de datos de la trama Ethernet tiene una longitud máxima de 1500 bytes. En este caso, la longitud máxima del datagrama IP encapsulado en una trama Ethernet sera de 1500 bytes. Si utilizamos UDP como protocolo de transporte, la cantidad de bytes de usuario (campo data del datagrama UDP) será como máximo 1500−20−8=1472  bytes (a 1500 se le resta la cabecera IP, usualmente 20 bytes, y la cabecera UDP, 8 bytes) "



(https://i.imgur.com/PgLqTiH.jpg)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: KILLERJC en 19 de Septiembre de 2017, 19:21:32
Citar
envío 4096 bytes y recibo solo 2132 bytes en dos trozos (1514+618).

En realidad lo que te dice ese parrafo extra largo, es que tu dato esta "encapsulado",
Es decir que a tu dato se le agrega (una cabecera) la informacion de IP https://es.wikipedia.org/wiki/Cabecera_IP,
Luego a tu dato + cabecera IP, se lo vuelve a encapsular nuevamente y se le agrega lo referente a UDP https://es.wikipedia.org/wiki/User_Datagram_Protocol.

Por lo tanto los datos a enviar maximo en 1 solo paquete es de 1472 bytes. Que si observas en la imagen del wireshark, dice Len = 1472. Tambien podes ver la imagen donde te desglosa cada uno de los paquetes, y dice Data ( 1472 bytes )

De alli es como lo maneje el stack UDP/IP en tu micro, si decide enviar 3 completos y luego 1 lo que sobra, lo va a hacer. Pero parece que decide ir por numeros que son multiplos de 2,
Si sumas ambos lenght tenes que 1472 + 576 = 2048

El tema esta en los otros 2048 bytes que faltan, o tal ves en el wireshark no lo mostraste, o tal ves nunca se envio.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 19 de Septiembre de 2017, 20:05:08
Abre cualquiera de los paquetes con doble click.

Ahí verás que el tamaño del del dato recibido va a ser de 4096bytes. El mismo protocolo lo reensambla, y probablemente wireshark sólo reporta el último de los paquetes recibidos.

Esto es debido que existe un tamaño máximo de paquete que se conoce como Unidad Máxima de Transmisión o MTU, por lo general este valor está en 1500bytes pero de esos 1500 bytes 20 son para el encabezado. Por lo tanto te quedan 1480 bytes de carga últil o datos.

Si abres uno de los paquetes debes de observar varios campos:

Frame
Ethernet
Internet Protocol Version 4
User Datagram Protocol
Data

Data debe de ser del tamaño de los 4096 bytes y dentro de Internet Protocol
Hay una sección que te indica cuantos paquetes fueron enviados y el tamaño de la carga útil.

(https://i.imgur.com/vLOcQ0j.png)

Aunque yo me quedaría por debajo del MTU para evitar problemas. Por ejemplo el script de python que uso para probar UDP, no puede manejar este tipo de paquetes, solo bajo por ejemplo a que tenga una carga útil de 1400 bytes trabaja de maravilla. Para esto le vería dos opciones, buscar como manejar este tamaño de paquete en el servidor, o comprimir los datos. Si ya tienes un programa servidor que soporta re ensamblar este tipo de paquetes entonces ya lo tienes listo.
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 19 de Septiembre de 2017, 20:27:47

Vale, gracias a ambos por los comentarios.
Voy a probar a partir los datos a enviar en paquetes de 1024 bytes, así cada matriz la troceo en cuatro pedazos y los envío uno tras otro en un bucle. Miraré en Wireshark, que esta vez se reciban todos los bytes.

Lo que me voy a encontrar en la versión final del programa que tengo que hacer es eso. El programa recibe unas animaciones que son frames de 4096 bytes cada uno, cada byte es un dígito de texto que va desde 0 hasta la F, todo eso se carga en una matriz, que cuando esta llena la tengo que enviar por UDP, y así constantemente en bucle.

Voy a mirar las funciones de manejo de cadenas en C, que es algo que lo tengo medio oxidado. La idea es trocear la matriz de 4096 bytes en cuatro trozos, enviarlos uno a uno, esperar 500 milisegundos y vuelta a empezar con la siguiente imagen recibida en la matriz. El cliente quiere una cadencia de envío de 2 imágenes por segundo, y poder configurar desde fuera (se lo pondré en un archivo de texto en SD) la IP de destino, el puerto y la velocidad de transmisión (imágenes por segundo).
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: tsk en 19 de Septiembre de 2017, 20:58:55
Para observarlo coloca como filtro

ip.src==192.168.1.189

Vas a ver algo como esto

(https://i.imgur.com/OXCYZEoh.png)
Título: Re:Ethernet - UDP, RJ45 con Kinetis
Publicado por: planeta9999 en 25 de Septiembre de 2017, 04:31:18
 

Ya lo tengo todo funcionando y va de fábula. Un kinetis MK64 enviando paquetes de 1025 bytes por UDP, el cliente me pidió añadir un byte a cada paquete para identificar el orden de los paquetes, del 1 al 4, cada cuatro paquetes es una imagen.

Hubo un poco de lío con si se envían los datos como campos "char" o "int", en principio enviaba una matriz de campos "char", pero parece que de esa manera los dígitos 0, 1, 2 y 3 no se reciben como el quiere, le van bien si los muevo desde un campo "int".

Supongo que un "0" desde un campo char envía el ASCII 48 del dígito "0", y enviar un 0 numérico envía el ASCII 0, o será al revés, menuda gaita con los char y los int. El caso es que si se lo envío todo desde campos "int" lo recibe bien.

El bootloader uTasker encriptado, funciona perfecto, después de resolver un pequeño problema con los parámetros de encriptación. El Viernes pasado ya envié unas cuantas modificaciones, colgando los archivos de MEGA y pasándole al cliente los enlaces de descarga por Whatsapp. Todo genial, si tengo un rato me gustaría configurar uTasker para los STM32, porque voy a usar un STM32F405 en el proyecto de la ruleta y me vendrá muy bien para poder dar también actualizaciones a distancia.

El chip W5500, fenomenal para gestionar comunicaciones Ethernet por SPI desde un micro.