%CopyrightBegin% Copyright Ericsson AB 1997-2009. All Rights Reserved. The contents of this file are subject to the Erlang Public License, Version 1.1, (the "License"); you may not use this file except in compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. %CopyrightEnd% ----------------------------------------------------------------------- README, Erlang/OTP R11B for VxWorks on PPC860 and PPC603 ----------------------------------------------------------------------- 20060515 -- Patrik Nyblom, support@erlang.ericsson.se R11B is a libraries only release for VxWorks. Only the libraries of erl_interface (ei+erl_inteface) and ic are expected to be used. Still the whole erlang system is distributed, although no support will be given for anything else but the libraries. The information in this file still applies to the full erlang distribution and parts of it are therefore somewhat irrelevant to commercial users. Included OTP applications ------------------------- appmon asn1 compiler cosEvent cosNotification cosTime cosTransaction debugger erl_interface erts eva [1] ic inets [2] jinterface kernel mesh mnemosyne mnesia [1] mnesia_session orber os_mon pman runtime_tools sasl snmp stdlib tools tv [1] Only ram_copies work, The VxWorks filesystems are not reliable enough for disk_copies to be fully supported. [2] CGI scripts do not work on VxWorks. Omitted applications -------------------- crypto emacs etk gs odbc parsetools toolbar ssl megaco webtools As `crypto' and `ssl' provides cryptographic functionality to `inets' and `snmp', the latter applications will not handle cryptography on VxWorks. Graphical interfaces -------------------- For applications using graphical interfaces, only the backend part works. Compilers --------- All compilers are expected to be run on a cross host. The VxWorks systems memory capabilities are too restricting to allow native compiling. The expected host system is a Sun Solaris machine, although Erlang compilation may be done on most platforms. Supported boards and configuration (only libraries supported) ---------------------------------- The following boards and configurations are supported: * Force PowerCore 603 with Force pcore603 BSP and VxWorks 3.5.1 (no SENS or SENS 1.1 + SPR23938) and a minimum of 32 Mb memory. * Force Powercore 750 with Force pcore750 BSP and VxWorks 3.5.1 (no SENS or SENS 1.1 + SPR23938) and a minimum of 32 Mb memory. * PSS Core PPC860 processors, only erl_interface (too small main memory). Most PowerPC boards with FPU are expected to work, but will need to be tested by OTP to be fully supported. The PPC603 build has been compiled with Wind River's `-mlongcall' flag (SPR25893) to support arbitrary function calls across more than 32 MB of memory. The PPC860 (PowerQuicc) has no FPU and requires a separate build. For Erlang to run, the Wind kernel has to be configured with a minimum of these variables defined in config.h (or by the Tornado configuration tool): INCLUDE_ANSI_ALL INCLUDE_ENV_VARS INCLUDE_EXC_HANDLING INCLUDE_EXC_TASK INCLUDE_FLOATING_POINT INCLUDE_FORMATTED_IO INCLUDE_IO_SYSTEM INCLUDE_LOADER INCLUDE_NETWORK INCLUDE_NET_INIT INCLUDE_NET_SHOW INCLUDE_NET_SYM_TBL or INCLUDE_STANDALONE_SYM_TBL INCLUDE_PIPES INCLUDE_POSIX_FTRUNC INCLUDE_RLOGIN or INCLUDE_TELNET (for pty's only) INCLUDE_SELECT INCLUDE_SEM_BINARY INCLUDE_SEM_COUNTING INCLUDE_SEM_MUTEX INCLUDE_SHELL (*) INCLUDE_SHOW_ROUTINES INCLUDE_SIGNALS INCLUDE_STARTUP_SCRIPT (*) INCLUDE_STDIO INCLUDE_SYM_TBL INCLUDE_TASK_HOOKS INCLUDE_TASK_VARS INCLUDE_TTY_DEV INCLUDE_UNLOADER INCLUDE_NFS or INCLUDE_RAMDRV or INCLUDE_DOSFS (i.e. a file system, possibly read-only) (**) (*) Needed for the example startup script, not actually needed in production if erlang is set up by a c routine called from usrConfig.c. (**) INCLUDE_NFS usually requires the NFS_USER_ID and NFS_GROUP_ID variables to be set in config.h As an erlang system may open a lot of files, it is recommended to raise the default NUM_FILES variable to something like 256 in config.h like this: #ifdef NUM_FILES #undef NUM_FILES #endif #define NUM_FILES 256 The SENS stack *has* to be of version 1.1 or higher, 1.0 is *not* supported and will not work reliably. Upgrades as well as the patch for SPR23938 can be found at www.wrs.com (i.e. WindSurf). Also, the following constants in $WIND_BASE/target/h/netBufLib.h has to be raised to a value of at least four times the default: NUM_NET_MBLKS NUM_64 NUM_128 NUM_256 NUM_512 NUM_1024 NUM_2048 NUM_SYS_64 NUM_SYS_128 NUM_SYS_256 NUM_SYS_512 Use the show routines mbufShow and netStackSysPoolShow to verify that these pools are not exhausted. Installation ------------ To install Erlang on a VxWorks card, the following knowledge is expected: * VxWorks installation and configuration. * Network (TCP/IP) configuration. * Erlang basic operation and configuration. There is no specific install script for erlang on the VxWorks platform. There is however an example VxWorks startup file named erts-5.0.1/bin/erl_script.sam under the root of an unpacked release. There may of course be other things to do in the start script, like using the rdate program in the erlang distribution to get a correct date and set the TIMEZONE variable. Please consult the "Embedded System" documentation for further information on installation. Known Bugs and problems ----------------------- We have found the VxWorks/NFS client file system to be unreliable. Important file operations like rename, ftruncate, cd and unlink doesn't always work as expected. Therefore more complex file using parts of OTP, like DETS and disk based mnesia tables cannot be used reliably with NFS. Lowering the NFS cache size (global variable nfsCacheSize) to 512 gives a more reliable NFS client, but to disk base the mnesia tables over NFS is still not a good idea, especially as disk based mnesia tables are not supported on VxWorks. Another problem with VxWorks file systems is that the error codes they produce are not consistent. We have worked around this problem by mapping the codes to POSIX ones, by doing this we make the VxWorks Erlang platform behave similarly to the UNIX and Windows implementations. The rename and ftruncate operations over NFS are emulated using copying of files. This is mainly for our own test suites and it is not recommended to use file:rename and/or file:ftruncate on NFS file systems in production. Floating point operations is somewhat faulty. For instance, testing floating point numbers for equality should be done with care. This is actually not a bug, IEEE specifies no equality among floating point numbers. Memory handling --------------- Please read the erl_set_memory_block(3) manual page in the ERTS documentation for information concerning memory handling in the erlang emulator. Also please observe that reclaim.o has to be loaded and reclaim_init() called before any other erlang routines are loaded and started. If one wish to use the resource reclamation routines in other programs, refer to the header file in `erts-5.0.1/include/reclaim.h'. Including that file in your C source makes malloc/realloc/free and open/fopen/socket/close etc be redefined to routines that makes the memory and files be free'd/closed when the task exits. Still, reclaim_init() *has* to be called before any program that uses this is started. Using heart ----------- The default behavior of the heart object file that is part of the distribution is that it reboots the target when the Erlang process hasn't given it a heart beat in 60 seconds. The normal heart beat rate is one beat per five seconds. This makes an effective "software watchdog" but there is really no substitute for the real thing --- a hardware watchdog. If you want to add a hardware watchdog to the system please contact us for directions. If you want to disable the reboot you may set the environment variable HEART_DONT_REBOOT (see the example erlang start script, erl). Please note that if you DO want the card to reboot you mustn't define HEART_DONT_REBOOT at all. E.g. to disable heart reboot you may include the following line in the start script (as is indeed the case with the example start script). putenv "HEART_DONT_REBOOT=1" A few words on writing port program and dynamically loaded drivers for VxWorks ------------------------------------------------------------------------------ VxWorks has one name-space for all symbols. This makes it harder to write C programs whose global symbols doesn't interfere with each other. It is a good rule to avoid all globally visible symbols that are not absolutely necessary. Due to these facts we use the following naming rules that are crucial to follow. (there are more issues involved but the issues described here is a good beginning). Port programs must have a function with the same name as the object file. E.g. if you have an object file named `port_test.o' it must contain a globally visible function named `port_test'. This is the function that will be called when you output data from Erlang to the port. (The object file, in this example, should be named `port_test.o', but `port_test' will also do). Also, in an embedded system, it is recommended to load the port program into the system before the port program is used. This is to avoid the real time degradation dynamical linking in runtime would introduce. Use VxWorks command ld < "port_prg" to accomplish this. Dynamically linked drivers must have a function with the same name as the object file with the added suffix `_init'. We recommend the use of the macro DRIVER_INIT in `driver.h'. E.g. if you have an object file named `echo_drv.eld' it must contain a globally visible function `echo_drv_init'. (The object file, in this example, should be named `echo_drv.eld' (`eld' is short for Erlang Loadable Driver), but `echo_drv.o' and `echo_drv' will both also do). It is also very important to initialize all unused function pointer in the `driver_entry' struct to NULL (see example below). Example of dynamically linked driver ------------------------------------ #include #include "driver.h" static int erlang_port; static long echo_start(); static int echo_stop(), echo_read(); static struct driver_entry echo_driver_entry = { null_func, echo_start, echo_stop, echo_read, null_func, null_func, "echo_drv", null_func }; int DRIVER_INIT(echo_drv)(void *handle) { erlang_port = -1; echo_driver_entry.handle = handle; return (int) &echo_driver_entry; } static long echo_start(long port,char *buf) { if (erlang_port != -1) { return -1; } erlang_port = port; return port; } static int echo_read(long port, char *buf, int count) { return driver_output(erlang_port, buf, count); } static int echo_stop() { return erlang_port = -1; }