<< Previous | Index | Next >>

2. Using RabbitSys Components

This chapter describes the use of RabbitSys components and features. Detailed instructions are given for:

2.1 The Board's IP Address

The IP address of the single board computer (SBC) is needed to contact the board remotely. This section explains how to assign or obtain an IP address.


2.1.1 Assigning the IP Address

Assign the IP address at runtime by calling the Dynamic C ifconfig() function in your application. To do this, include the following statement in your program:

ifconfig(IF_ETH0, IFS_DOWN, IFS_DHCP, 0, IFS_IPADDR, aton("10.10.6.107"), IFS_UP, IFS_END);

The above line of code brings down the network interface, turns off DHCP, sets the IP address to 10.10.6.107 and then brings the interface back up. Since you have turned off DHCP, the IP address will remain unchanged unless you renable DHCP or reassign the IP address by calling ifconfig() with a new IP address. See Section 2.3.1 and Section 2.5.2 for information on other ways to assign an IP address.

The IP address you choose to assign to your board must meet the addressing requirements of your network. If you are unsure what the IP address should be, see your network administrator.


2.1.2 Obtaining the IP Address

If the target board is on the same network as the host machine running Dynamic C, you can use the UDP discovery feature to query your network for all of the RabbitSys-enabled devices present. A utility is provided for this purpose. For Windows users, click on rdiscover.exe, which is in your Dynamic C folder: \Utilities\RDPClient\Windows. The utility will open a window and list the MAC addresses for any RabbitSys board that responded. Selecting a board from the list displays additional information, including the board's IP address. For more information see Section 2.5.2.

You may have to turn off firewall protection for the discover utility to find your board.

If you allow the IP address to be assigned using DHCP, be aware that the IP address reported using UDP discovery may change without warning. This is because IP addresses are frequently leased for a certain amount of time, then released back to the server and a new lease negotiated. Often the IP address will remain the same; however, there is no requirement that this will be the case.

If you have a serial connection to your RabbitSys-enabled board you can use the Console "shownet" command to find out the IP address. You can also use the Console to turn off DHCP and set the IP address to anything you want.

2.2 Remote Program Upload

Dynamic C compiles a special type of file for upload to a RabbitSys-enabled target. To compile a file for remote upload, open the file in Dynamic C. From the Options | Project Options menu, select the Compiler tab and select "Compile program in RabbitSys user mode." Then, either select one of the .bin file compile mode options on the Compiler tab, or override this setting by selecting one of the "Compile to .bin File" options from the Compile menu. After compilation, a new file will be created in the same directory with the same name as the Dynamic C file but with a ".upl" extension.

If there is a user-level program currently running on the RabbitSys-enabled target and it has registered a callback function for the event type _SYS_EVENT_SHUTDOWN, the callback function will execute prior to the program upload. (For more information on events and how to register callback functions for them, see Section 3.6.)

If the upload is successful, RabbitSys will start the newly uploaded application. If the upload fails, the new application will not run; the old application will not run either. RabbitSys will wait for you to make contact. (For more information on how to start execution of an application, see the "app go" command in Section 2.3.1.)

There are three methods for remotely uploading a program: with a web browser, using FTP or programmatically. Each method is described in the following three subsections.


2.2.1 Using the HTTP Server

RabbitSys has an internal HTTP server listening on port 32080. To contact the system server you must know its IP address in addition to its port number. Type the following (substituting the board's IP address for the one given) into any standard web browser:


http://10.10.6.1:32080/RABBITSYS

You will be asked to provide a user name and password. The default values are "admin" and "password." Once you have been authenticated, a web page will be displayed that looks something like the one in Figure 2-1.

Figure 2-1. RabbitSys HTTP Server Home Page.

As you can see in Figure 2-1, you can type the name of the .upl file into the text box or browse for it, and then click on the Upload button. That's all there is to it.

On the web server home page, there are links to the Console and Monitor because both of these RabbitSys components are accessible via the HTTP server. They are discussed in Section 2.3 and Section 2.4 respectively.


2.2.2 Using the FTP Server

RabbitSys has an internal FTP server listening on port 32021. As with the HTTP server, you must know the board's IP address and port number to make contact. See the discussion under "The Board's IP Address" for how to determine the IP address of your board.

From a command window, type "ftp" to bring up an ftp prompt. At the prompt, type:


ftp>open 10.10.6.107 32021

substituting your board's IP address for the one given.You will be asked to provide a user name and password. The default values are the same as for the web server, "admin" and "password."

For those using a cygwin FTP program you must use the "bin" command before uploading the file.


ftp>bin

After you have been authenticated, you can upload a file to the RabbitSys-enabled target by typing:


ftp>put <filename>

The FTP server can also be used to send Console commands. See Section 2.3 for more information.

NOTE: The FTP server cannot be used simultaneously with the serial Console.

2.2.3 Using the RabbitSys API for Remote Upload

To programmatically upload a program to flash, the application must be running entirely in RAM. There are three functions to perform the remote program upload and one to start execution of the newly uploaded program.

_sys_uploadstart

Call this function first to let RabbitSys know a new user program is available.

_sys_uploaddata

Call this function repeatedly until the entire .upl file has been loaded.

_sys_uploadend

Call this function once the .upl file is completely loaded.

_sys_uploadstartupl

Call this function after calling _sys_uploadend() in order to start the newly loaded program.

The sample program in Samples\RabbitSys\usermodeupload.c uses the above API. For simplicity's sake, the sample program ximports the .upl file. It is likely you will want to use an alternative method for transferring the file to the target, such as FTP or a secure HTTP server. In addition to a secure transfer, if you use your own FTP or HTTP server you could add automatic updating of your application by polling the server for the existence of a new .upl file.

2.3 RabbitSys Console

The RabbitSys Console can be accessed over a serial connection using a terminal emulator such as HyperTerminal or Tera Term. It can also be accessed over an Ethernet connection using Telnet, FTP or HTTP. All of these communication methods are described in the subsections following a description of the Console commands.


2.3.1 Console Command Set Descriptions

The following is a complete list of RabbitSys Console commands:
help listlog showevnt
adduser logout showlog
app query shownet
alert remove showsys
getid resetlog swreset
getver rmuser sysupd
hwreset setlog watch
ifconfig setup

help

Lists all Console commands.

adduser name pw

Defines a user by adding a new name and password that will be accepted when an attempt is made to contact the Console. The name and password strings have a maximum length of 8. The number of users allowed is 8.

There is one default user which is defined as "admin" and "password." You may remove the default user once you have defined at least one other user. Users are removed using the Console command rmuser.

alert log level

Sets an alert level for a Monitor log. An alert level is the number of entries that will be logged before an email is sent to the email address set up previously.

Valid values for level are from 0 to 32767, inclusive. Valid values for "log" are: reset, system or runtime. The fatal log alert level cannot be changed.

app go|stop

Starts or stops execution of the loaded application. If an application is stopped, it will remain stopped even if the device is reset. The "app go" command must be issued to run the program. Once the program is running a reset will restart the program. Use the showsys command to determine if the program is running or stopped.

getid

Shows the following portion of the System ID block:

· Product ID1 - 2-byte number that identifies a core module or board type.
· Flash ID - 4-byte number
· Flash Type - 2-byte number
· Flash Size - 2-byte number
· RAM ID - 4-byte number
· RAM Size - 2-byte number
· MAC - 6-byte unique address that identifies the Ethernet hardware.
getver

Displays the version number: a 16-bit integer interpreted as two 8-bit hex numbers; the MSB is the major version number, and the LSB is the minor version number. Additionally, the Console displays the version build time, which is a 32-bit number.

hwreset

Causes primary watchdog reset. The Console connection will be closed. Any loaded application will not start after reset; you will need to make a new connection to start the application.

ifconfig subcmds params

Configures network parameters at runtime. Up to 8 parameters per line are allowed. The subcommands and parameters are:

baud bps - Set baud rate used by the target
port - changes the serial port while it is not being used, i.e., you must be logged in through telnet or HTTP. Introduced in RabbitSys 1.03.
dhcp on|off [#.#.#.#] - Set use of DHCP server, with optional fallback. Default is on.
gate #.#.#.# - Set gateway IP address
ip #.#.#.# - Set IP address of RabbitSys-enabled board
to address - Set email address where alerts are sent; the mailserver IP address must be set first
from address - Set email address of RabbitSys-enabled board. The address string will show up in the "from" field of the email.
mask #.#.#.# - Set subnet mask; default is 255.255.255.0
to #.#.#.# - Set nameserver IP address
smtp #.#.#.# - Set mailserver IP address

Some of the subcommands cannot be executed with an Ethernet connection; they are: dhcp, gate, ip, mask and name. The other subcommands can be executed via an Ethernet connection.

listlog log

Displays contents of specified log.

logout

Closes the Console connection.

query [[#:]# [length [s|x]]]

Shows all watch list entries if no parameters are given. Otherwise, the first parameter is the starting address in hex, using a physical address. The memory specified by the starting address is shown for the number of bytes specified by parameter "length" which must be less than or equal to 64. The default for "length" is 64; its format is either hex (x), which is the default, or a string (s).

remove [#:]#|all

Removes specified watch or all watches. A watch is specified by its starting address, either in logical or physical format.

resetlog log

Zeros out the specified log. Resetting the fatal log resets RabbitSys and restarts a loaded application.

rmuser name

Removes a user from the list of recognized names. At least one user must be defined at all times. If you try to remove the only defined user, the request will be denied.

setlog log size

Changes the number of bytes used for the specified log, automatically adjusting the size of the adjacent log to make room. Changed logs are cleared.

setup subcmds params

Sets system performance parameters (the same parameters that are shown when the command "showsys" is executed). The subcommands and parameters are:

· tick interval (in ms) - the subcommand tick takes one parameter. Setting this to zero (0) disables automatic RabbitSys tick servicing. The user must call the system tick explicitly. The system tick must be called often enough to prevent the primary and secondary watchdogs from expiring. Default = 10
· rte s|c - specifies the action to take when a runtime error occurs; execution stops (s) or continues (c). Default = "c"

Up to 8 setup subcommands and their parameters are allowed per line.

showevnt

Displays the current events and some associated data:

seh type flags clbk data timeout interval
3828 0002 0000 50AF A893

3870 0003 0000 50AF A8E1

3888 0001 0001 50A3 A8FB 00033C99 00001388
3840 0001 0001 50BB A8AD 00033CCB 000003E8
3858 0001 0001 50A3 A8C7 0003409A 00000BB8
38A0 0001 0001 50A3 A915 00034838 00001B58
38B8 0001 0003 50A3 A92F 00034F0E 00019000
38D0 0021 0028 50AF A949


"seh" is the system event handle address

"type" refers to the event type (timer-1, alert-2, shutdown-3, user-n)

"flags" indicate whether an event is recurring (1), system (0x8000), or user-defined (anything else)

"clbk" is the function callback address

"data" is the address of the event data that will be given to the callback

"timeout" is the milliseconds until the event occurs

"interval" is the period for recurring timer events.

For details on the RabbitSys event handler and what you need to know to use events in your application see Section 3.6.

showlog

Displays log information. Specifically, for each log type (watch, fatal, reset, system and runtime) its size, number of maximum entries allowed, number of current entries logged and its alert level (i.e., number of entries that it takes to trigger an email alert) are displayed. You can change the size, max entries and the alert level. The first two are changed using the Console "setlog" command. The alert level is changed with the Console alert command.

shownet

Displays the following system parameters:

· Active serial port and baud rate for Console
· IP address, Netmask and Gateway of target board
· DHCP status
· Nameserver IP address
· SMTP server IP address
· Email address where alerts are sent
showsys

Displays the system parameters that are listed here.

· System Tick Interval - default is 10
· Runtime Error action - default is cont
· Application Status - stopped | running

Some of these system parameters are set with the Console command "setup" and its subcommands.

swreset

Causes a software reset. The Console connection will be closed. If an application exists on the target, it will restart.

sysupd

Allows a RabbitSys update.

watch [[#:]# [length [x/s [log]]]]

Returns the current watch list settings if no parameters are given. If parameters are given, the specified address is added to the watch list.

The first parameter is the starting physical address in hex. Next comes the number of bytes to watch, then the format of the watched data: hex (x) or string (s). The last parameter "log," if included, causes a watch log entry to be made when a system event occurs. If "log" is not included, no entry is made in the watch log; however, the watch can be looked at using the Console "query" command.

For convenience, you can just specify the address and take the default values for the other parameters. The defaults are:

length: 64
data format: x (hex)
log: no


2.3.2 Console Access Using a Terminal Emulator

The serial port used by a terminal emulator defaults to serial port E. It can be changed by calling _sys_con_altserial() or by using the "port" subcommand of the "ifconfig" command. The new serial port will be retained over resets and can only be changed by a call to _sys_con_altserial() or by issuing the "port" subcommand.

If using the default port, follow these instructions:

  1. Connect wires to TxE, RxE and ground. Look in the user manual for your board to determine the location of the serial port E pin connections.

  2. Connect the other ends of the three wires to the appropriate locations in the 10-pin connector of a serial cable.

  3. Connect the DB9 connector of the serial cable to a COM port on your host machine.

  4. Open a terminal emulator, such as Tera Term or HyperTerminal. Tera Term is used in these instructions, but another terminal emulator would be similar.

  5. Select "Terminal" from the Setup menu and change the newline option for "Transmit" to "CR+LF."

  6. Select "Serial port setup" from the Setup menu and make sure that the COM port used by Tera Term matches the one you connected to serial port E. Match the remaining serial port parameters with those used by the target. The target's default baud rate is 115,200 bps, with 8 data bits, no parity, 2 stop bits (8N2) and no flow control.

When the programming cable is connected to the target board, the system goes into bootstrap mode on powerup or reset. The Console is unavailable via any connection when the system is in bootstrap mode. However, as soon as the system comes out of bootstrap mode or when the programming cable is removed, the Console will request a username and password which when authenticated will cause the Console prompt to be displayed. As with the other Console access methods, "admin" and "password" are the default login values.

Figure 2-2. Console login and prompt

The Console will disconnect if the session is inactive for 5 minutes.


2.3.3 Console Access Using Telnet

To make a connection to the RabbitSys Console using telnet, you must know the board's IP address and the port number on which it is listening for telnet requests. As described in Section 2.1, there are two ways to know a board's IP address. One way is to tell the board what it is and the other way is to ask it.

The telnet server listens on port 32023. You cannot make a serial or telnet connection at the same time as an FTP connection. However, you can have simultaneous connections via a web browser and either a serial or a telnet connection.

To initiate a telnet connection open a command window and type:


telnet 10.10.6.107 32023

substituting your board's IP address for the one given. As mentioned previously, you will be asked to provide a username and password. The default values are "admin" and "password." After you have been authenticated, the Console command prompt is displayed and you can type in any Console command.


2.3.4 Console Access Using FTP

This section describes the RabbitSys FTP server for Console access. First, you must log in to the server by running an FTP client and requesting a connection. From a command window, type "ftp" to bring up an ftp prompt. At the prompt, type:


open 10.10.6.107 32021

substituting your board's IP address for the one given. As mentioned previously, you will be asked to provide a username and password. The default values are "admin" and "password." After you have been authenticated, you can access Console commands by typing:


quote SYST <console command>

If your FTP client does not implement "quote" try "literal." The "SYST" command has a non-standard implementation in the RabbitSys FTP server. Instead of its common use for requesting the system type, "SYST" is used to transmit Console commands. For example, to list the Console commands, type:


quote SYST help

You may issue the SYST command without parameters to get the system type.


2.3.5 Console Access Using HTTP

As shown in Figure 2-1, the home page of the internal HTTP server has a link to the Console. Click on this link or type the following into a browser:


http://10.10.6.107:32080/CON

substituting your board's IP address for the one given. If you use the Console link from the home page, you will already be authenticated; otherwise, you will be asked to provide a username and password (defaults are "admin" and "password"). After you have been authenticated, you can access any Console command by typing it into the text box.

Figure 2-3. HTTP Interface to the Console

2.4 RabbitSys Monitor

This section describes the RabbitSys Monitor. The purpose of the RabbitSys Monitor is to provide an audit trail for detection and diagnosis of system reliability problems. This is done by using various types of Monitor logs.

NOTE: The logs are stored in battery-backed RAM and will be lost in the event of a power failure on a product that has no battery.

2.4.1 Monitor Access

The logs can be accessed via the Console or using a web browser, as well as programmatically. The Console commands that access the Monitor logs are listed in Section 2.3. The web interface was partially explained in Section 2.2.1. You can choose to access the RabbitSys home page described there and then click on the link to the Monitor or you can access the Monitor directly by typing the following into a web browser (substituting the correct IP address):


http://10.10.6.1:32080/MONITOR 

For programatic access to the Monitor, see the Monitor API function listed in Section 2.4.4 or their full descriptions found in Appendix C. "RabbitSys API Functions"


2.4.2 Monitor Logs

All log entries are time-stamped with the current time and date. There are five types of logs available: Watch, Reset, Fatal, System and Run Time. Any resets (hardware or software), fatal, system or runtime errors are logged automatically. Watch logs are different in that you must explicitly request them. All Watch logs are viewable using the Console "query" command.


2.4.2.1 Watch List Log

Up to eight memory sections can be logged simultaneously using a pool of 1862 bytes of memory (default). Each memory section can be up to 64 bytes long and can be read as a string or as ascii hex values. The Watch log size can be changed from its default size of 1862 bytes by using the Console setlog command. There is a total of 2K bytes available for all logs, so any adjustment in the size of the watch list log will affect the other logs.

To define a watch log, use the RabbitSys Console command "watch." The syntax of this command lets you specify a starting address and the number of bytes to watch, which can be up to 64 bytes.

If a watch log was defined with the "log" parameter, an entry is added to it when a system event occurs, such as a reset or a runtime error. To illustrate this point, the sample program random.c was run on the RabbitSys-enabled target. The map file2 for random.c was examined to choose a memory location to watch. (The map file gives the physical address of local variables.)

The screenshot in Figure 2-4 shows a Console session immediately following a reset. If you are reading an electronic copy of this manual, the user input in the Console session is displayed as blue text. If you are reading a hardcopy of the manual the blue text looks gray, so the color difference is harder to see. In general, user input is entered at the "CON:" prompt.

Since the Console connection was closed, the first thing that happens is that login information is requested for a new session. In this case, the default values of "admin" and "password" are returned to the Console. After being logged in, the "watch" command is sent with no parameters, which is a request for the Console to display all defined watches. Only one watch log was defined previous to the reset: 2 bytes at address 90:cb9a. Next, the "listlog" command is used to look at the watch log entries. The logged data is displayed, starting with a date/time stamp, the starting memory location, the number of bytes to display, and the data format.

If another system event were to take place, another log entry would be made. Instead, the watch is removed and then defined again. Now when the "listlog" command is given, there is no entry in the watch log because there have been no system events since the watch was defined.

Figure 2-4. Console session showing watch log
NOTE: The watch list log is not associated with Dynamic C watch expressions.

If the parameter "log" was not passed to the Console when the watch log was defined, then no entry will be placed in the log when a system event occurs. This can be useful when you are examining memory repeatedly while an application is running. Sometimes application events are happening at human speeds while memory contents are not changing quickly. In such cases you could look at the memory contents after some event without the need to log an event to trigger a watch.

You may use the runtime error log as a way to instrument your application code: Set the runtime error behavior to 'c' (continue) in the setup <rte> command, set memory watches on the pertinent variables/memory buffers of your program, and then call the runtime error routine _sys_mon_rt_error()with a location code for the error code. This will cause watches to be saved and allow your program to continue running. You may also want to disable alerts during this by setting the alert level to zero (0) using the "alert" command.


2.4.2.2 Reset Log

The reset log records each hardware and software reset. The screenshot in Figure 2-5 shows the result of the "showlog" command. There are three entries in the reset log; we use the "listlog" command to display them.

Figure 2-5. Reset Log

After the date/time stamp there is a 2-byte hex number that identifies the type of reset. The possible values are:

0008 - software reset
0048 - watchdog timeout
00C8 - hardware reset

These values are read from the Global Control/Status Register (GCSR) on startup.


2.4.2.3 Error Logs

There are three types of error logs: fatal, runtime and system. Each error log entry has a date/time stamp followed by a 2-byte number that identifies the error. Look in /lib/errno.lib for a description of the system-defined error codes.

Fatal errors are caused by attempts to access system resources, like memory. Both fatal and system errors will shutdown the system, with the exception of the system I/O error -EIO. The error code -EFAULT is always fatal.

An application may add user-defined error codes for both runtime or system error logging by calling the API functions _sys_mon_rt_error() or _sys_mon_system_error(), respectively. An application cannot add user-defined error codes that will be logged to the fatal error log.


2.4.3 E-mail Alerts

An e-mail alert is triggered by exceeding a user-settable number of entries in a log. For example, say you use the RabbitSys Console to set the number of entries for the Reset log to one. At the Console command prompt, you would type:


alert reset 1

If the system is then reset, an email will be sent, provided that either the Console command ifconfig or the function _sys_mon_set_email() has been used to set IP addresses for the SMTP server and the email recipient. Note that any defined "alert" events are triggered at this time as well.


2.4.4 Monitor API Functions

The Monitor is available programmatically as well as through the Console. The Monitor API is comprised of the following functions:

_sys_mon_get_log()

This function returns all entries in the specified log.

_sys_mon_get_watch()

This function returns all entries in the watch log.

_sys_mon_get_log_def()

This function returns the size and alert levels for all Monitor logs.

_sys_mon_get_watch_def()

This function returns the settings of all watch log entries.

_sys_mon_rt_error()

This function enters the specified error code into the runtime error log. It logs all defined watches that have their logging flag set. If an alert level for the runtime error log is reached, this function sends an email and triggers the alert event. If the watch log is full, an entry is made in the system Monitor log, which will trigger an email if the alert level for the system log is reached.

_sys_mon_set_email()

This function sets the IP address of the SMTP server and the e-mail address for alert messages. The maximum length for the email address is 39 characters.

_sys_mon_system_error()

This function enters the specified error code into the system or fatal error log. It logs all defined watches that have their logging flag set. If an alert level for the system error log is reached, this function sends an email and triggers the alert event.
If this is a fatal error the application will be stopped and the system will be reset. The user program will not be allowed to run again until the fatal log is cleared. System errors also cause a system reset, except for a few exceptions, such as "-EIO" which is an I/O error.

The following code fragment is an example of setting the parameters to receive email alerts.


if(_sys_mon_set_email("209.233.102.3", "me@rabbit.com"))
{
printf("set_email() failed\n");
}

2.5 Network Support

This section describes the interface to the networking subsystem of RabbitSys. As mentioned previously, using the network capabilities of Dynamic C under RabbitSys is almost exactly like using the network capabilities of Dynamic C without RabbitSys.The one difference is in the allocation of socket structure memory. You should clear any tcp_Socket structures that you use; do this one time at the beginning of your application. Do not clear this memory at any time afterwards as you will be overwriting the index of the socket in the socket array, i.e., the handle to tcp_Socket, and probably corrupting memory.

Socket management takes place "under the hood." For those that want direct access, there are several new API functions available. To see function descriptions, go to the links named under "Networking" in Chapter Appendix C. "RabbitSys API Functions."


2.5.1 Configuration Macros

The following configuration macros are already available when using the Dynamic C TCP/IP stack. When running RabbitSys, the macros have the same name and function but different default values.

The macros MAX_TCP_SOCKET_BUFFERS and MAX_UDP_SOCKET_BUFFERS define the number of socket buffers available. Without RabbitSys, the default value for these macros is 4; when running RabbitSys, the default is 3. The maximum number of sockets allowable is 48.


2.5.2 DHCP and UDP Discovery

RabbitSys-enabled boards are configured with DHCP by default for automatic network configuration. As long as your local area network provides a DHCP server, this feature works seamlessly.

A utility that makes use of the UDP discovery feature is provided for both Windows and Linux users. Relative to the location of your Dynamic C installation, rdiscover.exe is in the Utilities\RDPClient folder.

To use this utility you must have your host machine connected to the same network as the RabbitSys-enabled device whose IP address you want to know. If you have the programming cable connected, you must disconnect it and reset the target board before running rdiscover.exe. Note that the device must be RabbitSys-enabled, i.e., RabbitSys must be loaded on the device.

The screenshot in Figure 2-6 shows the rdiscover screen when two target boards responded to the UDP discovery packet.

Figure 2-6. Initial Screen of rdiscover Utility

To find out the IP address of your board, match the last six digits of the MAC address (which is on a sticker on your RabbitCore module) with one of the choices displayed by the discover utility. Enter the appropriate number for your board at the prompt and hit return. You will see a screen like the one in Figure 2-7:

Figure 2-7. Secondary Screen of rdiscover Utility

From the secondary screen you can edit the network configuration, changing things like the IP address and the use of DHCP. Changing the IP address should be done with caution as it may make the board unavailable over the network. If this happens, you can recover by changing the IP address through the serial Console or by removing the battery which will reset to default settings.

The combination of DHCP and UDP Discovery give you immediate access to the board as soon as you attach it to your network.


2.5.3 HTTP Server

The RabbitSys HTTP server provides two main services. First, it provides information to the outside world via static and dynamically created web pages. These pages contain board specific information, system status, user program status, as well as user registered information from the RabbitSys Monitor. Second, the HTTP server provides program updating capabilities through standard HTTP upload. The RabbitSys HTTP server can be accessed in an application to:


2.5.3.1 Registering User-Defined Web Pages

This section describes how to register web pages with the RabbitSys internal HTTP server. Web pages are not registered individually, instead a resource table is registered. The application has a resource table separate from the web server's resource table.

The following macros are used to create a resource table.

RS_HTTPRESOURCETABLE_START

This macro is required. It must be first.

RS_HTTPRESOURCE_XMEMFILE_HTML(name, addr)

This macro identifies an html page. As the macro name implies, the page must be in xmem. This is done with an #ximport statement.

RS_HTTPRESOURCE_XMEMFILE_GIF(name, addr)

This macro identifies a .gif file. As with an html page, the .gif file must be in xmem, brought in by an #ximport statement.

RS_HTTPRESOURCE_XMEMFILE_JPEG(name, addr)

This macro identifies a .jpg file. As with html pages and .gif files, the .jpg file must be in xmem, brought in by an #ximport statement.

RS_HTTPRESOURCE_FUNCTION(name, addr)

This macro identifies a Dynamic C function that can be referenced in an html page (SSI).

RS_HTTPRESOURCE_CGI(name, addr)

This macro identifies a Dynamic C function that can be referenced in an html page (CGI).

RS_HTTPRESOURCETABLE_END

This macro is required. It must be last.

RS_REGISTERTABLE()

This macro is used to register the resource table with the RabbitSys web server.

The sample program http.c creates a resource table and registers it with the server in the following code fragment:


#ximport "samples/rabbitsys/static_ssi.html"      index_html
#ximport "samples/tcpip/http/pages/rabbit1.gif"   rabbit1_gif
#ximport "samples/rabbitsys/RabbitSysCGI.html" rscgi_html
RS_HTTPRESOURCETABLE_START
RS_HTTPRESOURCE_XMEMFILE_HTML("/", index_html),
RS_HTTPRESOURCE_XMEMFILE_GIF("/rabbit1.gif", rabbit1_gif),
RS_HTTPRESOURCE_FUNCTION("testfunc", testproc),
RS_HTTPRESOURCE_FUNCTION("/purefunc", pureproc),
RS_HTTPRESOURCE_XMEMFILE_HTML("/rscgi", rscgi_html),
RS_HTTPRESOURCE_CGI("/rabbitsys_cgi.cgi", rscgi_func),
RS_HTTPRESOURCETABLE_END
void main (void){
RS_REGISTERTABLE();
while (1)
_sys_tick(1);
}

2.5.3.2 Using RabbitSys-Style SSI

The RabbitSys HTTP server has an SSI-style parser. Rather than using the SSI syntax shown here:


<!--#exec cmd="functionname"-->

The RabbitSys HTTP server will enforce the following syntax:


`function_number,param;

where function_number identifies a function known to the server and used in the web page; and param is a numeric parameter that will be placed in the substate member of the server's state structure for use by said function.

The SSI-style tag must appear in the web page as it does above, starting with a single quote3 and with no whitespace within the string. Functions identified in an SSI-style tag must return a pointer to this type of structure:


typedef struct{
int retval;
int newParameter;
char *buffer;
}rs_SSI_CGI_State;

The buffer holds the data to send and must be null-terminated. The buffer size must be less than RS_HTTP_MAXBUFFER (512 bytes). Prior to calling the function referenced in the SSI tag, the HTTP socket buffer will be flushed. The function is responsible for copying correctly formatted HTML into the buffer it returns, and returning RS_SSI_SEND to signify that data needs to be sent, RS_SSI_SEND_DONE to signify that data needs to be sent and the function does not need to be called anymore, or RS_SSI_DONE to signify that the function is finished.

The sample program http.c and its web page static_ssi.html provide an example of using the new SSI tag and also of registering a resource table. First, take a look at the web page, shown below. There are two SSI-style tags.

File Name: /samples/RabbitSys/static_ssi.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><HEAD>
<TITLE>my first stack web server</TITLE>
</HEAD>
<BODY topmargin="0" leftmargin="0" marginwidth="0"
  marginheight="0" bgcolor="#FFFFFF" link="#009966"
  vlink="#FFCC00" alink="#006666">
<CENTER>
<img SRC="rabbit1.gif">
<BR><BR><BR>
That was EASY!!!!!!
'testfunc,12;
</CENTER>
'testfunc,42;

Next, look at this code fragment from http.c. It is the function that is referenced in the html page static_ssi.html. To see the full sample program, go to /samples/RabbitSys.

File Name: /samples/RabbitSys/http.c

rs_SSI_CGI_State st;
char mybuffer[256];
rs_SSI_CGI_State *testproc (int param)
{
st.buffer = mybuffer;
sprintf(st.buffer,"<BR>Text from an SSI procedure.\n<BR> Param was %d\n",param); if ( param==42 ) { strcpy(mybuffer,"<P><A HREF=/RABBITSYS>RabbitSys Home</A> \n</BODY>\n</HTML>"); st.retval = RS_SSI_SENDDONE;
}
else if (param==15)
st.retval = RS_SSI_SENDDONE;
else {
st.newParameter = param+1;
st.retval = RS_SSI_SEND;
}
return &st;
}

An important thing to notice is that the HTML code in the file static_ssi.html referenced the name testfunc to request execution of the function testproc(). This renaming was done when the user's resource table was created. The code in Section 2.5.3.1 included the line:


RS_HTTPRESOURCE_FUNCTION("testfunc", testproc),

which registered the name testfunc with the server as a label for the function testproc().


2.5.3.3 CGI Programming

The sample program http.c demonstrates RabbitSys CGI programming. Download this program to your target and then open a browser and type:


http://10.10.6.107/

substituting your board's IP address for the one given. Your browser will display the web page static_ssi.html; from there click on the link "CGI Example." A different web page will be displayed: RabbitSysCGI.html. This web page contains a form for text entry. When the form is submitted (i.e., the user clicks on the submit button labeled "Okay") the CGI defined in http.c is called multiple times by the web server. The CGI is named rscgi_func(). Basically, it is a big switch statement to handle the state machine requirements of a CGI as it dynamically builds a web page.

Use rscgi_func() as a template for your own CGI. Every CGI is passed a pointer to a sysHttpState structure. The definition of this structure at the beginning of http.c is provided for reference only. It could be commented out of http.c and a void pointer be substituted as the parameter in the definition of rscgi_func() and the application would behave exactly the same.

You should not write to any of the sysHttpState struct fields. Consider them read-only. The action field contains the CGI action code sent from the HTTP server. The HTTP server separates out the form parts (and parses the headers). As it does this, it calls the CGI function with the data for each section. The action code states the reason that the CGI is being called. Action codes that may be sent to the CGI function from the internal HTTP server are defined in syscommon.lib. They are: RS_CGI_START, RS_CGI_DATA, RS_CGI_END, RS_CGI_EOF, RS_CGI_CONTINUE, RS_CGI_PROLOG, RS_CGI_HEADER and RS_CGI_EPILOG. For more information on CGI action codes see the Dynamic C TCP/IP User's Manual, Vol. 2.

The web page containing the text-entry form is shown in Figure 2-8.

Figure 2-8. Text-Entry Form Screenshot

The html source code for the above web page is shown next.

File Name: RabbitSysCGI.html

You will have to create a similar html page that will identify the CGI defined in your application. The important line in the above code is the "Form" tag, specifically its "Action" attribute. The "Action" attribute is where you name the CGI that the web server should call when the form is submitted. Note that "/rabbitsys_cgi.cgi" is the label given to rscgi_func() in the user resource table defined just before main() in http.c.

The "Method" and "enctype" attributes of the "Form" tag must appear in your html page as they do in RabbitSysCGI.html.

1 A list of known products and their product IDs can be found in the Dynamic C GUI by choosing Options -> Project Options and then selecting the "Targetless" tab and then the "Board Selection" tab.

2 Map files are a convenient tool to use with watch logs. For more information on map files, see the Dynamic C User's Manual.

3 If a RabbitSys web page needs to include the single quote character (`), encode it in HTML as &#96;.


RabbitSys << Previous | Index | Next>> rabbit.com