C&H Technologies, Inc. (C&H) provides this manual "as is" without warranty of any kind,
either expressed or implied, including but not limited to the implied warranties of
merchantability and fitness for a particular purpose. C&H may make improvements and/or
changes in the product(s) and/or program(s) described in this manual at any time and without
notice.
This publication could contain technical inaccuracies or typographical errors. Changes are
periodically made to the information herein; these changes will be incorporated in new editions
of this publication.
The information and/or drawings set forth in this document and all rights in and to inventions
disclosed herein which might be granted thereon disclosing or employing the materials, methods,
techniques, or apparatus described herein, are the exclusive property of C&H Technologies, Inc.
A Reader's Comment Form is provided at the back of this publication. If this form has been
removed address comments to:
C&H Technologies, Inc.
Technical Publications
800 Paloma Drive, Suite 150
Round Rock, Texas 78665
C&H may use or distribute any of the information you supply in any way that it believes
appropriate without incurring any obligations whatever.
ii
Page 3
DOCUMENT REVISION NOTICE
C&H Technologies, Inc. makes every attempt to provide up-to-date manuals with the associated
equipment. Occasionally, throughout the life of an instrument, changes are deemed necessary to
equipment related documentation. The latest revision of our documentation is available for
download from our web site at http://www.chtech.com.
NOTE
The contents of any amendment may affect operation,
maintenance, or calibration of the equipment.
iii
Page 4
INTRODUCTION
This manual describes the operation and use of the scripting features of the EM405-8 Ethernet
M-Module Carrier/Bridge (Part Number 11029380). The scripting features described throughout
this manual are available on all EM405-8’s containing firmware version 3.0 and later. Contained
within this manual are the functional details and the programmatic guidelines to adequately
develop and deploy script-based applications for the EM405-8.
The EM405-8 is one of many test, data acquisition and control modules provided by C&H
Technology and is one of a number of M-Module carriers in C&H Technologies’ product line.
All manufacturing options of the EM405-8 include the scripting features; however, only options
that include an internal mass storage device provide non-volatile storage of scripts and
autonomous operation using the startup script feature.
The part numbers of the EM405-8’s that are covered by this manual are:
Part Number Description
11029380-0001 EM405-8 with external triggers
11029380-0002 EM405-8 without external triggers
11029380-0003 EM405-8 with external triggers and 16GB mass storage
11029380-0004 EM405-8 without external triggers, but with 16GB mass storage
EM405-8’s that contain a firmw are revision prior to 3.0 can be updated in the field to the most recent firmware
revision containing the scripting support. Please contact C&H Technologies Technical Support for update files and
detailed instructions.
iv
Page 5
TABLE OF CONTENTS
1.0 GENERAL DESCRIPTION ............................................................................................1
1.1 PURPOSE OF EQUIPMENT.............................................................................................2
1.2 THE LUA SCRIPTING LANGUAGE ...............................................................................2
1.3 KEY FEATURES OF EM405-8 SCRIPTING ................................................................... 2
Figure 6 Data Passing Example....................................................................................................21
Figure 7 M-Module Driver Example Code...................................................................................25
Figure 8 M-Module Driver Example Using Buffers ....................................................................26
Figure 9 M-Module Driver Example Using Arrays......................................................................27
Figure 10 Simple Lua Based Web Page .......................................................................................30
Figure 11 Example Adding Link to the Navigation Menu...........................................................31
Figure 12 Example Linking to a User Image.................................................................................32
Figure 13 Example Retrieving Arguments from the URL ............................................................33
Figure 14 Example Using “l_em405web.lua” Library..................................................................35
LIST OF TABLES
Table I Use and Management Commands......................................................................................4
Table II. Functions in the EM405-8 Extensions Library..............................................................14
Table III. Alien Data Types ..........................................................................................................23
Table IV l_em405web.lua Library Functions................................................................................33
vi
Page 7
PART OF SCRIPTING EN
VIRONMENT FURNISHED
BY C&H
APPLICATION SPECIF IC
CUSTOMER DEVELOPMEN
T HARDWARE
STANDARD AVAILABLE S
OFTWARE FROM C&H OR
THIRD PA R TY
EM405
-
8 UTILITIES
EM405
-
8 LUA EXTENSIONS
M-
MODULE ANSI
-
C DRIVERS
LUA STD LIBRARIES
ALIEN LIB
MASS STORAGE
EM405
-
8 SCRIPT MANAGEMENT
EM405
-
8 IVI DRIVER
USER
WEB BROWSER
HOST
EM405
-8
RUN-TIME ENVIRONMENT
STANDARD TOOLS
ETHERNET
1.0 GENERAL DESCRIPTION
The scripting utilities of the EM405-8 M-Module Bridge provide enhanced programming
capabilities allowin g the user to easily embed software on the bridge to improve performance
and further integrate a set of M-modules. The scripting utilities are based off of the Lua
programming language and include extensions and customizations designed specifically for the
EM405-8. An architecture diagram of the scripting utilities is shown in Figure 1. Since Lua is
an interpretive language, EM405-8 users can easily develop scripts without the need for an
expensive development environment.
By embedding a script or a set of scripts on the EM405-8, the burden for monitoring, configuring
and controlling the M-modules is taken off the network and placed onto the EM405-8’s embedded
processor. This provides significant performance improvements and allows the EM405-8 and
associated M-modules to be customized and configured. It can also act independently for a long
period of time without the need for a network client to monitor the device(s).
DEVELOP SCRIPTS
MANAGE SCRIPTS
RUN S CRIPTS
VIEW SCRIPT OUTPUT
TELNET – RAW SOCKET I/F
TERMINAL EMULATOR
TEXT-BASED DEV ELOPMENT
COMMANDS
AND DATA
SCRIPTS
APPLICATION
CONT ROL SCRIPTS
SEND COMMANDS
RETRIEVE DATA
The EM405-8 was designed for measurement, automation and control applications. The EM405
easily interfaces a VITA 12-1996 standard M-Module to a typical Ethernet network. The carrier
allows the numerous functions available in the M-Module mezzanine format to be remotely
located near the unit-under-test, easing many system integration issues. Over 100 M-Modules
are available from numerous manufacturers.
The scripting utilities were added to the EM405-8 to allow users to fully ut ilize the embedded
processor of the EM405-8 and to allow for easy customization of the integrated unit.
1.2 THE LUA SCRIPTING LANGUAGE
Lua (pronounced LOO-ah) is a powerful, fast, lightweight embeddable scripting language. It is
important to note that the name Lua is not an acronym. Lua was written in ANSI-C and is
designed to easily integrate with other software written in C and other conventional
programming languages. Thus, one of Lua’s primary strengths is its extensibility. Lua’s
extensibility is two-fold. Lua can be used to extend an application by embedding Lua scripting
into the application. Also, Lua itself is extendible allowing Lua scripts to utilize libraries and
components written in other programming languages.
Lua is an interpreted language in that Lua programs are stored as text that is interpreted at runtime. In reality, Lua code is compiled at runtime into an intermediate form; however, the fact
that compilation is performed at runtime allows scripts to be run directly from text and allows
Lua to retain the designation of an interpreted language.
Lua is free software distributed under the terms of the MIT license. The MIT license is short and
very liberal, allowing the user unrestricted use the software.
Further details, including documentation and references can be found at www.lua.org.
1.3 KEY FEATURES OF EM405-8 SC RIPTING
The EM405-8 implementation of scripting includes the basics of Lua including all standard
libraries, as well as EM405-8 specific extensions and EM405-8 specific script development
tools. Key features include:
EM405-8 extensions to control M-modules and EM405-8 utilities
Call high-level M-module drivers and other libraries
TCP/IP based interactive interpreter for development
Develop scripts using any text editor. No compilation required
Store and retrieve data to/from mass storage device (mass storage is an EM405-8 option)
Receive commands and pass data over the Ethernet interface
Network based commands to use and manage scripts (store, retrieve, run, halt, etc.)
Create custom web pages to control the instrument
2
Page 9
1.4 APPLICABLE REFERENCES
In addition to this reference manual there are several sources of further information on both the
EM405-8 and the Lua programming language. These documents should be referenced for details
of topics not covered or not elaborated on by this manual. The most applicable references are:
The scripting utilities are accessible via the standard EM405-8 command interfaces (VXI-11 and
raw socket). In addition, a special scripting socket interface is available to help develop and
debug scripts. A set of use and management commands are defined and any of th ese commands
can be sent via any of the available interfaces with a few exceptions.
2.1 COMMANDS
The scripting commands allow the user to develop, use and manage scripts. These commands
are the primary interface to the scripting utilities and are used during both development and
deployment of scripts. They are available, with a few exceptions, via any of the EM405-8’s
command interfaces including the special scripting socket interface. A complete list of use and
management commands is shown in Table I. Details of each command can be found in the
subsequent sections.
Table I Use and Management Commands
?|help list command help
data <data>
halt <script> halt the script of the specified name
-l <script> halt last script started of specified name
-a [script] halt all running scripts
list list all scripts
-l [script] list details (script name optional)
-r [script] list if running (script name optional)
read <script> read the specified script
remove <script> remove the script
retrieve <script><port> retrieve the script using the specified port
-d delete the file upon retrieval
run <script> run specified script
-e <command> execute command
-i
socket? returns 1 if scripting socket running, 0 if not
-p returns the port of the scripting socket
upload <script><port> upload the script using the specified port
-x execute script after upload
-o overwrite script if file exists
ver returns versions of Lua and EM405-8 extensions
Note: An asterisk (*) is required before the command if sent via the VXI-11 or raw socket interface. The
EM405-8 contains a binary command protocol. An asterisk (*) character denotes that the remaining
command consists of ASCII characters. If the first byte i s anything other that an asterisk (*) the EM405-8
perceives it as a binary command. The binary commands are not available via the scripting socket therefore
the asterisk (*) is not required nor recognized.
-nx <script>
send up to 16Kbytes to a script (VXI-11 only)
halt script number x of specified name
enter interactive mode (scripting socket only)
2.1.1 ? | Help
The help command or simply ‘?’ will return a list of commands along with argument options
and descriptions similar to Table I. The result will be output via the same interface from which
the command was received.
help or ?
4
Page 11
2.1.2 Data
The data command allows the user to transfer up to 16 kilobytes of data to a running script.
This command is only available over the VXI-11 or raw socket interface. It has no effect if sent
over the scripting socket interface.
data <up to 16K of data>
The command requires a running script that is expecting or polling for data. If such a script is
not running then this command will result in an I/O Error. For details on transferring data
to/from a running script refer to section 3.3.
2.1.3 Halt
The halt command is used to stop running scripts. Scripts always run in their own thread
allowing multip le scripts to be run at the same time. The halt command has the followin g
syntax:
halt <options>
options:
<script> halt the first script started of the specified name
-l <script> halt the last script started of the specified name
-nX <script> halt script number x of specified name
-a [script] halt all scripts or all scripts of the specified name
In addition to running more that one script at a time, the same script can be concurrently run
multiple times, each in its own thread. The system maintains a sequence list indicating the order
in which each instance of a running script was started. Using the halt command, the user can
specify the specific instance to halt, based on this start sequence. The system does not maintain
any further details other that the start order. It is up to the user to understand the details of a
specific instance, such as the responsibilities of that instance, and the order in which that instance
was started.
With the –a option the user can halt all running scripts of a specified name, by passing the script
name argument or all running scripts within the system by not specifying a script name.
2.1.4 List
The list command will return a list of all scripts stored on the system. The result will be output
via the same interface from which the command was sent.
list [options]
options:
-l show details of each file
-r show only scripts that are currently running
[script] if the optional [script] is specified only that script
will be shown
5
Page 12
Arguments of the list command are optional. If no arguments are provided, all scripts will be
listed without details. Use the –l option to show the details of the scripts. Details include the
file size, date, the system/user designation and a run/idle status indication. The –r option shows
only those scripts that are currently running. Both options may be included in a single list
command. If the optional [script] argument is passed only scripts of the specified name will
be listed.
In the output of the list command, each script listing is terminated with a “new line” character
(‘\n’ or 0xA). The entire list is terminated with a carriage return (‘\r’ or 0xD).
2.1.5 Read
The read command will return the source code of the specified script via the interface from
which the command was sent. For example, if in the scripting socket interface you type read
myscript.lua the source code of myscript.lua will appear in the terminal window. If you
send the same command via the VXI-11 interface, the next VXI-11 read will return the source
code of the script. Note that the VXI-11 interface has a 16 kilobyte limit therefore any script
greater than 16 kilobytes will not be returned properly. An alternative to the read command is
the retrieve command detailed in section 2.1.7.
read <script>
2.1.6 Remove
The remove command will delete the specified script from both volatile and non-volatile
memory. A removed script is not recoverable therefore care must be taken to ensure a script is
saved on a host computer before sending the remove command.
remove <script>
2.1.7 Retrieve
The retrieve command is used to download a script from the EM405-8 to the host computer.
A download port must be specified.
retrieve [options] <script> <port>
options:
-d delete the file upon retrieval
Upon receiving the retrieve command, the EM405-8 will search for the specified script and
return a 4-byte acknowledge (“ack\n” if found or “nck\n” if not found) via the same interface
from which the command was received. If the script was found, the EM405-8 will launch a
small TCP/IP server at the specified port. The host application must then connect to this server
to download the script. The TCP/IP server will automatically ex it once the script has been
downloaded. Therefore, a new retrieve command must be used for each script to be
downloaded.
6
Page 13
4
The script is sent over the TCP/IP server by the EM405-8 in a raw format preceded by 4 bytes
specifying the size of the file as shown in Figure 2. Figure 2 also shows the simple procedure to
download the file.
FILE SIZE (4 BYTES)
FILE DATA
0
4 + FILE SIZE
Download Procedure
1. Send the download command
2. Read the 4-byte Acknowledge
3. If “nck\n” then exit else if “ack\n” continue
4. Connect to the download port via raw socket
5. Read 4-bytes to determine size. Byte 0 is
the least significant byte.
6. Read size bytes to buffer
7. Write buffer to file on host computer
Figure 2 Retrieve Script Download Format
If the –d option is found, the script will be deleted at the completion of the download. A deleted
script is not recoverable therefore care must be taken before sending the -d option
2.1.8 Run
The run command starts the specified script, launches interactive mode or executes the specified
Lua command. One of the three arguments is required for the run command. Only one
argument can be passed in a single run command.
run <argument>
arguments:
<script> run the specified script
-i enter interactive mode (scripting socket only)
-e <command> executes the specified command
Running a specific scri pt will launch the script in its own process so that it may run
independently and so that the user may launch more that one script. In reality, the run command is optional. Scripts can be run by simply sending the name of the script to the EM405-8 as a
command itself. Further, if the file extension of the script is .lua than the extension may be
omitted. For example, if the script file is myscript.lua then the followin g three commands
perform the same action of launching the script
run myscript.lua
myscript.lua
myscript
Interactive mode is a special mode of the scripting socket in which the user can type Lua source
code directly to the interpreter to be run immediately. Details on interactive mode can be found
in section 2.3.3. The –i option is only valid from the scripting socket interface and does not
return until the socket is closed.
7
Page 14
The –e argument allows the user to input Lua source to be run immediately. It is different than
interactive mode in that it does not give the user a different command prompt in the scripting
socket and more importantly once the command(s) is complete the Lua state is lost. In other
words, variables, loaded libraries and other constructs that are normally valid from one command
to the next are only available durin g that one command.
2.1.9 Socket?
The socket? command will return an ASCII ‘1’ if the scriptin g socket interface is available and
an ASCII ‘0’ if not. Further passing the –p argument will return the TCP/IP port of the scripting
socket interface. Note that the –p argument will return a port number regardless of whether or
not the scripting socket is available.
socket? [options]
options:
-p returns the port number of the raw socket interface
It is useful to send the socket? command via the VXI-11 or raw socket interface to determine if
the scripting socket interface is available and to determine at which TCP/IP port to connect to it.
2.1.10 Upload
The upload command is used to upload a script from a host computer to the EM405-8. An
upload port must be specified.
upload [options] <script> <port>
options:
-x execute the script after upload
-o overwrite the script if the file exists
Upon receiving the upload command, the EM405-8 will first determine if a script of the same
name already exists. If the EM405-8 finds a script of the same name and the –o is not provided a
4-byte negative acknowledge (“nck\n”) is returned. If it does not find a script of the same name
or if the –o option is provided, a 4-byte positive acknowledge (“ack\n”) is returned. The
acknowledge, whether it is positive or negative, is sent via the same interface from which the
command was received.
If a positive acknowledge is returned the, EM405-8 will launch a small TCP/IP server at the
specified port. The host application must then connect to this server to upload the script. The
TCP/IP server will automatically exit once the script has been uploaded. Therefore, a new
upload command must be used for each script to be uploaded.
The host computer must send the script in a raw format preceded with 4 bytes specifying the size
of the file as shown in Figure 3. Figure 3 also shows the simple procedure to upload the file.
8
Page 15
4
FILE SIZE (4 BYTES)
FILE DATA
0
4 + FILE SIZE
Upload Procedure
1. Send the upload command
2. Read the 4-byte Acknowledge
3. If “nck\n” then exit else if “ack\n” continue
4. Connect to the upload port via raw socket
5. Determine the file size
6. Pass the 4-byte size. Byte 0 is the least
significant byte.
7. Read the file and pass size bytes to the
EM405-8
Figure 3 Script Upload Format
If the –x option is found, the script will be automatically executed at the completion of the
download. A minor limitation of the –x option is that is does not allow you to pass arguments to
the script upon running it. If this functionality is needed, simply use the upload command
without the –x option followed by the run command.
2.1.11 Ver
The ver command will return version information of both the Lua interpreter and the EM405-8
extensions. The result will be output via the same interface from which the command was
received. There are no arguments to the ver command.
ver
2.2 STORING SCRIPTS AND SUPPORTING FILES
All scripts and supporting files are stored in a single script pool. Since there are no
subdirectories in the script pool each file must have a unique name. U sing the upload command
detailed in section 2.1.10, the user can upload and store any file into the script pool. All file
related commands such as list, read, remove, retrieve and run operate on the script pool.
Files in the script pool are labeled either sys or user. The system files are scripts that are
furnished by C&H and are stored on the EM405-8 as part of the EM405-8 firmware. These files
include EM405-8 utility scripts. User files are those uploaded by the user. Using the –l
argument of the list command, the sys versus user type of each file can be determined.
If the EM405-8 being used includes the internal mass storage option, the script pool is
automatically stored on the mass storage device in a non-volatile fashion. If the EM405-8 does
not contain the internal mass storage option, the script pool, with the exception of the system
scripts, is stored in volatile memory and must be uploaded after every power-up. In both cases,
the absolute path of the user script pool is: /usr/scripts/user.
There are several symbolic links in the EM405-8 web server host directory and link to the script
pool. These symbolic links allow scripts to be used to create custom web pages and allow these
custom webpage to link to images and other files uploaded by the user. Details on the symbolic
links and the use of scripts to develop custom web pages can be found in section 4.0.
9
Page 16
2.3 SCRIPTING SOCKET INTERFACE
The EM405-8 supplies a TCP/IP socket interface that allows the user to interact with the
scripting utilities of the carrier. This is the primary interface used for developing scripts. This
interface accepts commands that allow the user to run scripts and view the script output. If a
script is started from the scripting socket interface, the scripting socket interface acts as the
stdout of the script. The commands accepted over the scripting socket interface are detailed in
section 2.1. In addition, the interface implements an interactive mode that allows the user to
input script commands line by line.
2.3.1 Configuring the Scripting Socket Interface
The scripting socket interface provided by the EM405-8 is disabled by default. It can be enabled
via the webpage of the EM405-8 under “Network Configuration.” Figure 4 shows the Network
Configuration webpage.
Figure 4 Network Configuration Webpage
The “Scripting Socket” enable/disable selection determines whether the socket interface is
available and the “Scripting Socket Port” specifies the TCP/IP port number at which the user will
connect to the interface. The default port number is 10011. If this port is used by a different
application in the system then this setting can be modified.
10
Page 17
Port numbers are assigned by the Internet Assigned Numbers Authority (IANA) and many are
reserved for specific functions such as HTTP, SMTP, or telnet. Care must be taken not to choose
a port number that is reserved or that will be commonly used on the network.
2.3.2 Connecting to the Scripting Socket Interface
Application software can utilize the scripting socket interface using a standard TCP/IP raw
socket connection to the EM405-8’s IP address and the scripting socket port number. The
application can then transmit ASCII commands as detailed in section 2.1 and receive standard
output directly from the scripts.
Alternatively and more commonly, the user will utilize the scripting socket interface using a
telnet type connection in which the user will be able to manually type in commands and view the
script output. For example, using the Windows command prompt or a Linux terminal, the user
can connect to the scripting socket interface by typing the following:
$ telnet 192.168.1.236 10011
In this example 192.168.1.236 is the IP address of the EM405-8 and 10011 is the configured port
number of the scripting socket interface. For proper operation and display, the telnet interface must be configured for local echo and for CR+LF termination of commands.
The user can directly input commands as detailed in section 2.1 at the command prompt. In
addition, the scripting socket interface forwards the standard output console (stdout and
stderr) to the socket allowing all data destined for the stdout and stderr to be displayed on
the scripting socket interface. The data includes stdout data (print() function) from the
scripts themselves and warnings, errors and messages from the Lua interpreter.
In contrast, the standard EM405-8 VXI-11 and raw socket interfaces accept the same commands
that are available via the scripting socket interface; however these interfaces do not allow the
user to interactively control the scripting utilities w ith a telnet type connection nor do they allow
the user to receive console messages and errors.
2.3.3 Interactive Mode
From the scripting socket interface, the user can enter interactive mode with the command
run –i.
Once in interactive mode, the user can input Lua statements directly at the command prompt.
Interactive mode reads lines that the user inputs and executes them as they are read like the
following example (bold indicates the output):
>print(5+10)
15
Interactive mode recognizes incomplete Lua statements and in-turn prompts the user for more
data until the statement is complete or a syntax error is found. This allows the user to input
multi-line statements such as for loops and if-else conditional statements. For example an if-then
11
Page 18
statement will look like the follow ing (bold indicates the output):
>a=10
>if a == 5 then
>> print(“pass”)
>>else
>>print(“fail”)
>>end
fail
Interactive mode also supports a special prefix “=” that will cause the interpreter to print the
value of the expression to the right of the “=” sign. For example (bold indicates the output):
>a=10+5
>=a
15
There are a few limitations to interactive mode. Notably, each statement is executed as its own
Lua script; therefore local variables are not carried over to the next statement. The followin g
example illu strates this (bold indicates the output):
>local b=10
>print(b)
nil
>c=10
>print(c)
10
Another notable limitation is the inability to print tables.
There is no command to exit interactive mode. The user may exit interactive mode by simply
disconnecting from the scripting raw socket. When the user re-connects to the scripting raw
socket he/she will return to normal mode. Interactive mode is a great tool to learn and
experiment with the Lua langua ge; however most script development will be done by writing
scripts into files that are uploaded and run.
12
Page 19
3.0 DEVELOPING SCRIPTS
3.1 DEVELOPMENT SOFTWARE – EM405-8 IVI DRIVER SOFT FRONT PANEL
The EM405-8 IV I Driver Soft Front Panel contains a scripting panel that allows the user to
interface with the scripting utilities and provides tools to ease script development. A screenshot
of this scripting panel is shown in Figure 5. With this panel the user can interactively use and
manage the scripts. The panel provides the capability to, among others, upload, retrieve, run,
halt, and remove scripts. The panel also contains debug utilities that allow the user to run a
script in the scripting socket interface and view the script output in a standard command prompt.
Further, the panel allows the user to open a command prompt to the scripting socket interface
where he/she can directly input use and management commands.
The EM405-8 Extension Library is a set of functions in the form of a Lua library that can be
included and called from a Lua script like any of the standard Lua libraries. The functions in the
EM405-8 Extension Library allow a Lua script to utilize and interact with the EM405-8 utilities
and M-module hardware. Functions include the ability to read and write M-module registers,
configure the EM405-8 triggers, send and receive data via the VXI-11 interface, control the
EM405-8 fans, and read the EM405-8 temperature sensors.
13
Page 20
To use the Lua libraries simply require the library in the script as follows:
require “lua_em405”
Once the library is loaded any of the library functions are available for use in the script with the
following syntax:
lua_em405.function()
To further enhance readability, the library can be assigned to a local or global variable and the
library functions can be called with this variable as the prefix as in the following example. This
method will be used throughout this manual.
em405 = require “lua_em405”
em405.function()
Table II summarizes the functions that are in the EM405-8 Extensions Library. Details of each
function including a function description, va lid parameter ranges and return types follow the
table.
Numerical constants in the Lua language are written much like they are in ANS I-C. Examples of
numerical constants are:
7 7.893 756.87e-6 0.784e1 0x76
The detailed descriptions below follow the same conventions.
Table II. Functions in the EM405-8 Extensions Library
Function Description
clock Returns the number of clocks used by the process
clockspersec Returns the number of clocks per second
emclose Free resources allocated during library load
emfans Control the speed of the fans
emread Read an EM405-8 carrier control reg ister
emtemp Read an EM405-8 on-board temperature sensor
emwrite Write an EM405-8 carrier control register
input Input data to the script from the VXI-11 interface
mread Read an M-Module register
mreadblock Read a block of M-Module registers
mreadfifo Repeatedly read an M-Module register
mreadid Read the ID PROM of an M-Module
mwrite Write an M-Module register
mwriteblock Write a block of M-Module registers
mwritefifo Repeatedly write an M-Module register
output Output data to VXI-11 interface
usleep Sleep for specified microseconds
version Get the version of the EM405-8 Extension Library
14
Page 21
clock ()
Description: Returns an approximation of processor time used by the program. This function
call the ANSI-C function clock() in the C standard library. The time is returned
as the number of processor clocks. To convert to seconds use the value returned
by clockspersec(). The value is not guaranteed to start a 0 at boot-up or reset
therefore you should call clock() to get a starting value and use the difference to
get time elapsed.
Parameters: None
Return: clocks Integer value of the number of processor clocks
clockspersec ()
Description: Returns the number of processor clock in one second. This value can be used to
convert the result of clock() into seconds. The function returns the ANSI-C value
CLOCKS_PER_SEC.
Parameters: None
Return: clockspersec Integer value of the number of processor clocks per second
emclose ()
Description: This function must be called before exiting any script that loads the EM405-8
Extensions. It closes and frees resources that were allocated during library load.
Parameters: None
Return: None
emfans (full_on)
Description: Controls the speed of the EM405-8 fans. The fans can be full-on or variable
Parameters: full_on Integer with 1 = fan set to full-on and 0 = fan set to variable
Return: None
15
Page 22
status, value = emread (offset)
Description: Reads an EM405-8 control reg ister. These registers are shared between all M-
Modules and control the carrier utilities such as triggers and fans. Refer to the
EM405-8 User’s Manual for register details.
Parameters: offset Integer specifying the register offset to read
Return: status Integer indicating status of the read (0 = success)
value The integer value read from the register
temp = emtemp (sensor)
Description: Read one of three temperature sensor and return the result in degrees C
Parameters: sensor Integer indicating the temperature sensor to read.
0 = Fan Area, 1 = Logic Area, 2 = M-Module Area
Return: temp Real value of temperature in degrees C
status = emwrite (offset, value)
Description: Writes an EM405-8 control register. These registers are shared between all M-
Modules and control the carrier utilities such as triggers and fans. Refer to the
EM405-8 User’s Manual for register details.
Parameters: offset Integer specifying the register offset to read value Integer value to write to the register
Return: status Integer indicating status of the read (0 = success)
num_input, buffer = input (length)
Description: Inputs length bytes from the VXI-11 interface and returns the data in buffer. The
data may be ASCII or binary. Refer to section 3.3 for details passing data via the
VXI-11 interface.
Parameters: length Integer number of bytes from the buffer to be input
Return: num_input Integer number of bytes successfully input; 0 = no data is available.
buffer Buffer of data that is input from the VXI-11 interface
Note: Only one script at a time should attempt to input data from the VXI11 interface
16
Page 23
status, value = mread (module, width, offset)
Description: Reads an M-Module register from a specified M-Module position.
Parameters: module Integer indicating the M-Module position to read. (0 – 7)
width Integer specifying the access width in bytes
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to read. This value must be
bounded by the width parameter. For example, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
Return: status Integer status of the M-Module read (0 = success) value Integer value read from the M-Module register
status, buffer = mreadblock (module, width, offset, length)
Description: Read a block of M-Module registers from a specified M-Module position. The
function will read length words incrementing the address between each read
Parameters: module Integer indicating the M-Module position to read. (0 – 7) width Integer specifying the access width in bytes. This value also
determines the increment of the address for each read in the block.
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to read. This value must be
bounded by the width parameter. For example, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
length Integer indicating the number of words of size width to read.
Return: status Integer status of the block read (0=Success) buffer Buffer of data from the block read
17
Page 24
status, buffer = mreadfifo (module, width, offset, length)
Description: Read a single M-Module register repeatedly from a specified M-Module position.
The function will read length words from the specified offset without
incrementing the address between each read
Parameters: module Integer indicating the M-Module position to read. (0 – 7) width Integer specifying the access width in bytes.
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to read. This value must be
bounded by the width parameter. For example, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
length Integer indicating the number of words of size width to read.
Return: status Integer status of the FIFO read (0=Success)
buffer Buffer of data from the FIFO read
status, value = mreadid (module, word)
Description: Reads one 16-bit word of the specified M-Module’s ID PROM
Parameters: module Integer indicating the M-Module position to read. (0 – 7)
word Integer specifying the 16-bit word of the ID PROM to read (0 for
first 16-bit word, 1 for second 16-bit word and so forth)
Return: status Integer status of the ID read (0 = success) value Integer value read from the M-Module ID PROM
status = mwrite (module, width, offset, value)
Description: Writes an M-Module register to a specified M-Module position.
Parameters: module Integer indicating the M-Module position to write. (0 – 7)
width Integer specifying the access width in bytes
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to write. This value must be
bounded by the width parameter. For example, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
value Integer value to write to the M-Module register
Return: status Integer status of the M-Module read (0 = success)
18
Page 25
status = mwriteblock (module, width, offset, length, buffer)
Description: Write a block of M-Module registers to a specified M-Module position. The
function will write length words incrementing the address between each write
Parameters: module Integer indicating the M-Module position to write. (0 – 7) width Integer specifying the access width in bytes. This value also
determines the increment of the address for each read in the block.
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to write. This value must be
bounded by the width parameter. For example, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
length Integer indicating the number of words of size width to write.
buffer Buffer of data for the block write
Return: status Integer status of the block read (0=Success)
status = mwritefifo (module, width, offset, length, buffer)
Description: Write a single M-Module registers repeatedly to a specified M-Module position.
The function will write length words from the specified offset without
incrementing the address between each write
Parameters: module Integer indicating the M-Module position to write. (0 – 7) width Integer specifying the access width in bytes.
2 = 16-bit
4 = reserved for future use
offset Integer specifying the register offset to write. This value must be
bounded by the width parameter. For examp le, if width = 2 then this
value must be a multiple of 2 (0, 2, 4…). If width = 4 then this value
must be a multiple of 4 (0, 4, 8…). Valid values are 0 - 0xFF.
length Integer indicating the number of words of size width to write.
buffer Buffer of data for the FIFO write
Return: status Integer status of the FIFO read (0=Success)
num_output = output (buffer , length)
Description: Outputs length bytes to the VXI-11 interface from the data in buffer. The data
may be ASCII or binary. Refer to section 3.3 for details passing data via the
VXI-11 interface.
Parameters: length Integer number of bytes from the buffer to be output buffer Buffer of data that is output to the VXI-11 interface
Return: num_output Integer number of bytes successfully output
19
Page 26
version = version ()
Description: Get the version information of the EM405-8 Extension Library (this library).
Parameters: None
Return: version String describing the version of the library
usleep ()
Description: Suspend the thread for the specified number of microseconds. The library
function calls the Linux standard library function usleep(). Actual time slept may
be longer due to system latencies and limitations of the timer resolution of the
hardware.
Parameters: useconds Integer number of microseconds to sleep
Return: None
3.3 PASSING DATA
Data, including commands, can be passed to a script when a script is launched by simply placing
the data in the script arguments. But, what if we want to pass data to a script at some
indeterminate time after launch and what if the script wants to return data? The EM405-8
Extensions Library, discussed in section 3.1, provides both input and output utilities that allow
for data passing between the script and the host computer using the VXI-11 interface. For the
purpose of this discussion, the direction of data is in reference to the script. In other words, input
refers to passing data from host computer to the script and output refers to passing data from the
script to the host computer.
The EM405-8 extensions implement two FIFO’s for data passing, one for each direction. To
place data in the input FIFO, the host computer must send the data preceded by the *data
command via the VXI-11 interface. The *data command is discussed in section 2.1.2. For
example, to pass the string “Hello World” to a script, the host computer can perform a VISA call
as follo ws:
sprintf(string, “*data Hello World”);
viWrite(vi, strlen(string), string);
The data can be ASCII like the above example or binary like the following example that sends
binary 1, 2, 3, and 4.
Note: If a script is not running to accept that data, the VISA function viWrite will return an I/O
error.
To retrieve data from the input FIFO, the script must call the EM405-8 Extensions Library
function input. The EM405-8 Extensions Library functions are detailed in section 3.1. The
input function takes a single parameter specifying the number of bytes to input. The input
function is non-blocking meaning that if the specified number of bytes is not available in the
FIFO, the function will return anyway. In addition, being non-blocking also means that the
script must poll for input data either on a regular basis or when data is expected. The return
value of input specifies the number of bytes retrieved from the FIFO. There is only one input
FIFO, therefore only one script should input data at any given time. If more than one script calls
input at the same time, the behavior is indeterminate.
To output data from a script to the host computer, the script can use the EM405-8 Extensions
Library function output to place data into the output FIFO. The host computer can in-turn use
the VISA function viRead to retrieve the data from the output FIFO. Unlike input, more than
one script can output data to the VXI-11 interface; however, there is no built-in indication as to
which script a piece of data is from nor is there a defined delimiter to separate data from one
script with data from another script. All data is dumped into a singl e buffer to be read from the
host. It is guaranteed however, assuming no errors, that all data written within a single call to
em405.output will be contiguous in the buffer. With that said, there is nothing preventing the
scripts themselves from adding an ID tag and a delimiter to the data itself. In this case, it will be
up to the host application to parse the data. Also, in contrast to input, there is always something
(i.e. the VXI-11 firmware) waiting to retrieve data from the output FIFO, therefore the user may
call output at any time without error.
To illustrate data passing we have created an example script that simply retrieves data from the
VXI-11 interface using the input function then echo’s it back to the VXI-11 interface using the
output function. The Lua source code is found in Figure 6. The host side simply uses viWrite
to send the data and viRead to retrieve the echo.
em405 = require "lua_em405"
io.write("Echo Example\n")
io.write("VXI-11 data will be echoed via VXI-11\n")
io.flush()
while 1 do
num_read, buffer = em405.input(256)
if num_read > 0 then
em405.output(buffer, num_read);
end
end
Figure 6 Data Passing Example
21
Page 28
3.4 CALLING M-MODULE DR IVERS
The scripting utilities include a Lua library known as Alien that allows a Lua script to call
dynamic libraries (,so, dll, etc.). Using Alien, we can make calls to any of C&H Technologies’
standard M-Module drivers. Alien uses the Foreign Function Interface (FFI) library to
dynamically call shared library functions. Alien was written by a third party and like Lua, is
open source software.
The alternative to using Alien is to write a “wrapper” around the driver that makes the library a
native Lua component. Tools do exist that can automatically generate a wrapper however they
still require knowledge of Lua C components and the tools necessary to cross compile the source
code for ARM based Linux. By using Alien, we can utilize M-module drivers as-is without the
need of building more software.
The downside to using Alien is that ANSI-C code is inherently not “safe.” In other words, the
code can perform actions that result in undefined behaviors, such as dereferencing an invalid
address. In a C program or library this will result in a crash of the application. In contrast, Lua
is a safe language where no matter the code, the behavior is defined. Alien is written to be as
safe as possible; however it is still easy to crash Lua from within a library, thus, to avoid
frustration, care must be taken when calling drivers using Alien.
Crashes due to a misbehaving C library typically only occur during development. Once a
program is debugged, it is rare that a crash will occur. Recovering from a crash typically
involves rebooting or power-cycling the EM405-8. A system reboot can be performed remotely
via the EM405-8 webpage under the Status/Control link.
3.4.1 Using Alien to Call M-Module Drivers
The usage of Alien to call M-Module drivers can be divided into three basic steps:
1. Load the driver library
2. Define function prototypes for the functions to be called
3. Perform function calls.
To load a driver library from within a script, we must first load the Alien Lua module using the
require function like we would any other Lua library. In addition to the alien library, we may
also sometimes load a library called “alien.struct.” This library can be used to convert Lua
values to and from C structures. It is a good idea, in most cases, to require alien.struct by
default. Once Alien is loaded, we can use the alien.load function to load the M-Module
driver. The Lua source code below shows how to perform these steps. Note that there are
multiple ways to perform the same tasks in Lua source code. For clarity, we a have chosen to
present the most straight forward way.
Note that in the above example code, the path /usr/scripts/user/ is the absolute path of the
script pool where libm228.so will be uploaded. The absolute path must be specified for Alien to
find the shared library.
To use a function in the driver you first must tell Alien the function prototype of driver. This is
performed with the call lib.func:types(return_type, arg_types…). For each driver function that is
to be called. The types are specified as a string and can be any of the types specified in Table III.
Most correspond directly to C data types.
Table III. Alien Data Types
Alien Data Type C Data Type
“void” void
“int” int
“double” double
“char” char
“string” const char*
“pointer” void*
“ref int” int passed by reference
“ref double” double passed by reference
“ref char” char passed by reference
“callback” generic function pointer
“short” short
“byte” signed char
“long” long
“float float
The following example code illustrates how to define the function prototype of the M228 driver
initialize function whose C prototype is:
int m228_Init(int path, int id_query, int reset, M228_HANDLE *handle);
Note that in the below example, we create a variable of the same name as the C function that is
equal to lib.func. This is not required but makes for more readable code as from that point on,
the function can be called with the function name.
Function prototypes only need to be defined once and can be defined anywhere in the script as
long as it is before the function is called. With that said, it makes for more readable code if all
prototypes are defined in one section near the top of the code.
Once the prototype is defined the function can be called as follows:
You may find it strange that there are two variables specified on the left side of the equal sign.
The first variable is the return value of the function. The second and subsequent variables are the
return values of the parameters that are passed by reference. Alien supports by-reference types
by allocating space for the argument on the Lua stack then initializing this stack space to the Lua
number (typecasting where needed) specified in the function call (0 in the example above).
When the C library function returns, Alien takes the value and returns it (converting where
appropriate) after the functions normal return value.
To put this all together, the example source code in Figure 7 uses the M228 M-module driver to
read 20 locations of the M-modules ID PROM. This example uses three driver functions:
m228_Init, m228_GetIdentWord, and m228_Close. Note that these examples use the
m228_GetIdentWord function not the EM405-8 Extensions Library function mreadid. This
same example can be performed using just the EM405-8 Extensions Library. The example prints
a line to the standard output for each ID location indicating the ID address and the value read.
Note that the functions print and string.format are part of the Lua standard libraries.
require "alien"
require "alien.struct"
local libm228 = alien.load("/usr/scripts/user/libm228.so")
for offset=0, 19, 1
do
result, value = m228_GetIdentWord(handle, offset, 0)
print(string.format('0x%x: 0x%x', offset, value))
end
m228_Close(handle)
print("Done!")
24
Page 31
Figure 7 M-Module Driver Example Code
3.4.2 Dealing with data
The data types shown in Table III are straightforward and cover most function calls to MModule drivers. But there are M-Module driver function calls that, for example, require special
data types (C structures) or require the calling software to allocate memory that the driver then
modifies. In both cases, there are no data types in Table III to handle this type of data.
The Alien library provides a host of functions and utilities that can be used to deal with data
types not covered by the standard types shown in Table III. The following sections discuss the
functions and utilities that are most pertinent to M-Module Drivers. These sections are not
meant to replace Alien documentation which may include further details and a more complete
list of utilities.
3.4.2.1 Buffers
Alien buffers allow the script to allocate a block of memory that can then be passed to a function
in place of any string or pointer type. A buffer is a llocated with alien.buffer(). If nothing
is passed to alien.buffer() a buffer of default length is allocated. If a number is passed a
buffer of that length is allocated. If a string or userdata is passed to alien.buffer(), a buffer
will be allocated and initialized with a copy of the string or data. Once the driver function is
called, the function buf:tostring() can be called to retrieve the data from the buffer.
Individual bytes of the buffer can be accessed using buf[i] where i is 1-based not 0-based.
Further you can get or set non-byte values using the buf:get(offset, type) and buf:set(offset,
type). Note that the buf:get() and buf:set() the offset is 1-based and is in bytes not elements so if
the buffer has integers, their offsets are 1, 5, 9, etc. An example of using buffers in a M-Module
driver call is shown in Figure 8.
for offset=0, 256, 1
do
print(string.format('0x%x', raw_buff:get((i *
alien.sizeof("short")) + 1, "short"))
end
m228_Close(handle)
print("Done!")
Figure 8 M-Module Driver Example Using Buffers
3.4.2.2 Arrays
Alien arrays build upon buffers by adding an extra layer of safety and elements that describe the
array. The function alien.array(type, length) allocates an array where type is the Alien
type of the elements and length is the number of elements in the array. Once allocated, the user
may use arr.type to get the type of the elements, arr.length to get the number of elements in
the array, arr.size to get the size in bytes of each element and arr.buffer to get the
underlying buffer. The user can access the elements of an array directly with arr[i]. The
example in Figure 9, perform the same exact function as the example in Figure 8 but with arrays
instead of buffers.
26
Page 33
require "alien"
local libm228 = alien.load("/usr/scripts/user/libm228.so")
for offset=0, 256, 1
do
print(string.format('0x%x', raw_array[i])
end
m228_Close(handle)
print("Done!")
Figure 9 M-Module Driver Example Using Arrays
3.4.2.3 Pointer Unpackin g
Pointer can be de-referenced and converted to a Lua type using one of the functions
alien.tostring, alien.toint, alien.toshort, alien.tolong, alien.tofloat, and
alien.todouble. These functions should be used with care as they do not check whether the
dereference or the typecast is safe. More robust unpacking can be performed using the
alien.struct.unpack function.
3.4.2.4 Callback Functions
I some rare cases an M-Module driver will take a function pointer as a parameter and call that
function to perform a certain task. This is known as a callback function. Alien provides the
27
Page 34
function alien.callback() that lets the user create a callback by passing it the function and
prototype of the callback function. The function alien.callback() will return an object that
can be passed to any argument of callback type.
3.4.3 Building M-Module Drivers into a Linux Shared Library
In order for Alien to call a function within a M-Module driver, the driver must be built into a
Linux Shared Library (.so) file for the XSca le ARM processor on the EM405-8 and the file must
be hosted on the EM405-8. C&H Technologies, writes M-Module drivers in an architecture that
makes it easy to port the driver to various operating systems and processors (See the application
note titled M-Module Instrument Driver Architecture for details). Thus, it is easy to build one of
C&H’s M-Module drivers into a Linux shared library for the XScale ARM processor.
Instructions to do so are beyond the scope of this document. If an M-module’s driver is not
available as a Linux shared library then please contact C&H Technologies for assistance.
The Alien library is configured to look for dynamic libraries in the same location that scripts are
stored. Therefore hosting an M-module driver on the EM405-8 is as simple as uploading the
driver like any script using the upload command as detailed in section 2.1.10.
3.5 SHARING DATA BETWEEN SCRIPTS
Lua scripts have access to the complete set of Lua standard libraries and the EM405-8’s Linux
kernel upon which the Lua interpreter is running contains all the common utilities such as a file
system, messaging utilities including pipes and FIFO’s, and sockets. These utilities can be very
useful to pass data between independent scripts; however, the details of using the standard
utilities and recommendations as to which method is best to use are beyond the scope of this
document. The intent of this paragraph is simply to highlight that these utilities are available and
may be very useful to the system developer.
3.6 STARTUP SCRIPT
Upon bootup or system reset, the EM405-8 will search for a startup script named startup.lua in
the pool of user stored scripts. If startup.lua is found, the EM405-8 will automatically run this
script. This utility allows the system to run autonomously without the need for a host computer’s
intervention. In reality, this utility will allow the system to run without the network cable
plugged in for a long period of time.
The startup script can perform any task a normal script can perform, including, configuring
M-Modules, sending and receiving VXI-11 data, acquiring data, storing data to the mass storage
device, starting other scripts and so forth. In addition, the startup script is listed with the list
-r command and can be halted like any other script.
To utilize the startup script functionality, simply upload a script with the name startup.lua. Since
the script must be present at bootup, the startup script function requires the mass stora ge option
of the EM405-8 which provides non-volatile storage of scripts.
28
Page 35
3.7 USING THE MASS STORAGE DEVICE
In addition to providing non-volatile storage of scripts, the mass storage device (ordering option
-0003 only) provides the user with a large amount of non-volatile memory for storage of user
data. The EM405-8 system only uses the mass storag e device for the script pool. The remainder
of the device is available for user data.
Scripts can store and retrieve data to/from the mass storage device using the standard file I/O
functions found in the Lua I/O Library. The mass storage device is mapped to the directory
/media. A single subdirectory /media/scripts is created by the system for the script pool.
Care should be taken not to overwrite or erase the script pool. If desired, the user can create
subdirectories from the Interactive Mode of the scripting socket or from within a script using the
execute function in the Lua Operating System Library as show in the following example:
os.execute(“mkdir /media/userdir”)
29
Page 36
4.0 USING LUA TO WRITE CUSTOM WEB PAGES
Using Lua, the user may create custom web pages to be served by the EM405-8’s embedded web
server. In addition to creating the pages, themselves, the user can add links to the standard
navigation menu that is found on every one of the default web pages of the EM405-8. The
scripts that create the custom web pages have full access to the EM405-8 scripting utilities like
any standard script. Scripts can, among other things, configure hardware, retrieve status,
write/read files, and send/receive data.
Lua based web pages are called from a CGI executable that maps the standard console output
(stdout) to the requesting web browser. In other words, all standard output from the standard I/O
library functions such as print() and io.write() go directly to the web browser. Therefore, a
Lua script can create a webpage by simply outputting the HTML like the example in Figure 10.
Note that in the example in Figure 10, double square brackets ([[ & ]]) start and stop the print
statement instead of the standard double quotes (“). In Lua, double square brackets denote a
literal string where there are no special characters or escape sequences. This is especially useful
when using Lua to create a webpage as it allows the developer to input the HTML exactly as it
would be in a standard HTML file.
Unlike standard scripts, web-based scripts do not run in there own thread; therefore they must
not loop forever, nor can they be queried using list –r or halted. In fact, for most, if not all,
browsers, a webpage will not be displayed until the script is complete. If a script needs to be run
in a loop, the developer should use a Meta Refresh Tab to instruct the web browser to
automatically refresh the page (i.e. run the script) after a certain period of time.
4.1 URL OF SCRIPT BASED PAGES
As mentioned in section 4.0, Lua web page scripts are called from a CGI executable. This
executable is named script.cgi and takes the script filename as a parameter. There are actually
two locations of script.cgi one for public pages at /cgi-bin/script.cgi and one for private
password-protected pages at /cgi-bin/private/script.cgi. The script filename is passed to
script.cgi within the U RL using the standard name/value pair parameter passing.
30
Page 37
For example, if your script is named myscript.lua then the URL would be:
/cgi-bin/script.cgi?script=myscript.lua
or
/cgi-bin/private/script.cgi?script=myscript.lua
Of course, typing these URL’s directly into a browser would require the above to be preceded
with the IP address; however, these are the absolute paths from within the device itself and
therefore the paths that should be used for all links within the HTML.
The CGI executable script.cgi will search the standard pool of Lua scripts. Therefore, scripts
that create web pages will be intermixed with non-webpage scripts and the user may use the
standard upload command to store the script on the device.
Arguments to be passed to the script are also passed within the URL by adding a name/value pair
within the URL. Details on passing arguments to the script can be found in section 4.4.
4.2 ADDING A LINK TO THE C&H NAVIGATION MENU
The user can add links to the main navigation menu displayed on all C&H standard web pages
by simply creating a file named “web_navbar.lua” and adding links to this file. This file should
be uploaded to the standard script pool like any other script.
The navigation menu bar is an HTML table with each link in a separate row. To add a link,
“web_navbar.lua” must include the HTML to create a new row. The example in Figure 11
illustrates how to add two links to the navigation menu.
print([[
<tr><td align=”left” bgcolor=”EFEFEF”>
<a href=”/cgi-bin/script.cgi?script=myscript.lua”>
My Page
</a>
</td></tr>
<tr><td align=”left” bgcolor=”EFEFEF”>
<a href=”/cgi-bin/script.cgi?script=myscript_2.lua”>
My Page #2
</a>
</td></tr>
]])
Figure 11 Example Adding Link to the Navigation Menu
31
Page 38
4.3 URL OF PICTURES AND OTHER SUPPORTING FILES
Sometimes a script based webpage will need to link to other supporting files such as graphics
and images. A directory name scripts on the root level of the URL is provided to give the user a
location for supporting files.
In reality, /scripts is simply a symbolic link to the standard pool of scripts in which all scripts are
stored. Therefore, the user may simp ly store images or other supporting files like he/she would
scripts and link to them with the URL /scripts/user/file.
The example in Figure 12, shows the script for a webpage that links to an image names logo.jpg.
The user must upload both this script and the image logo.jpg for the webpage created by this
script to display properly.
print([[
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
Arguments are passed to the script via URL by simply adding name/value pairs to the URL. For
example:
/cgi-bin/script.cgi?script=myscript.lua&arg1=val1&arg2=val2
In the above example, the script receives the arguments val1 and val2. The labels (arg1 and
arg2) are discarded before running the script therefore they may be any identifier. Also, because
the labels are discarded, the order of the arguments is important as the script has no way to
identify an argument other than the order in which it was received.
Arguments are received by the script in the same manner is if the script was called from the
command line. When a script is called, a Lua table named arg is defined and populated with the
arguments. Table item arg[0] contains the name of the script. The arguments are placed in
arg[1], arg[2] and so forth in the order in which they appear in the URL.
Figure 13 illustrates the Lua source code required to retrieve the arguments. In this example, the
table arg is printed to the webpage as the index followed by the argument.
32
Page 39
print([[
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
]])
for i=0, table.getn(arg) do
print(i,arg[i])
print("<br>")
end
Figure 13 Example Retrieving Arguments from the URL
4.5 DEVELOPING THE PAGE CONTENT
The user may customize the webpage to look however he/she likes by creating the entire HTML
content. Alternatively, the user can maintain the EM405-8 default look and feel of the webpage
by using the l_em405web.lua Lua library. This library contains a set of functions that can be
used to generate the main HTML structure that is used in the EM405-8’s default pages. By using
this library, the developer needs only to concentrate on the added content of the custom page.
The library l_em405web.lua includes four functions as summarized in Table IV. Details of each
function follow the table.
Table IV l_em405web.lua Library Functions
Function Description
Top Create the HTML header info and display the top banner
Bottom Display the bottom banner & close the HTML
Contents_Pre Setup a nested table including the navigation menu
Contents_Post Close the nested table
33
Page 40
Top(refresh, refresh_time, refresh_url)
Description: This function creates the HTML header information and displays the top banner
including the C&H logo and banner graphic. The parameter allow the user to
control the Refresh Meta Tag.
Parameters: refresh 1 or 0 indicating whether or not to include the Refresh Meta tag in
the HTML header
refresh_time The refresh time placed in the CONTENT section of the Refresh
Meta Tag. This is the number of seconds to wait before the
browser should refresh the page.
refresh_url The URL that the page load when the refresh time is complete.
This allows the page to redirect to a different URL. Pass an empty
string to this parameter to refresh to the same URL.
Bottom()
Description: This function display the bottom banner and closes the page with the </body> and
</html> tags.
Parameters: None
Contents_Pre()
Description: This function creates a nested table that includes the navigation menu and the
page content. This function leaves the table open so that the user may insert
his/her content. The last html tag output by this function is a <td>. The user can
follow this function with his/her content then close th <td> tag the table by calling
the function Contents_Post().
Note: The user may call Top() and Bottom() without calling Contents_Pre()
Contents_Post() since Top() does not leave any HT ML tags open.
Parameters: None
34
Page 41
Contents_Post()
Description: This function closes the <td> tag left open by Contents_Pre() and then
subsequently closes the nested table. The user should always call Contents_Post()
if Contents_Pre() was used before the page content. The first HTML tag output
by this function is </td>.
Note: The user may call Top() and Bottom() without calling Contents_Pre()
Contents_Post() since Top() does not leave any HT ML tags open.
Parameters: None
As discussed in the above descriptions, the l_em405web.lua functions create a nested table with
the user content being one table cell. The best way to learn the effects of using the
l_em405web.lua library is to add them to your script, load the page in a web browser then view
the source using the browsers utility to view source.
Figure 14 shows an example web page using the l_em405web.lua library. This example
performs the same function as the example in Figure 13; however it uses the l_em405web.lua
library instead of explicitly outputting the full HTML.
em405web = require "l_em405web"
em405web.Top(0,0,"")
em405web.Contents_Pre()
-- Contents Begin Here -for i=0, table.getn(arg) do
print(i,arg[i])
print("<br>")
end
-- Contents End Here --
em405web.Contents_Post()
em405web.Bottom()
Figure 14 Example Using “l_em405web.lua” Library
It is highly recommended that you use the W3C Markup Validation Service to validate you
HTML. This is a free utility available at: http://validator.w3.org/. By validating your HTML,
you are ensuring that is will be properly displayed on any W3C compliant web browser.
35
Page 42
Page 43
N O T E S:
Page 44
.
Page 45
READER'S COMMENT FORM
Your comments assist us in improving the usefulness of C&H's publications; they are an
important part of the inputs used for revision.
C&H Technologies, Inc. may use and distribute any of the information that you supply in any
way that it believes to be appropriate without incurring any obligation whatsoever. You may, of
course, continue to use the information, which you supply.
Please refrain from using this form for technical questions or for requests for additional
publications; this will only delay the response. Instead, please direct your technical questions to
your authorized C&H representative.
COMMENTS:
Thank you for helping C&H to deliver the best possible product. Your support is appreciated.
Sincerely,
F. R. Harrison
President and CEO
Page 46
INSTRUCTIONS
In its continuing effort to improve documentation, C&H Technologies, Inc. provides this form
for use in submitting any comments or suggestions that the user may have. This form may be
detached, folded along the lines indicated, taped along the loose edge (DO NOT STAPLE), and
mailed. Please try to be as specific as possible and reference applicable sections of the manual or
drawings if appropriate. Also, indicate if you would like an acknowledgment mailed to you
stating whether or not your comments were being incorporated.
NOTE: This form may not be used to request copies of documents or to request
waivers, deviations, or clarification of specification requirements on current
contracts. Comments submitted on this form do not constitute or imply
authorization to waive any portion of the referenced document(s) or to amend
contractual requirements.
(Fold along this line)
(Fold along this line)