wiki:TBR/UserManual/PPPD_on_SIS

Version 1 (modified by Tiemens, on Apr 26, 2010 at 5:30:49 PM) (diff)

Created page with 'This page is intended for anyone who wants to use ethernet (tcp/ip) on the ERC32 Sparc Instruction Simulator (SIS). After reading this page, you should be able to create an image…'

PPPD on SIS

This page is intended for anyone who wants to use ethernet (tcp/ip) on the ERC32 Sparc Instruction Simulator (SIS). After reading this page, you should be able to create an image which you can run in the SIS and can ping to from your host PC (the PC running SIS).

Prerequisites

In order to be able to follow this howto, you need the following:

  • A version of RTEMS which includes this console driver for the ERC32 target.
  • The SIS with this patch. At the time of writing this the patch has just been submitted to GDB. If you check out GDB head, apply the patch to src/sim/erc32, and configure with --target=sparc-rtems4.9 (or your version of rtems) you should be good to go. If you don't have this patch the simulator will hang after a couple of minutes.
  • A Linux host pc which has pppd installed. Other operating systems should not be problematic, as long as they have pppd.
  • Two virtual devices on the host pc which act as the endpoints of a serial link. I used /dev/ptyr0 and /dev/ttyr0, but your system may be different.

Known limitations

  • PPPD will have to use one of the uarts available. Since you probably want to use the first one for regular console i/o, you will use the second uart for PPPD. Since the simulator one supports two uarts, you will not be able to use the second uart for anything else.

Writing the code

This part assumes that you know how to compile and link an rtems application, since no compiler/linking commands are included. However, compiling and linking the example program should not be different from compiling and linking other RTEMS programs. However, keep in mind that RTEMS must be build for use with the SIS.

General initialization

First of all, you will need to initialize rtems_pppd and rtems_bsdnet:

rtems_bsdnet_initialize_network(); rtems_pppd_initialize();

Obviously, you may want to check return values here.

Setting options for PPPD in RTEMS

You'll have to use the correct settings, both on RTEMS and on the host machine. We'll deal with the host machine later, for now we set the following settings in RTEMS:

rtems_pppd_set_option("/dev/console_b", NULL); rtems_pppd_set_option("192.168.0.80:192.168.0.1", NULL); rtems_pppd_set_option("netmask", "255.255.255.0"); rtems_pppd_set_option("defaultroute", NULL); rtems_pppd_set_option("usepeerdns", NULL); rtems_pppd_set_option("nocrtscts", NULL); rtems_pppd_set_option("local", NULL); rtems_pppd_set_option("noauth", NULL); rtems_pppd_set_option("passive", NULL); rtems_pppd_set_option("debug", NULL);

If you want to see what happens in more detail, or you have to debug your ppp connection, you can uncomment the last line. Note that some options may not be required for your application, please refer to the man page of pppd for details on the various settings.

Setting up a hook

Since we want to know when the connection has been established, we set up a hook.

static void ipup_hook () {

printf ("ip up!\n"); gConnected = true; this is a global variable. You should use events in a real app.

} rtems_pppd_set_hook(RTEMS_PPPD_IPUP_HOOK, ipup_hook);

This hook is called when the ip layer is up. This means that after that, we are completely connected to the host pc and can start using ethernet based stuff.

Connecting to the host pc

In order to start the connection process, we call:

rtems_pppd_connect();

The complete example app

Following you find a complete example application, ready to compile. Make sure to use "-lpppd" when linking. This example application includes some extra code not discussed before, but these parts will not be discussed here. Most should be pretty self-explanatory.

#include <bsp.h>

#include <rtems.h> #include <rtems/rtems_bsdnet.h> extern "C" { #include <rtems/rtemspppd.h> }

#include <stdlib.h> #include <stdio.h>

static rtems_task Init(rtems_task_argument);

/* RTEMS configuration */ #define CONFIGURE_INIT #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER #define CONFIGURE_RTEMS_INIT_TASKS_TABLE #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 128 #define CONFIGURE_MAXIMUM_TIMERS 16 #define CONFIGURE_MAXIMUM_TASKS 16 #define CONFIGURE_INIT_TASK_STACK_SIZE (64*1024) #include <rtems/confdefs.h>

/* network config */ extern "C" int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching); static struct rtems_bsdnet_ifconfig gNetdriverConfig = {

(char *)"ppp0", /* name */ rtems_ppp_driver_attach, /* attach function */ NULL, /* link to next interface */ NULL, /* ip_address */ NULL, /* ip_netmask */ NULL, 0

};

struct rtems_bsdnet_config rtems_bsdnet_config = { rtems naming convention required for proper linking

&gNetdriverConfig, ifconfig NULL, bootp 128, network_task_priority 128*1024, mbuf_bytecount */ 256*1024, mbuf_cluster_bytecount */ (char *)"pppd_test", hostname (char *)"localnet", domainname (char *)"192.168.0.1", gateway NULL, log host {NULL, }, Name server(s) {NULL, }, NTP server(s)

};

static bool gConnected = false;

static void ipup_hook () {

printf ("ip up!\n"); gConnected = true; this is a global variable. You should use events in a real app.

}

int main(int argc, char *argv[]) static rtems_task Init(rtems_task_argument argument) {

/* init */ rtems_bsdnet_initialize_network(); rtems_pppd_initialize();

/* set options */ rtems_pppd_set_option("/dev/console_b", NULL); rtems_pppd_set_option("192.168.0.80:192.168.0.1", NULL); rtems_pppd_set_option("netmask", "255.255.255.0"); rtems_pppd_set_option("defaultroute", NULL); rtems_pppd_set_option("usepeerdns", NULL); rtems_pppd_set_option("nocrtscts", NULL); rtems_pppd_set_option("local", NULL); rtems_pppd_set_option("noauth", NULL); rtems_pppd_set_option("passive", NULL); rtems_pppd_set_option("debug", NULL);

/* connect hook */ rtems_pppd_set_hook(RTEMS_PPPD_IPUP_HOOK, ipup_hook);

/* start pppd connection */ rtems_pppd_connect();

/* wait for ipup */ while (!gConnected) {

sleep(1);

}

/* you can now start using tcp/ip stuff */ while (1) {

sleep(1);

}

}

Get ready to ping

In order to run the application in the SIS and ping it on your host machine you need to take the following steps:

  • Start the application in the sis: you@host:~/ppptest$ sparc-rtems4.9-sis -uart2 /dev/ptyr0

SIS - SPARC instruction simulator 2.7.5, copyright Jiri Gaisler 1995 Bug-reports to jgais@…

sis> lo image sis> go

  • Start PPPD on the host machine: you@host:~$ pppd noauth local nodetach nodefaultroute passive lcp-echo-interval 0 /dev/ttyr0

You can supply 'debug' as an argument to see more details of the connection establishing process. You may have to wait a couple of seconds for the link to come up, if this happens the example app will print "ip up!".

  • Ping the application: you@host:~$ ping 192.168.0.80 PING 192.168.0.80 (192.168.0.80) 56(84) bytes of data. 64 bytes from 192.168.0.80: icmp_seq=1 ttl=255 time=1.71 ms 64 bytes from 192.168.0.80: icmp_seq=2 ttl=255 time=1.61 ms 64 bytes from 192.168.0.80: icmp_seq=3 ttl=255 time=1.63 ms

Troubleshooting

This section includes some possible problems you might encounter.

Cannot link the application

If you get errors like:

undefined reference to `rtems_pppd_initialize()' undefined reference to `rtems_pppd_set_option(char const*, char const*)'

check that you are including -lpppd when linking. If so, check the order of the linker options, a wrong order sometimes causes problems.

PPP connection is established, but echo requests are ignored by application

This happens if you use an old console driver. See #Prerequisites.

= SIS hangs after a few minutes of simulation =

This happens if you use the wrong version of the SIS. See #Prerequisites.