eCos Synthetic Target with Ethernet

One of the convenient features of the eCos real time operating system is the ability to develop and test code on your Linux development PC without downloading to target hardware. This can be done using hardware emulation (via QEMU or VMWare) or just using the built in “Synthetic Target” support. I have documented here the various steps required to install and configure the Synthetic Target on Linux (Ubuntu). As well as supporting basic eCos threading you can even run networking applications in this environment via the bundled synthetic Ethernet driver.

Getting the sources from CVS

Everything you need to build and run synthetic eCos applications is provided in the sources available from the eCos public CVS repository. This contains the kernel sources, as well as the sources used to build the host tools, e.g. ecosoconfig (used for kernel configuration) and rawether (used for handling Ethernet support within the synthetic target environment). To checkout all of these sources from CVS into a local directory /opt/cvs use the following (press enter when prompted for password):

cd /opt
cvs -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos login
cvs -z3 -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos

You should now have the full set of eCos sources in directory /opt/ecos.

Building the host tools

You must have GCC and Tcl/Tlk installed in order to build the host tools. With these in place you build the tools directly from the CVS sources as follows:

mkdir /home/kelvin/hostbuild
cd /home/kelvin/hostbuild
/opt/ecos/configure --prefix=/usr/local –with-tcl=/usr/local
make
sudo make install

You should now have some host tools (e.g. ecosconfig) in /usr/local/bin and some supporting tools (e.g. rawether) in the /usr/local/libexec/ecos folder hierarchy.

Note that there are two configure scripts included in the eCos CVS sources; one to build the kernel configuration tools only, and one for the full set of host tools including rawether. If you previously followed instructions for building only the kernel configuration tools but would also like Ethernet support, then you will need to build again using the top-level configure script as described here.

Building the Kernel

Before compiling your eCos application code, you must first configure and build the eCos kernel. This creates a library which you can then link with your application.

The kernel configuration and build does not occur within the CVS tree, but rather in a separate folder, which might be considered a workspace in which your particular kernel configuration resides. You can have as many kernel build folders as you wish, in order to maintain different concurrent kernel configurations.

You must first point the ECOS_REPOSITORY environment variable to your eCos source tree location. You don’t work in there, but you need to tell ecosconfig where to find it. It will create a copy of the relevant bits of the original source tree for any projects you create:

ECOS_REPOSITORY=/opt/ecos/packages && export ECOS_REPOSITORY

Now make a working directory in which your kernel will be built. You can then enter the directory and start configuring your first kernel:

mkdir /home/kelvin/kernel-net
cd /home/kelvin/kernel-net
ecosconfig new linux
ecosconfig add fileio net freebsd_net eth_drivers
ecosconfig tree

ecosconfig new linux creates a new kernel configuration using the Linux Synthetic Target as the target platform. ecosconfig add adds particular packages to your kernel configuration. Before any of these packages are added you have a barebones kernel configuration. This ensures that eCos kernels start small and do not include extraneous libraries which would bloat your embedded application. You will usually want to extend the kernel to include support for a few packages, however, such as an IP stack, perhaps an HTTP server etc. In this example I have added support for the standard file interface, the Ethernet drivers, and an IP stack. There are three IP stacks available within the eCos sources but the FreeBSD-derived stack is currently the best-maintained and most fully-featured stack if you do not have strict resource limitations (for which the LWIP stack would be more appropriate). Finally ecosconfig tree creates the build tree, creating a set of header files within your working directory correctly configured according to your package requirements.

You will see that the /home/kelvin/kernel-net working directory now contains a file ecos.ecc. This is a text-based configuration file which stores your package requirements and allows you to tweak a large number of kernel options. There is a graphical configuration tool configtool for configuring the various configuration options, but if you prefer not to use a GUI or are working from a bash shell, you can get by using ecosconfig and a text editor to edit the options as I describe here.

The first thing to configure in the ecos.ecc file is the IP address that the eCos application should use. You can use DHCP, but this would require a DHCP server to be listening on the virtual Ethernet port created by the Synthetic target. For simplicity you may prefer to just set a static IP address for the target application. This can be done by editing the ecos.ecc file with a text editor. Find the lines containing the following configuration options, and uncomment (remove the hash symbol) the “user_value” line, then modify the line with your chosen options:

CYGHWR_NET_DRIVER_ETH0_BOOTP = 0
CYGHWR_NET_DRIVER_ETH0_DHCP = 0
CYGHWR_NET_DRIVER_ETH0_ADDRS = 1
CYGHWR_NET_DRIVER_ETH0_ADDRS_IP = 10.0.0.1
CYGHWR_NET_DRIVER_ETH0_ADDRS_BROADCAST = 10.0.0.255
CYGHWR_NET_DRIVER_ETH0_ADDRS_GATEWAY = 10.0.0.100
CYGHWR_NET_DRIVER_ETH0_ADDRS_SERVER = 10.0.0.101

This configures the eCos target application to use the private-range IP address 10.0.0.1. The SERVER field is not used on a static IP system, but it has been filled in here with something sensible anyway.

Note that it is necessary to alter the compiler flags on some Linux distributions (including recent versions of Ubuntu). If you get a segmentation fault when running the final application then you should try the following change in the ecos.ecc file; Edit the CYGBLD_GLOBAL_CFLAGS and uncomment the user_value line. On the same line you should remove “-finit-priority” and add “-fno-stack-protector”.

With all of these changes made, you can now build the kernel:

ecosconfig tree
make

Once complete you should find that the eCos kernel library has been created for you in /home/kelvin/kernel-net/install/lib. You can now move on to building some application code which will link with this library.

Building the Sample Applications

A set of very simple example applications are provided in the eCos sources. Check your environment is now fully configured by copying these into a local working directory and running make:

mkdir /home/kelvin/examples
cd /home/kelvin/examples
cp /opt/ecos/examples/* .
make INSTALL_DIR=/home/kelvin/kernel-net/install

Note that you need to pass the location of your kernel working directory to the Makefile.

This builds the application sources and links them with your kernel library to create a few executables which you can now run directly. For example you should now be able to run the hello application, a classic Hello World:

./hello

If you see “Hello, eCos world!” then the Synthetic target environment is now working, albeit without networking at this stage.

You may find that these applications fail to run due to the following Tcl/Tk error:

application-specific initialization failed: Can't find a usable init.tcl in the following directories:
    {} /usr/local/libexec/ecos/hal/synth/arch/share/tcl8.4 /usr/local/libexec/ecos/hal/synth/share/tcl8.4 /usr/local/libexec/ecos/hal/synth/arch/library /usr/local/libexec/ecos/hal/synth/library /usr/local/libexec/ecos/hal/synth/tcl8.4.1/library /usr/local/libexec/ecos/hal/tcl8.4.1/library

If you see this error then you will need to provide soft-links to guide the Synthetic applications to init.tcl and tk.tcl within your Tcl/Tk installation e.g.:

sudo mkdir -p /usr/local/libexec/ecos/hal/synth/share
sudo ln -s /usr/local/share/tcl8.4 /usr/local/libexec/ecos/hal/synth/share/tcl8.4
sudo ln -s /usr/local/share/tk8.4 /usr/local/libexec/ecos/hal/synth/share/tk8.4

With the sample applications confirmed as working, you can now move on to building an application with networking support.

Building a Networked Application

There are various bundled networking applications such as HTTP servers, but this example will simply build an application that boots and responds to ICMP echo requests (pings). Open the existing sample application hello.c in a text editor, and change it to the following:

/* this is a simple hello world program */
#include "stdio.h"
#include "network.h"
#include "cyg/kernel/kapi.h"

int main(void)
{
  init_all_network_interfaces();
  printf("Hello, eCos world!\n");
  while (1) {
    printf ("Sleeping\n");
    cyg_thread_delay (200);
  }
  return 0;
}

The main difference with the original is that a call to init_all_network_interfaces() has been added. As the name suggests this function will initialise the Ethernet interface and IP stack using the IP address settings you made in the kernel configuration earlier. This is essentially all that is needed to start the IP stack up in your application. The other change to the original code is the addition of a while loop to keep the application open so that you can experiment with pinging the Synthetic target.

Now recompile the new hello.c:

make INSTALL_DIR=/home/kelvin/kernel-net/install

You should now be able to run the new application, this time enabling the IO option for Ethernet support:

./hello -io -t /usr/local/libexec/ecos/devs/eth/synth/ecosynth/current/ethernet.tdf

Note that this uses the default TDF (Target Definition File) supplied with the host tools, which should be adequate for most needs. The default version translates eCos ethernet device “eth0” to a virtual Ethertap device on the host system “tap3”. A suitable MAC address for “tap3” is provided in the TDF. If you wish to write your own TDF to tweak the configuration, you can follow the instructions here. In the same instructions you will also find details on using a spare real Ethernet device in your development PC rather than using an Ethertap virtual device.

Assuming the Synthetic application started successfully you should now have a Tcl/Tk GUI window showing the debug statements printed by the application, as well as some debug showing the the first few bytes of any Ethernet traffic. The Synthetic environment should now have dynamically created the “tap3” device, and the eCos application end will be configured to use IP address 10.0.0.1. You are now ready to test IP communications with the target.

Open another shell, and set the IP address for the PC side of the virtual Ethernet link to 10.0.0.2:

sudo ifconfig tap3 10.0.0.2

All being well, it should now be possible to ping the running eCos application from the second shell window (i.e. from the PC 10.0.0.2 to the eCos application 10.0.0.1). Make sure that your firewall is configured to allow packets through on this interface and for these addresses.

ping 10.0.0.1

As well as the ping responses showing on the second shell terminal, you should see details of the ICMP echo packets being printed in the eCos application GUI window. This GUI is useful for tracking down any issues with the networking, as you can ascertain whether your ICMP echo requests are actually reaching the target application based on whether they appear in the GUI.

Note that if you wish to run a Synthetic environment where you do not have a display available (e.g. from a remote machine via Telnet/SSH) then you can add the “-nw” parameter when running the application. If you do not do this then you will be presented with the following error:

application-specific initialization failed: no display name and no $DISPLAY environment variable

Note that when using the default TDF configuration as described here, the “tap3” device is created for the duration of the eCos application execution only. Once you close the application the “tap3” device will disappear, and you will need to run ifconfig again to set the IP address when you instantiate the application next time. There are of course distro-specific means of automatically setting the IP address when the device appears. For alternative modes of operation consult the eCos manual.

This should leave you with an environment from which you can start to build more advanced applications. You may find it interesting to browse the bundled packages list via ecosconfig or the configtool. There you will find ready-rolled packages for HTTP servers, FTP clients etc. For anything which is not already available in the sources, you can use the example hello.c above as a basic template which you can extend to add support for any networked applications. eCos supports the BSD sockets API (and the main stack is actually a port of the FreeBSD stack itself) so porting sockets-based applications from other environments is simple.

Bookmark and Share This Article
[del.icio.us] [Digg] [Google] [Reddit] [Slashdot] [StumbleUpon] [Technorati] [Twitter] [Yahoo!] [Email]
This entry was posted in HowTo and tagged , , , , , , , , . Bookmark the permalink.

One Response to eCos Synthetic Target with Ethernet

  1. C says:

    Very cool. This is a perfect intro to getting started programming in eCos. Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *