Inspirel banner

YAMI4 on Intel Galileo

Intel Galileo

Intel Galileo is a prototyping board based on the Intel CPU and designed in line with the Arduino Certified program.

The Intel Galileo board is intended to be software compatible with the Arduino environment, which allows to reuse software prepared for the Arduino platform. We already know that YAMI4 works on Arduino Uno, and we have tested it on Galileo, too.

In other words, you can rely on all the tips and guidance that was prepared for the Uno board. The programming environment that is used for Galileo is specially prepared and should be downloaded from the Intel website. Apart from that, all rules are the same - in particular, the YAMI4 library can be installed in the same way as for the Arduino Uno board.

UDP Galileo bug workarounds

Unfortunately, the Intel Galileo software has a bug in its networking routines and is unable to properly detect the address and port of the UDP remote client. In other words, when some program sends the UDP packet to Galileo, its origins are not properly discovered - instead, the client address is always reported as 255.255.255.255 and the port number is always 0. This is not a problem for one-way communication, where the client only sends packets to Galileo, but might be a problem with request-response senarios, where the Galileo is expected to send back some response - without proper origin information the software running on the board might not be able to properly send back the response. This bug was already spotted by other users and was discussed on Galileo support forums and according to the Intel's release notes, this bug was confirmed, but fixed for the Edison board only.

There are several possible workarounds for this. One of them assumes that the sketch knows its client address and port and does not have to rely on discovery of every packet's origin. This way, Galileo can simply send the response back to the address and port that is known up-front and the client can receive it.

The YAMI4 library examples (that is, YAMI4AnalogRead and YAMI4Calculator, because only these two require two-way communication) can be modified by forcing the returning address and port when the reply is sent back. The original code of both examples contains the call function:

// this function will receive all YAMI4 messages:
void call(IPAddress remoteIp, uint16_t remotePort,
    enum yami_message_type message_type,
    const char object_name[], const char message_name[], const char exception_msg[],
    int64_t message_id,
    const uint8_t body[], size_t body_size)
{
  // server-side code as before
  // ...

  res = agent.sendReply(remoteIp, remotePort, message_id, reply_body, reply_body_size);

  // ...
}

The remoteIp and remotePort variables come as parameters to the call function and normally contain proper values for client's address and port - but with the current bug in the Galileo software, these values are not valid and should be ignored; instead, proper client address and port should be set up explicitly:

  IPAddress clientRemoteIp(192, 168, 1, 10);
  uint16_t clientRemotePort = 12346;
  res = agent.sendReply(clientRemoteIp, clientRemotePort, message_id, reply_body, reply_body_size);

Above, clientRemoteIp and clientRemotePort are set to hard-coded example values that assume a client running on the 192.168.1.10 computer and using 12346 UDP listener port - set the IP address appropriately for your networking configuration.

The client program also needs some minor workaround for this method - normally YAMI4 clients do not use fixed port numbers and use system-assigned ports for each created communication channel. By setting up a listener with appropriate address (here, the "udp://192.168.1.10:12346" string will do the trick) before sending the message, the client will be able to receive response sent back by the server running on the Galileo board. Note that the client-side listener should be created before any message is sent to the Galileo board.

Another workaround strategy might involve sending the client address and port as part of the message. Normally this is redundant, as this information is already sent as part of the UDP packet, but the bug prevents Galileo from using it. By embedding address and port values in the message, the client allows the server to read them and use when sending back the response. The advantage of this method is that the client origin can be different with each message - in particular, it allows many distinct clients to communicate with a single program running on the board. Use the method that is appropriate for your particular system.

Memory tuning

The Intel Galileo board has lots of memory and there is no need to tune the library with memory constraints in mind. The tuning constants are defined in the YAMI4.h header file:

/* max size of output message payload */
#define MAX_OUTGOING_MESSAGE_PAYLOAD 250u

/* max size of input message payload */
#define MAX_INCOMING_MESSAGE_PAYLOAD 250u

It is possible to handle much bigger messages than this, so you might want to change these values. Note, however, that since this variant of the YAMI4 library uses only UDP communication, the packets will never be bigger than the maximum size of the UDP packet anyway - for this reason the optimal value will be something around 512 bytes for both incoming and outgoing buffers.

Note that it might be necessary to completely reinstall the YAMI4 library after modifying these values as the Arduino IDE tends to reuse the already compiled library files.

Stay tuned for descriptions on how to use YAMI4 on other single board devices.