Structural changes to create ca module

This commit is contained in:
Ralph Lange
2017-09-19 17:02:36 +02:00
parent c036fd056b
commit c55fb421ce
1766 changed files with 146 additions and 243428 deletions
+11
View File
@@ -0,0 +1,11 @@
TOP=../..
include $(TOP)/configure/CONFIG
TEMPLATES_DIR = makeBaseApp
TEMPLATES += top/caClientApp/Makefile
TEMPLATES += top/caClientApp/caExample.c
TEMPLATES += top/caClientApp/caMonitor.c
include $(TOP)/configure/RULES
-99
View File
@@ -1,99 +0,0 @@
TOP=../../..
include $(TOP)/configure/CONFIG
TEMPLATES_DIR = makeBaseApp
TEMPLATES += top/Makefile
TEMPLATES += top/configure/CONFIG
TEMPLATES += top/configure/CONFIG_SITE
TEMPLATES += top/configure/Makefile
TEMPLATES += top/configure/RELEASE
TEMPLATES += top/configure/RULES
TEMPLATES += top/configure/RULES.ioc
TEMPLATES += top/configure/RULES_DIRS
TEMPLATES += top/configure/RULES_TOP
TEMPLATES += top/supportApp/Makefile
TEMPLATES += top/supportApp/Db/Makefile
TEMPLATES += top/supportApp/src/Makefile
TEMPLATES += top/supportApp/src/_APPNAME_.dbd
TEMPLATES += top/iocApp/Makefile
TEMPLATES += top/iocApp/Db/Makefile
TEMPLATES += top/iocApp/src/Makefile
TEMPLATES += top/iocApp/src/_APPNAME_Main.cpp
TEMPLATES += top/exampleApp/Makefile
TEMPLATES += top/exampleApp/Db/Makefile
TEMPLATES += top/exampleApp/Db/dbExample1.db
TEMPLATES += top/exampleApp/Db/dbExample2.db
TEMPLATES += top/exampleApp/Db/_APPNAME_Version.db
TEMPLATES += top/exampleApp/Db/dbSubExample.db
TEMPLATES += top/exampleApp/Db/user.substitutions
TEMPLATES += top/exampleApp/src/Makefile
TEMPLATES += top/exampleApp/src/dev_APPNAME_Version.c
TEMPLATES += top/exampleApp/src/dev_APPNAME_Version.dbd
TEMPLATES += top/exampleApp/src/xxxRecord.dbd
TEMPLATES += top/exampleApp/src/xxxRecord.c
TEMPLATES += top/exampleApp/src/devXxxSoft.c
TEMPLATES += top/exampleApp/src/xxxSupport.dbd
TEMPLATES += top/exampleApp/src/sncExample.stt
TEMPLATES += top/exampleApp/src/sncProgram.st
TEMPLATES += top/exampleApp/src/sncExample.dbd
TEMPLATES += top/exampleApp/src/dbSubExample.c
TEMPLATES += top/exampleApp/src/dbSubExample.dbd
TEMPLATES += top/exampleApp/src/_APPNAME_Main.cpp
TEMPLATES += top/exampleApp/src/_APPNAME_Hello.c
TEMPLATES += top/exampleApp/src/_APPNAME_Hello.dbd
TEMPLATES += top/exampleApp/src/initTrace.c
TEMPLATES += top/exampleApp/src/initTrace.dbd
TEMPLATES += top/exampleBoot/Makefile
TEMPLATES += top/exampleBoot/nfsCommands@vxWorks
TEMPLATES += top/exampleBoot/nfsCommands@RTEMS
TEMPLATES += top/exampleBoot/ioc/Makefile@Common
TEMPLATES += top/exampleBoot/ioc/Makefile@vxWorks
TEMPLATES += top/exampleBoot/ioc/Makefile@win32
TEMPLATES += top/exampleBoot/ioc/Makefile@windows
TEMPLATES += top/exampleBoot/ioc/Makefile@cygwin
TEMPLATES += top/exampleBoot/ioc/st.cmd@Common
TEMPLATES += top/exampleBoot/ioc/st.cmd@vxWorks
TEMPLATES += top/exampleBoot/ioc/st.cmd@RTEMS
TEMPLATES += top/exampleBoot/ioc/README@Common
TEMPLATES += top/exampleBoot/ioc/README@vxWorks
TEMPLATES += top/caClientApp/Makefile
TEMPLATES += top/caClientApp/caExample.c
TEMPLATES += top/caClientApp/caMonitor.c
TEMPLATES += top/caServerApp/Makefile
TEMPLATES += top/caServerApp/README
TEMPLATES += top/caServerApp/exAsyncPV.cc
TEMPLATES += top/caServerApp/exChannel.cc
TEMPLATES += top/caServerApp/exPV.cc
TEMPLATES += top/caServerApp/exScalarPV.cc
TEMPLATES += top/caServerApp/exServer.cc
TEMPLATES += top/caServerApp/exServer.h
TEMPLATES += top/caServerApp/exVectorPV.cc
TEMPLATES += top/caServerApp/main.cc
TEMPLATES += top/caServerApp/test.adl
TEMPLATES += top/caServerApp/vxEntry.cc
TEMPLATES += top/iocBoot/Makefile
TEMPLATES += top/iocBoot/nfsCommands@vxWorks
TEMPLATES += top/iocBoot/nfsCommands@RTEMS
TEMPLATES += top/iocBoot/ioc/Makefile@Common
TEMPLATES += top/iocBoot/ioc/Makefile@vxWorks
TEMPLATES += top/iocBoot/ioc/Makefile@win32
TEMPLATES += top/iocBoot/ioc/Makefile@windows
TEMPLATES += top/iocBoot/ioc/Makefile@cygwin
TEMPLATES += top/iocBoot/ioc/st.cmd@Common
TEMPLATES += top/iocBoot/ioc/st.cmd@Cross
TEMPLATES += top/iocBoot/ioc/st.cmd@vxWorks
TEMPLATES += top/iocBoot/ioc/st.cmd@RTEMS
SCRIPTS_HOST += makeBaseApp.pl
include $(TOP)/configure/RULES
-432
View File
@@ -1,432 +0,0 @@
#!/usr/bin/env perl
# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson
use FindBin qw($Bin);
use lib ("$Bin/../../lib/perl", $Bin);
use Cwd;
use Getopt::Std;
use File::Find;
use File::Path 'mkpath';
use EPICS::Path;
use EPICS::Release;
$app_top = cwd();
%release = (TOP => $app_top);
@apps = (TOP);
$bad_ident_chars = '[^0-9A-Za-z_]';
readReleaseFiles("configure/RELEASE", \%release, \@apps);
expandRelease(\%release);
get_commandline_opts(); # Check command-line options
GetUser(); # Ensure we know who's in charge
#
# Declare two default callback routines for file copy plus two
# hook routines to add conversions
# These may be overriden within $top/$apptypename/Replace.pl
# First: the hooks
sub ReplaceFilenameHook { return $_[0]; }
sub ReplaceLineHook { return $_[0]; }
# ReplaceFilename
# called with the source (template) file or directory name, returns
# the target file/dir name (current directory is the application top).
# Inside iocBoot, templates can install different files for different
# IOC architectures or OSs: 'name@<arch>', 'name@<os>' & 'name@Common'
# The best match is installed as 'name', but if the best matching file
# is empty then no file is created, allowing a file 'name@Common' to
# be omitted by providing an empty 'name@<arch>' or 'name@<os>'.
# Returning an empty string means don't copy this file.
sub ReplaceFilename { # (filename)
my($file) = $_[0];
$file =~ s|.*/CVS/?.*||; # Ignore CVS files and Replace.pl scripts
$file =~ s|.*/$apptypename/Replace\.pl$||;
if($opt_i) {
# Handle name@arch stuff, copy only the closest matching file
# NB: Won't work with directories, don't use '@' in a directory name!
my($base,$filearch) = split /@/, $file;
if ($base ne $file) { # This file is arch-specific
my($os,$cpu,$toolset) = split /-/, $arch, 3;
if (-r "$base\@$arch") { # A version exists for this arch
$base = '' unless ($filearch eq $arch && -s $file);
} elsif (-r "$base\@$os") { # A version exists for this os
$base = '' unless ($filearch eq $os && -s $file);
} elsif ( $ENV{EPICS_HOST_ARCH} !~ "$os-$cpu" &&
-r "$base\@Cross" ) { # Cross version exists
$base = '' unless ($filearch eq "Cross" && -s $file);
} elsif (-r "$base\@Common") { # Default version exists
$base = '' unless ($filearch eq "Common" && -s $file);
} else { # No default version
$base = '';
}
$file = $base; # Strip the @... part from the target name
}
$file =~ s|/$apptypename|/iocBoot|; # templateBoot => iocBoot
}
if ($ioc) {
$file =~ s|/iocBoot/ioc|/iocBoot/$ioc|; # name the ioc subdirectory
$file =~ s|_IOC_|$ioc|;
} else {
$file =~ s|.*/iocBoot/ioc/?.*||; # Not doing IOCs here
}
if ($app) {
$file =~ s|/$apptypename|/$appdir|; # templateApp => namedApp
$file =~ s|/$appdir/configure|/configure/$apptype|;
}
$file =~ s|_APPNAME_|$appname|;
$file =~ s|_APPTYPE_|$apptype|;
my $qmtop = quotemeta($top);
$file =~ s|$qmtop/||; # Change to the target location
$file = ReplaceFilenameHook($file); # Call the apptype's hook
return $file;
}
# ReplaceLine
# called with one line of a file, returns the line after replacing
# this and that
sub ReplaceLine { # (line)
my($line) = $_[0];
$line =~ s/_IOC_/$ioc/g if ($ioc);
$line =~ s/_USER_/$user/go;
$line =~ s/_EPICS_BASE_/$app_epics_base/go;
$line =~ s/_TEMPLATE_TOP_/$app_template_top/go;
$line =~ s/_TOP_/$app_top/go;
$line =~ s/_APPNAME_/$appname/g;
$line =~ s/_CSAFEAPPNAME_/$csafeappname/g;
$line =~ s/_APPTYPE_/$apptype/go;
$line =~ s/_ARCH_/$arch/go if ($opt_i);
$line = ReplaceLineHook($line); # Call the apptype's hook
return $line;
}
# Source replace overrides for file copy
if (-r "$top/$apptypename/Replace.pl") {
require "$top/$apptypename/Replace.pl";
}
#
# Copy files and dirs from <top> (other than App & Boot) if not present
#
opendir TOPDIR, "$top" or die "Can't open $top: $!";
foreach $f ( grep !/^\.\.?$|^[^\/]*(App|Boot)/, readdir TOPDIR ) {
find({wanted => \&FCopyTree, follow => 1}, "$top/$f") unless (-e "$f");
}
closedir TOPDIR;
#
# Create ioc directories
#
if ($opt_i) {
find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename");
$appname=$appnameIn if $appnameIn;
foreach $ioc ( @names ) {
($appname = $ioc) =~ s/App$// if !$appnameIn;
($csafeappname = $appname) =~ s/$bad_ident_chars/_/og;
$ioc = "ioc" . $ioc unless ($ioc =~ m/ioc/);
if (-d "iocBoot/$ioc") {
print "iocBoot/$ioc exists, not modified.\n";
next;
}
find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename/ioc");
}
exit 0; # finished here for -i (no xxxApps)
}
#
# Create app directories (if any names given)
#
foreach $app ( @names ) {
($appname = $app) =~ s/App$//;
($csafeappname = $appname) =~ s/$bad_ident_chars/_/og;
$appdir = $appname . "App";
if (-d "$appdir") {
print "$appname exists, not modified.\n";
next;
}
print "Creating $appname from template type $apptypename\n" if $opt_d;
find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename/");
}
exit 0; # END OF SCRIPT
#
# Get commandline options and check for validity
#
sub get_commandline_opts { #no args
getopts("a:b:dhilp:T:t:u:") or Cleanup(1);
# Options help
Cleanup(0) if $opt_h;
# Locate epics_base
my ($command) = UnixPath($0);
if ($opt_b) { # first choice is -b base
$epics_base = UnixPath($opt_b);
} elsif ($release{"EPICS_BASE"}) { # second choice is configure/RELEASE
$epics_base = UnixPath($release{"EPICS_BASE"});
$epics_base =~s|^\$\(TOP\)/||;
} elsif ($ENV{EPICS_MBA_BASE}) { # third choice is env var EPICS_MBA_BASE
$epics_base = UnixPath($ENV{EPICS_MBA_BASE});
} elsif ($command =~ m|/bin/|) { # assume script was run with full path to base
$epics_base = $command;
$epics_base =~ s|^(.*)/bin/.*makeBaseApp.*|$1|;
}
$epics_base and -d "$epics_base" or Cleanup(1, "Can't find EPICS base");
$app_epics_base = LocalPath($epics_base);
$app_epics_base =~ s|^\.\.|\$(TOP)/..|;
# Locate template top directory
if ($opt_T) { # first choice is -T templ-top
$top = UnixPath($opt_T);
} elsif ($release{"TEMPLATE_TOP"}) { # second choice is configure/RELEASE
$top = UnixPath($release{"TEMPLATE_TOP"});
$top =~s|^\$\(EPICS_BASE\)|$epics_base|;
$top =~s|^\$\(TOP\)/||;
}
$top = $ENV{EPICS_MBA_TEMPLATE_TOP} unless $top && -d $top; # third choice is env var
$top = $epics_base . "/templates/makeBaseApp/top" unless $top && -d $top; # final
$top and -d "$top" or Cleanup(1, "Can't find template top directory");
$app_template_top = LocalPath($top);
$app_template_top =~s|^\.\.|\$(TOP)/..|;
$app_template_top =~s|^$epics_base/|\$\(EPICS_BASE\)/|;
# Print application type list?
if ($opt_l) {
ListAppTypes();
exit 0; # finished for -l command
}
if (!@ARGV){
if ($opt_t) {
if ($opt_i) {
my @iocs = map {s/iocBoot\///; $_} glob 'iocBoot/ioc*';
if (@iocs) {
print "The following IOCs already exist here:\n",
map {" $_\n"} @iocs;
}
print "Name the IOC(s) to be created.\n",
"Names given will have \"ioc\" prepended to them.\n",
"IOC names? ";
} else {
print "Name the application(s) to be created.\n",
"Names given will have \"App\" appended to them.\n",
"Application names? ";
}
$namelist = <STDIN>;
chomp($namelist);
@names = split /[\s,]/, $namelist;
} else {
Cleanup(1);
}
} else {
@names = @ARGV;
}
# ioc architecture and application name
if ($opt_i && @names) {
# ioc architecture
opendir BINDIR, "$epics_base/bin" or die "Can't open $epics_base/bin: $!";
my @archs = grep !/^\./, readdir BINDIR; # exclude .files
closedir BINDIR;
if ($opt_a) {
$arch = $opt_a;
} elsif (@archs == 1) {
$arch = $archs[0];
print "Using target architecture $arch (only one available)\n";
} else {
print "The following target architectures are available in base:\n";
foreach $arch (@archs) {
print " $arch\n";
}
print "What architecture do you want to use? ";
$arch = <STDIN>;
chomp($arch);
}
grep /^$arch$/, @archs or Cleanup(1, "Target architecture $arch not available");
# Application name
if ($opt_p){
$appnameIn = $opt_p if ($opt_p);
} else {
my @apps = glob '*App';
if (@apps) {
print "The following applications are available:\n",
map {s/App$//; " $_\n"} @apps;
}
print "What application should the IOC(s) boot?\n",
"The default uses the IOC's name, even if not listed above.\n",
"Application name? ";
$appnameIn = <STDIN>;
chomp($appnameIn);
}
}
# Application type
$appext = $opt_i ? "Boot" : "App";
if ($opt_t) { # first choice is -t type
$apptype = $opt_t;
$apptype =~ s/$appext$//;
} elsif ($ENV{EPICS_MBA_DEF_APP_TYPE}) { # second choice is environment var
$apptype = $ENV{EPICS_MBA_DEF_APP_TYPE};
$apptype =~ s/(App)|(Boot)$//;
} elsif (-d "$top/default$appext") { # third choice is default
$apptype = "default";
} elsif (-d "$top/example$appext") { # fourth choice is example
$apptype = "example";
}
$apptype or Cleanup(1, "No application type set");
$apptypename = $apptype . $appext;
(-r "$top/$apptypename") or
Cleanup(1, "Can't access template directory '$top/$apptypename'.\n");
print "\nCommand line / environment options validated:\n"
. " Templ-Top: $top\n"
. "Templ-Type: $apptype\n"
. "Templ-Name: $apptypename\n"
. " opt_i: $opt_i\n"
. " arch: $arch\n"
. "EPICS-Base: $epics_base\n\n" if $opt_d;
}
#
# List application types
#
sub ListAppTypes { # no args
opendir TYPES, "$top" or die "Can't open $top: $!";
my @allfiles = readdir TYPES;
closedir TYPES;
my @apps = grep /.*App$/, @allfiles;
my @boots = grep /.*Boot$/, @allfiles;
print "Valid application types are:\n";
foreach $name (@apps) {
$name =~ s|App||;
printf "\t$name\n" if ($name && -r "$top/$name" . "App");
}
print "Valid iocBoot types are:\n";
foreach $name (@boots) {
$name =~ s|Boot||;
printf "\t$name\n" if ($name && -r "$top/$name" . "Boot");;
}
}
#
# Copy a file with replacements
#
sub CopyFile { # (source)
$source = $_[0];
$target = ReplaceFilename($source);
if ($target and !-e $target) {
open(INP, "<$source") and open(OUT, ">$target")
or die "$! Copying $source -> $target";
print "Copying file $source -> $target\n" if $opt_d;
while (<INP>) {
print OUT ReplaceLine($_);
}
close INP; close OUT;
}
}
#
# Find() callback for file or structure copy
#
sub FCopyTree {
chdir $app_top; # Sigh
if (-d "$File::Find::name"
and ($dir = ReplaceFilename($File::Find::name))) {
print "Creating directory $dir\n" if $opt_d;
mkpath($dir) unless (-d "$dir");
} else {
CopyFile($File::Find::name);
}
chdir $File::Find::dir;
}
#
# Cleanup and exit
#
sub Cleanup { # (return-code [ messsage-line1, line 2, ... ])
my ($rtncode, @message) = @_;
if (@message) {
print join("\n", @message), "\n";
} else {
Usage();
}
exit $rtncode;
}
sub Usage {
print <<EOF;
Usage:
<base>/bin/<arch>/makeBaseApp.pl -h
display help on command options
<base>/bin/<arch>/makeBaseApp.pl -l [options]
list application types
<base>/bin/<arch>/makeBaseApp.pl -t type [options] [app ...]
create application directories
<base>/bin/<arch>/makeBaseApp.pl -i -t type [options] [ioc ...]
create ioc boot directories
where
app Application name (the created directory will have \"App\" appended)
ioc IOC name (the created directory will have \"ioc\" prepended)
EOF
print <<EOF if ($opt_h);
-a arch Set the IOC architecture for use with -i (e.g. vxWorks-68040)
If arch is not specified, you will be prompted
-b base Set the location of EPICS base (full path)
If not specified, base path is taken from configure/RELEASE
If configure does not exist, from environment
If not found in environment, from makeBaseApp.pl location
-d Enable debug messages
-i Specifies that ioc boot directories will be generated
-l List valid application types for this installation
If this is specified the other options are not used
-p app Set the application name for use with -i
If not specified, you will be prompted
-T top Set the template top directory (where the application templates are)
If not specified, top path is taken from configure/RELEASE
If configure does not exist, top path is taken from environment
If not found in environment, the templates from EPICS base are used
-t type Set the application type (-l for a list of valid types)
If not specified, type is taken from environment
If not found in environment, \"default\" is used
-u user Set username; overrides OS defaults
Environment:
EPICS_MBA_DEF_APP_TYPE Application type you want to use as default
EPICS_MBA_TEMPLATE_TOP Template top directory
EPICS_MBA_BASE Location of EPICS base
Example: Create exampleApp
<base>/bin/<arch>/makeBaseApp.pl -t example example
<base>/bin/<arch>/makeBaseApp.pl -i -t example example
EOF
}
sub GetUser {
$user = $opt_u || $ENV{USER} || $ENV{USERNAME} || getlogin();
$user = Win32::LoginName() if !$user && $^ eq 'MSWin32';
unless ($user) {
print "Strange, I cannot figure out your user name!\n";
print "What should you be called ? ";
$user = <STDIN>;
chomp $user;
}
$user =~ tr/-a-zA-Z0-9_:;[]<>//cd; # Sanitize; these are the legal chars
die "No user name" unless $user;
}
-31
View File
@@ -1,31 +0,0 @@
# Makefile at top of application tree
TOP = .
include $(TOP)/configure/CONFIG
# Directories to build, any order
DIRS += configure
DIRS += $(wildcard *Sup)
DIRS += $(wildcard *App)
DIRS += $(wildcard *Top)
DIRS += $(wildcard iocBoot)
# The build order is controlled by these dependency rules:
# All dirs except configure depend on configure
$(foreach dir, $(filter-out configure, $(DIRS)), \
$(eval $(dir)_DEPEND_DIRS += configure))
# Any *App dirs depend on all *Sup dirs
$(foreach dir, $(filter %App, $(DIRS)), \
$(eval $(dir)_DEPEND_DIRS += $(filter %Sup, $(DIRS))))
# Any *Top dirs depend on all *Sup and *App dirs
$(foreach dir, $(filter %Top, $(DIRS)), \
$(eval $(dir)_DEPEND_DIRS += $(filter %Sup %App, $(DIRS))))
# iocBoot depends on all *App dirs
iocBoot_DEPEND_DIRS += $(filter %App,$(DIRS))
# Add any additional dependency rules here:
include $(TOP)/configure/RULES_TOP
@@ -1,34 +0,0 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
TOP=..
include $(TOP)/configure/CONFIG
PROD_LIBS += $(EPICS_BASE_HOST_LIBS)
#
# Added ws2_32 winmm user32 for the non-dll build
#
PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32
casexample_SRCS += main.cc
casexample_SRCS += exServer.cc
casexample_SRCS += exPV.cc
casexample_SRCS += exVectorPV.cc
casexample_SRCS += exScalarPV.cc
casexample_SRCS += exAsyncPV.cc
casexample_SRCS += exChannel.cc
PROD_HOST = casexample
include $(TOP)/configure/RULES
-63
View File
@@ -1,63 +0,0 @@
The files in this directory build an example CA server. This code
is meant to provide some examples of how the CA server library can
be used but is not intended to be an example of exemplary code organization
and therefore care should be taken when emulating what is found here.
The example server exports the process variables (PVs) in the table below.
ScanPeriod Name HOPR LOPR Type Asynchronous Elements
.1 "jane" 10.0 0.0 DBR_DOUBLE No 1
2.0 "fred" 10.0 -10.0 DBR_DOUBLE No 1
.1 "janet" 10.0 0.0 DBR_DOUBLE Yes 1
2.0 "freddy"10.0 -10.0 DBR_DOUBLE Yes 1
2.0 "alan" 10.0 -10.0 DBR_DOUBLE No 100
20.0 "albert"10.0 -10.0 DBR_DOUBLE No 1000
-1.0 "boot" 10.0 -10.0 DBR_ENUM No 1
-1.0 "booty" 10.0 -10.0 DBR_ENUM Yes 1
-1.0 "bill" 10.0 -10.0 DBR_DOUBLE No 1
-1.0 "billy" 10.0 -10.0 DBR_DOUBLE Yes 1
-1.0 "bloaty"10.0 -10.0 DBR_DOUBLE No 100000
Many ca servers will find that synchronous variables will meet
their needs and will not require the increased complexity
associated with asynchronous PVs. Asynchronous PVs are needed
when read and write IO requests cant be completed immediately.
The PVs in the example server are updated periodically if the
"ScanPeriod" column above contains a positive number. Some random
"noise" is added to a PV's current value each time that it is
updated.
usage:
excas [-d<debug level> -t<execution time> -p<PV name prefix>
-c<numbered alias count> -s<1=scan on (default), 0=scan off>
-ss<1=synchronous scan (default), 0=asynchronous scan>]
-d<debug level>
Increased diagnostics messages with increasing debug level. Defaults to no
messages.
-t<execution time>
Specifies the duration that the server will run. Defaults to forever.
-p<PV name prefix>
Specifies the prefix applied to all PV names. If you specify "-pxxx:"
then clients must specify PV names like "xxx:fred" or "xxx:jane".
This is useful when several example servers are running on the same
IP subnet for testing purposes. Defaults to no prefix.
-c<numbered alias count>
Useful when you need lots of aliased PV names. The alias names are
of the form "fred1", "fred2", etc. Defaults to no aliases.
-s<1=scan on (default), 0=scan off>
Used to turn off updating of the PVs with random noise. Default is
to update all PVs with a positive scan period.
-ss<1=synchronous scan (default), 0=asynchronous scan>
Controls updating of PVs from an asynchronous thread (tests thread
safety of the server library). Defaults to synchronous.
@@ -1,228 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
// (asynchrronous process variable)
//
#include "exServer.h"
exAsyncPV::exAsyncPV ( exServer & cas, pvInfo & setup,
bool preCreateFlag, bool scanOnIn,
double asyncDelayIn ) :
exScalarPV ( cas, setup, preCreateFlag, scanOnIn ),
asyncDelay ( asyncDelayIn ),
simultAsychReadIOCount ( 0u ),
simultAsychWriteIOCount ( 0u )
{
}
//
// exAsyncPV::read()
//
caStatus exAsyncPV::read (const casCtx &ctx, gdd &valueIn)
{
exAsyncReadIO *pIO;
if ( this->simultAsychReadIOCount >= this->cas.maxSimultAsyncIO () ) {
return S_casApp_postponeAsyncIO;
}
pIO = new exAsyncReadIO ( this->cas, ctx,
*this, valueIn, this->asyncDelay );
if ( ! pIO ) {
if ( this->simultAsychReadIOCount > 0 ) {
return S_casApp_postponeAsyncIO;
}
else {
return S_casApp_noMemory;
}
}
this->simultAsychReadIOCount++;
return S_casApp_asyncCompletion;
}
//
// exAsyncPV::writeNotify()
//
caStatus exAsyncPV::writeNotify ( const casCtx &ctx, const gdd &valueIn )
{
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
return S_casApp_postponeAsyncIO;
}
exAsyncWriteIO * pIO = new
exAsyncWriteIO ( this->cas, ctx, *this,
valueIn, this->asyncDelay );
if ( ! pIO ) {
if ( this->simultAsychReadIOCount > 0 ) {
return S_casApp_postponeAsyncIO;
}
else {
return S_casApp_noMemory;
}
}
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
}
//
// exAsyncPV::write()
//
caStatus exAsyncPV::write ( const casCtx &ctx, const gdd &valueIn )
{
// implement the discard intermediate values, but last value
// sent always applied behavior that IOCs provide excepting
// that we will alow N requests to pend instead of a limit
// of only one imposed in the IOC
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
pStandbyValue.set ( & valueIn );
return S_casApp_success;
}
exAsyncWriteIO * pIO = new
exAsyncWriteIO ( this->cas, ctx, *this,
valueIn, this->asyncDelay );
if ( ! pIO ) {
pStandbyValue.set ( & valueIn );
return S_casApp_success;
}
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
}
// Implementing a specialized update for exAsyncPV
// allows standby value to update when we update
// the PV from an asynchronous write timer expiration
// which is a better time compared to removeIO below
// which, if used, gets the reads and writes out of
// order. This type of reordering can cause the
// regression tests to fail.
caStatus exAsyncPV :: updateFromAsyncWrite ( const gdd & src )
{
caStatus stat = this->update ( src );
if ( this->simultAsychWriteIOCount <=1 &&
pStandbyValue.valid () ) {
//printf("updateFromAsyncWrite: write standby\n");
stat = this->update ( *this->pStandbyValue );
this->pStandbyValue.set ( 0 );
}
return stat;
}
void exAsyncPV::removeReadIO ()
{
if ( this->simultAsychReadIOCount > 0u ) {
this->simultAsychReadIOCount--;
}
else {
fprintf ( stderr, "inconsistent simultAsychReadIOCount?\n" );
}
}
void exAsyncPV::removeWriteIO ()
{
if ( this->simultAsychWriteIOCount > 0u ) {
this->simultAsychWriteIOCount--;
if ( this->simultAsychWriteIOCount == 0 &&
pStandbyValue.valid () ) {
//printf("removeIO: write standby\n");
this->update ( *this->pStandbyValue );
this->pStandbyValue.set ( 0 );
}
}
else {
fprintf ( stderr, "inconsistent simultAsychWriteIOCount?\n" );
}
}
//
// exAsyncWriteIO::exAsyncWriteIO()
//
exAsyncWriteIO::exAsyncWriteIO ( exServer & cas,
const casCtx & ctxIn, exAsyncPV & pvIn,
const gdd & valueIn, double asyncDelay ) :
casAsyncWriteIO ( ctxIn ), pv ( pvIn ),
timer ( cas.createTimer () ), pValue(valueIn)
{
this->timer.start ( *this, asyncDelay );
}
//
// exAsyncWriteIO::~exAsyncWriteIO()
//
exAsyncWriteIO::~exAsyncWriteIO()
{
this->timer.destroy ();
// if the timer hasnt expired, and the value
// hasnt been written then force it to happen
// now so that regression testing works
if ( this->pValue.valid () ) {
this->pv.updateFromAsyncWrite ( *this->pValue );
}
this->pv.removeWriteIO();
}
//
// exAsyncWriteIO::expire()
// (a virtual function that runs when the base timer expires)
//
epicsTimerNotify::expireStatus exAsyncWriteIO::
expire ( const epicsTime & /* currentTime */ )
{
assert ( this->pValue.valid () );
caStatus status = this->pv.updateFromAsyncWrite ( *this->pValue );
this->pValue.set ( 0 );
this->postIOCompletion ( status );
return noRestart;
}
//
// exAsyncReadIO::exAsyncReadIO()
//
exAsyncReadIO::exAsyncReadIO ( exServer & cas, const casCtx & ctxIn,
exAsyncPV & pvIn, gdd & protoIn,
double asyncDelay ) :
casAsyncReadIO ( ctxIn ), pv ( pvIn ),
timer ( cas.createTimer() ), pProto ( protoIn )
{
this->timer.start ( *this, asyncDelay );
}
//
// exAsyncReadIO::~exAsyncReadIO()
//
exAsyncReadIO::~exAsyncReadIO()
{
this->pv.removeReadIO ();
this->timer.destroy ();
}
//
// exAsyncReadIO::expire()
// (a virtual function that runs when the base timer expires)
//
epicsTimerNotify::expireStatus
exAsyncReadIO::expire ( const epicsTime & /* currentTime */ )
{
//
// map between the prototype in and the
// current value
//
caStatus status = this->pv.exPV::readNoCtx ( this->pProto );
//
// post IO completion
//
this->postIOCompletion ( status, *this->pProto );
return noRestart;
}
@@ -1,41 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
//
#include "exServer.h"
//
// exChannel::setOwner ()
//
void exChannel::setOwner(const char * const /* pUserName */,
const char * const /* pHostName */)
{
}
//
// exChannel::readAccess ()
//
bool exChannel::readAccess () const
{
return true;
}
//
// exChannel::writeAccess ()
//
bool exChannel::writeAccess () const
{
return true;
}
-344
View File
@@ -1,344 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
//
#include "exServer.h"
#include "gddApps.h"
//
// static data for exPV
//
char exPV::hasBeenInitialized = 0;
gddAppFuncTable<exPV> exPV::ft;
epicsTime exPV::currentTime;
//
// special gddDestructor guarantees same form of new and delete
//
class exFixedStringDestructor: public gddDestructor {
virtual void run (void *);
};
//
// exPV::exPV()
//
exPV::exPV ( exServer & casIn, pvInfo & setup,
bool preCreateFlag, bool scanOnIn ) :
cas ( casIn ),
timer ( cas.createTimer() ),
info ( setup ),
interest ( false ),
preCreate ( preCreateFlag ),
scanOn ( scanOnIn )
{
//
// no dataless PV allowed
//
assert (this->info.getCapacity()>=1u);
//
// start a very slow background scan
// (we will speed this up to the normal rate when
// someone is watching the PV)
//
if ( this->scanOn && this->info.getScanPeriod () > 0.0 ) {
this->timer.start ( *this, this->getScanPeriod() );
}
}
//
// exPV::~exPV()
//
exPV::~exPV()
{
this->timer.destroy ();
this->info.unlinkPV();
}
//
// exPV::destroy()
//
// this is replaced by a noop since we are
// pre-creating most of the PVs during init in this simple server
//
void exPV::destroy()
{
if ( ! this->preCreate ) {
delete this;
}
}
//
// exPV::update()
//
caStatus exPV::update ( const gdd & valueIn )
{
# if DEBUG
printf("Setting %s too:\n", this->info.getName().string());
valueIn.dump();
# endif
caStatus status = this->updateValue ( valueIn );
if ( status || ( ! this->pValue.valid() ) ) {
return status;
}
//
// post a value change event
//
caServer * pCAS = this->getCAS();
if ( this->interest == true && pCAS != NULL ) {
casEventMask select ( pCAS->valueEventMask() | pCAS->logEventMask() );
this->postEvent ( select, *this->pValue );
}
return S_casApp_success;
}
//
// exScanTimer::expire ()
//
epicsTimerNotify::expireStatus
exPV::expire ( const epicsTime & /*currentTime*/ )
{
this->scan();
if ( this->scanOn && this->getScanPeriod() > 0.0 ) {
return expireStatus ( restart, this->getScanPeriod() );
}
else {
return noRestart;
}
}
//
// exPV::bestExternalType()
//
aitEnum exPV::bestExternalType () const
{
return this->info.getType ();
}
//
// exPV::interestRegister()
//
caStatus exPV::interestRegister ()
{
if ( ! this->getCAS() ) {
return S_casApp_success;
}
this->interest = true;
if ( this->scanOn && this->getScanPeriod() > 0.0 &&
this->getScanPeriod() < this->timer.getExpireDelay() ) {
this->timer.start ( *this, this->getScanPeriod() );
}
return S_casApp_success;
}
//
// exPV::interestDelete()
//
void exPV::interestDelete()
{
this->interest = false;
}
//
// exPV::show()
//
void exPV::show ( unsigned level ) const
{
if (level>1u) {
if ( this->pValue.valid () ) {
printf ( "exPV: cond=%d\n", this->pValue->getStat () );
printf ( "exPV: sevr=%d\n", this->pValue->getSevr () );
printf ( "exPV: value=%f\n", static_cast < double > ( * this->pValue ) );
}
printf ( "exPV: interest=%d\n", this->interest );
this->timer.show ( level - 1u );
}
}
//
// exPV::initFT()
//
void exPV::initFT ()
{
if ( exPV::hasBeenInitialized ) {
return;
}
//
// time stamp, status, and severity are extracted from the
// GDD associated with the "value" application type.
//
exPV::ft.installReadFunc ("value", &exPV::getValue);
exPV::ft.installReadFunc ("precision", &exPV::getPrecision);
exPV::ft.installReadFunc ("graphicHigh", &exPV::getHighLimit);
exPV::ft.installReadFunc ("graphicLow", &exPV::getLowLimit);
exPV::ft.installReadFunc ("controlHigh", &exPV::getHighLimit);
exPV::ft.installReadFunc ("controlLow", &exPV::getLowLimit);
exPV::ft.installReadFunc ("alarmHigh", &exPV::getHighLimit);
exPV::ft.installReadFunc ("alarmLow", &exPV::getLowLimit);
exPV::ft.installReadFunc ("alarmHighWarning", &exPV::getHighLimit);
exPV::ft.installReadFunc ("alarmLowWarning", &exPV::getLowLimit);
exPV::ft.installReadFunc ("units", &exPV::getUnits);
exPV::ft.installReadFunc ("enums", &exPV::getEnums);
exPV::hasBeenInitialized = 1;
}
//
// exPV::getPrecision()
//
caStatus exPV::getPrecision ( gdd & prec )
{
prec.put(4u);
return S_cas_success;
}
//
// exPV::getHighLimit()
//
caStatus exPV::getHighLimit ( gdd & value )
{
value.put(info.getHopr());
return S_cas_success;
}
//
// exPV::getLowLimit()
//
caStatus exPV::getLowLimit ( gdd & value )
{
value.put(info.getLopr());
return S_cas_success;
}
//
// exPV::getUnits()
//
caStatus exPV::getUnits( gdd & units )
{
aitString str("furlongs", aitStrRefConstImortal);
units.put(str);
return S_cas_success;
}
//
// exPV::getEnums()
//
// returns the eneumerated state strings
// for a discrete channel
//
// The PVs in this example are purely analog,
// and therefore this isnt appropriate in an
// analog context ...
//
caStatus exPV::getEnums ( gdd & enumsIn )
{
if ( this->info.getType () == aitEnumEnum16 ) {
static const unsigned nStr = 2;
aitFixedString *str;
exFixedStringDestructor *pDes;
str = new aitFixedString[nStr];
if (!str) {
return S_casApp_noMemory;
}
pDes = new exFixedStringDestructor;
if (!pDes) {
delete [] str;
return S_casApp_noMemory;
}
strncpy (str[0].fixed_string, "off",
sizeof(str[0].fixed_string));
strncpy (str[1].fixed_string, "on",
sizeof(str[1].fixed_string));
enumsIn.setDimension(1);
enumsIn.setBound (0,0,nStr);
enumsIn.putRef (str, pDes);
return S_cas_success;
}
return S_cas_success;
}
//
// exPV::getValue()
//
caStatus exPV::getValue ( gdd & value )
{
caStatus status;
if ( this->pValue.valid () ) {
gddStatus gdds;
gdds = gddApplicationTypeTable::
app_table.smartCopy ( &value, & (*this->pValue) );
if (gdds) {
status = S_cas_noConvert;
}
else {
status = S_cas_success;
}
}
else {
status = S_casApp_undefined;
}
return status;
}
//
// exPV::write()
// (synchronous default)
//
caStatus exPV::write ( const casCtx &, const gdd & valueIn )
{
return this->update ( valueIn );
}
//
// exPV::read()
// (synchronous default)
//
caStatus exPV::read ( const casCtx &, gdd & protoIn )
{
return this->ft.read ( *this, protoIn );
}
//
// exPV::createChannel()
//
// for access control - optional
//
casChannel *exPV::createChannel ( const casCtx &ctx,
const char * const /* pUserName */,
const char * const /* pHostName */ )
{
return new exChannel ( ctx );
}
//
// exFixedStringDestructor::run()
//
// special gddDestructor guarantees same form of new and delete
//
void exFixedStringDestructor::run ( void * pUntyped )
{
aitFixedString *ps = (aitFixedString *) pUntyped;
delete [] ps;
}
@@ -1,120 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#include "exServer.h"
#include "gddApps.h"
#define myPI 3.14159265358979323846
//
// SUN C++ does not have RAND_MAX yet
//
#if !defined(RAND_MAX)
//
// Apparently SUN C++ is using the SYSV version of rand
//
#if 0
#define RAND_MAX INT_MAX
#else
#define RAND_MAX SHRT_MAX
#endif
#endif
//
// exScalarPV::scan
//
void exScalarPV::scan()
{
caStatus status;
double radians;
smartGDDPointer pDD;
float newValue;
float limit;
int gddStatus;
//
// update current time (so we are not required to do
// this every time that we write the PV which impacts
// throughput under sunos4 because gettimeofday() is
// slow)
//
this->currentTime = epicsTime::getCurrent ();
pDD = new gddScalar ( gddAppType_value, aitEnumFloat64 );
if ( ! pDD.valid () ) {
return;
}
//
// smart pointer class manages reference count after this point
//
gddStatus = pDD->unreference ();
assert ( ! gddStatus );
radians = ( rand () * 2.0 * myPI ) / RAND_MAX;
if ( this->pValue.valid () ) {
this->pValue->getConvert(newValue);
}
else {
newValue = 0.0f;
}
newValue += (float) ( sin (radians) / 10.0 );
limit = (float) this->info.getHopr ();
newValue = epicsMin ( newValue, limit );
limit = (float) this->info.getLopr ();
newValue = epicsMax ( newValue, limit );
*pDD = newValue;
aitTimeStamp gddts ( this->currentTime );
pDD->setTimeStamp ( & gddts );
status = this->update ( *pDD );
if (status!=S_casApp_success) {
errMessage ( status, "scalar scan update failed\n" );
}
}
//
// exScalarPV::updateValue ()
//
// NOTES:
// 1) This should have a test which verifies that the
// incoming value in all of its various data types can
// be translated into a real number?
// 2) We prefer to unreference the old PV value here and
// reference the incomming value because this will
// result in each value change events retaining an
// independent value on the event queue.
//
caStatus exScalarPV::updateValue ( const gdd & valueIn )
{
//
// Really no need to perform this check since the
// server lib verifies that all requests are in range
//
if ( ! valueIn.isScalar() ) {
return S_casApp_outOfBounds;
}
if ( ! pValue.valid () ) {
this->pValue = new gddScalar (
gddAppType_value, this->info.getType () );
if ( ! pValue.valid () ) {
return S_casApp_noMemory;
}
}
this->pValue->put ( & valueIn );
return S_casApp_success;
}
@@ -1,435 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// fileDescriptorManager.process(delay);
// (the name of the global symbol has leaked in here)
//
//
// Example EPICS CA server
//
#include "exServer.h"
//
// static list of pre-created PVs
//
pvInfo exServer::pvList[] = {
pvInfo (1.0e-1, "jane", 10.0f, 0.0f, aitEnumFloat64, excasIoSync, 1u),
pvInfo (2.0, "fred", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1u),
pvInfo (1.0e-1, "janet", 10.0f, 0.0f, aitEnumFloat64, excasIoAsync, 1u),
pvInfo (2.0, "freddy", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u),
pvInfo (2.0, "alan", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 100u),
pvInfo (20.0, "albert", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1000u),
pvInfo (-1.0, "boot", 10.0f, -10.0f, aitEnumEnum16, excasIoSync, 1u),
pvInfo (1.0, "booty", 10.0f, -10.0f, aitEnumEnum16, excasIoAsync, 1u),
pvInfo (-1.0, "bill", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1u),
pvInfo (-1.0, "billy", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u)
};
const unsigned exServer::pvListNElem = NELEMENTS (exServer::pvList);
//
// static on-the-fly PVs
//
pvInfo exServer::billy (-1.0, "billybob", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u);
pvInfo exServer::bloater (.010, "bloater", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 10000u);
pvInfo exServer::bloaty (.010, "bloaty", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 100000u);
//
// exServer::exServer()
//
exServer::exServer ( const char * const pvPrefix,
unsigned aliasCount, bool scanOnIn,
bool asyncScan, double asyncDelayIn,
unsigned maxSimultAsyncIOIn ) :
pTimerQueue ( 0 ), simultAsychIOCount ( 0u ),
_maxSimultAsyncIO ( maxSimultAsyncIOIn ),
asyncDelay ( asyncDelayIn ), scanOn ( scanOnIn )
{
unsigned i;
exPV *pPV;
pvInfo *pPVI;
pvInfo *pPVAfter = &exServer::pvList[pvListNElem];
char pvAlias[256];
const char * const pNameFmtStr = "%.100s%.20s";
const char * const pAliasFmtStr = "%.100s%.20s%.6u";
exPV::initFT();
if ( asyncScan ) {
unsigned timerPriotity;
epicsThreadBooleanStatus etbs = epicsThreadLowestPriorityLevelAbove (
epicsThreadGetPrioritySelf (), & timerPriotity );
if ( etbs != epicsThreadBooleanStatusSuccess ) {
timerPriotity = epicsThreadGetPrioritySelf ();
}
this->pTimerQueue = & epicsTimerQueueActive::allocate ( false, timerPriotity );
}
//
// pre-create all of the simple PVs that this server will export
//
for (pPVI = exServer::pvList; pPVI < pPVAfter; pPVI++) {
pPV = pPVI->createPV (*this, true, scanOnIn, this->asyncDelay );
if (!pPV) {
fprintf(stderr, "Unable to create new PV \"%s\"\n",
pPVI->getName());
}
//
// Install canonical (root) name
//
sprintf(pvAlias, pNameFmtStr, pvPrefix, pPVI->getName());
this->installAliasName(*pPVI, pvAlias);
//
// Install numbered alias names
//
for (i=0u; i<aliasCount; i++) {
sprintf(pvAlias, pAliasFmtStr, pvPrefix,
pPVI->getName(), i);
this->installAliasName(*pPVI, pvAlias);
}
}
//
// Install create on-the-fly PVs
// into the PV name hash table
//
sprintf ( pvAlias, pNameFmtStr, pvPrefix, billy.getName() );
this->installAliasName ( billy, pvAlias );
sprintf ( pvAlias, pNameFmtStr, pvPrefix, bloater.getName() );
this->installAliasName ( bloater, pvAlias );
sprintf ( pvAlias, pNameFmtStr, pvPrefix, bloaty.getName() );
this->installAliasName ( bloaty, pvAlias );
}
//
// exServer::~exServer()
//
exServer::~exServer()
{
this->destroyAllPV ();
this->stringResTbl.traverse ( &pvEntry::destroy );
}
void exServer::destroyAllPV ()
{
for ( unsigned i = 0;
i < NELEMENTS(exServer::pvList); i++ ) {
exServer::pvList[i].deletePV ();
}
}
//
// exServer::installAliasName()
//
void exServer::installAliasName(pvInfo &info, const char *pAliasName)
{
pvEntry *pEntry;
pEntry = new pvEntry(info, *this, pAliasName);
if (pEntry) {
int resLibStatus;
resLibStatus = this->stringResTbl.add(*pEntry);
if (resLibStatus==0) {
return;
}
else {
delete pEntry;
}
}
fprintf ( stderr,
"Unable to enter PV=\"%s\" Alias=\"%s\" in PV name alias hash table\n",
info.getName(), pAliasName );
}
//
// More advanced pvExistTest() isnt needed so we forward to
// original version. This avoids sun pro warnings and speeds
// up execution.
//
pvExistReturn exServer::pvExistTest
( const casCtx & ctx, const caNetAddr &, const char * pPVName )
{
return this->pvExistTest ( ctx, pPVName );
}
//
// exServer::pvExistTest()
//
pvExistReturn exServer::pvExistTest
( const casCtx& ctxIn, const char * pPVName )
{
//
// lifetime of id is shorter than lifetime of pName
//
stringId id ( pPVName, stringId::refString );
pvEntry *pPVE;
//
// Look in hash table for PV name (or PV alias name)
//
pPVE = this->stringResTbl.lookup ( id );
if ( ! pPVE ) {
return pverDoesNotExistHere;
}
pvInfo & pvi = pPVE->getInfo();
//
// Initiate async IO if this is an async PV
//
if ( pvi.getIOType() == excasIoSync ) {
return pverExistsHere;
}
else {
if ( this->simultAsychIOCount >= this->_maxSimultAsyncIO ) {
return pverDoesNotExistHere;
}
this->simultAsychIOCount++;
exAsyncExistIO * pIO =
new exAsyncExistIO ( pvi, ctxIn, *this );
if ( pIO ) {
return pverAsyncCompletion;
}
else {
this->simultAsychIOCount--;
return pverDoesNotExistHere;
}
}
}
//
// exServer::pvAttach()
//
pvAttachReturn exServer::pvAttach
(const casCtx &ctx, const char *pName)
{
//
// lifetime of id is shorter than lifetime of pName
//
stringId id(pName, stringId::refString);
exPV *pPV;
pvEntry *pPVE;
pPVE = this->stringResTbl.lookup(id);
if (!pPVE) {
return S_casApp_pvNotFound;
}
pvInfo &pvi = pPVE->getInfo();
//
// If this is a synchronous PV create the PV now
//
if (pvi.getIOType() == excasIoSync) {
pPV = pvi.createPV(*this, false, this->scanOn, this->asyncDelay );
if (pPV) {
return *pPV;
}
else {
return S_casApp_noMemory;
}
}
//
// Initiate async IO if this is an async PV
//
else {
if (this->simultAsychIOCount>=this->_maxSimultAsyncIO) {
return S_casApp_postponeAsyncIO;
}
this->simultAsychIOCount++;
exAsyncCreateIO *pIO =
new exAsyncCreateIO ( pvi, *this, ctx,
this->scanOn, this->asyncDelay );
if (pIO) {
return S_casApp_asyncCompletion;
}
else {
this->simultAsychIOCount--;
return S_casApp_noMemory;
}
}
}
//
// exServer::setDebugLevel ()
//
void exServer::setDebugLevel ( unsigned level )
{
this->caServer::setDebugLevel ( level );
}
//
// exServer::createTimer ()
//
class epicsTimer & exServer::createTimer ()
{
if ( this->pTimerQueue ) {
return this->pTimerQueue->createTimer ();
}
else {
return this->caServer::createTimer ();
}
}
//
// pvInfo::createPV()
//
exPV *pvInfo::createPV ( exServer & cas, bool preCreateFlag,
bool scanOn, double asyncDelay )
{
if (this->pPV) {
return this->pPV;
}
exPV *pNewPV;
//
// create an instance of the appropriate class
// depending on the io type and the number
// of elements
//
if (this->capacity==1u) {
switch (this->ioType){
case excasIoSync:
pNewPV = new exScalarPV ( cas, *this, preCreateFlag, scanOn );
break;
case excasIoAsync:
pNewPV = new exAsyncPV ( cas, *this,
preCreateFlag, scanOn, asyncDelay );
break;
default:
pNewPV = NULL;
break;
}
}
else {
if ( this->ioType == excasIoSync ) {
pNewPV = new exVectorPV ( cas, *this, preCreateFlag, scanOn );
}
else {
pNewPV = NULL;
}
}
//
// load initial value (this is not done in
// the constructor because the base class's
// pure virtual function would be called)
//
// We always perform this step even if
// scanning is disable so that there will
// always be an initial value
//
if (pNewPV) {
this->pPV = pNewPV;
pNewPV->scan();
}
return pNewPV;
}
//
// exServer::show()
//
void exServer::show (unsigned level) const
{
//
// server tool specific show code goes here
//
this->stringResTbl.show(level);
//
// print information about ca server libarary
// internals
//
this->caServer::show(level);
}
//
// exAsyncExistIO::exAsyncExistIO()
//
exAsyncExistIO::exAsyncExistIO ( const pvInfo &pviIn, const casCtx &ctxIn,
exServer &casIn ) :
casAsyncPVExistIO ( ctxIn ), pvi ( pviIn ),
timer ( casIn.createTimer () ), cas ( casIn )
{
this->timer.start ( *this, 0.00001 );
}
//
// exAsyncExistIO::~exAsyncExistIO()
//
exAsyncExistIO::~exAsyncExistIO()
{
this->cas.removeIO ();
this->timer.destroy ();
}
//
// exAsyncExistIO::expire()
// (a virtual function that runs when the base timer expires)
//
epicsTimerNotify::expireStatus exAsyncExistIO::expire ( const epicsTime & /*currentTime*/ )
{
//
// post IO completion
//
this->postIOCompletion ( pvExistReturn(pverExistsHere) );
return noRestart;
}
//
// exAsyncCreateIO::exAsyncCreateIO()
//
exAsyncCreateIO ::
exAsyncCreateIO ( pvInfo &pviIn, exServer &casIn,
const casCtx &ctxIn, bool scanOnIn, double asyncDelayIn ) :
casAsyncPVAttachIO ( ctxIn ), pvi ( pviIn ),
timer ( casIn.createTimer () ),
cas ( casIn ), asyncDelay ( asyncDelayIn ), scanOn ( scanOnIn )
{
this->timer.start ( *this, 0.00001 );
}
//
// exAsyncCreateIO::~exAsyncCreateIO()
//
exAsyncCreateIO::~exAsyncCreateIO()
{
this->cas.removeIO ();
this->timer.destroy ();
}
//
// exAsyncCreateIO::expire()
// (a virtual function that runs when the base timer expires)
//
epicsTimerNotify::expireStatus exAsyncCreateIO::expire ( const epicsTime & /*currentTime*/ )
{
exPV * pPV = this->pvi.createPV ( this->cas, false,
this->scanOn, this->asyncDelay );
if ( pPV ) {
this->postIOCompletion ( pvAttachReturn ( *pPV ) );
}
else {
this->postIOCompletion ( pvAttachReturn ( S_casApp_noMemory ) );
}
return noRestart;
}
@@ -1,602 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
//
//
// caServer
// |
// exServer
//
// casPV
// |
// exPV-----------
// | |
// exScalarPV exVectorPV
// |
// exAsyncPV
//
// casChannel
// |
// exChannel
//
//
// ANSI C
//
#include <string.h>
#include <stdio.h>
//
// EPICS
//
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include "gddAppFuncTable.h"
#include "smartGDDPointer.h"
#include "epicsTimer.h"
#include "casdef.h"
#include "epicsAssert.h"
#include "resourceLib.h"
#include "epicsAlgorithm.h"
#ifndef NELEMENTS
# define NELEMENTS(A) (sizeof(A)/sizeof(A[0]))
#endif
//
// info about all pv in this server
//
enum excasIoType { excasIoSync, excasIoAsync };
class exPV;
class exServer;
//
// pvInfo
//
class pvInfo {
public:
pvInfo ( double scanPeriodIn, const char * pNameIn,
aitFloat32 hoprIn, aitFloat32 loprIn, aitEnum typeIn,
excasIoType ioTypeIn, unsigned countIn );
pvInfo ( const pvInfo & copyIn );
~pvInfo ();
double getScanPeriod () const;
const char * getName ()
const; double getHopr () const;
double getLopr () const;
aitEnum getType () const;
excasIoType getIOType () const;
unsigned getCapacity () const;
unsigned getElementCount () const;
void setElementCount (unsigned);
void unlinkPV ();
exPV *createPV ( exServer & exCAS, bool preCreateFlag,
bool scanOn, double asyncDelay );
void deletePV ();
private:
const double scanPeriod;
const char * pName;
const double hopr;
const double lopr;
aitEnum type;
const excasIoType ioType;
const unsigned capacity;
unsigned elementCount;
exPV * pPV;
pvInfo & operator = ( const pvInfo & );
};
//
// pvEntry
//
// o entry in the string hash table for the pvInfo
// o Since there may be aliases then we may end up
// with several of this class all referencing
// the same pv info class (justification
// for this breaking out into a seperate class
// from pvInfo)
//
class pvEntry
: public stringId, public tsSLNode < pvEntry > {
public:
pvEntry ( pvInfo &infoIn, exServer & casIn,
const char * pAliasName );
~pvEntry();
pvInfo & getInfo() const { return this->info; }
void destroy ();
private:
pvInfo & info;
exServer & cas;
pvEntry & operator = ( const pvEntry & );
pvEntry ( const pvEntry & );
};
//
// exPV
//
class exPV : public casPV, public epicsTimerNotify,
public tsSLNode < exPV > {
public:
exPV ( exServer & cas, pvInfo & setup,
bool preCreateFlag, bool scanOn );
virtual ~exPV();
void show ( unsigned level ) const;
//
// Called by the server libary each time that it wishes to
// subscribe for PV the server tool via postEvent() below.
//
caStatus interestRegister ();
//
// called by the server library each time that it wishes to
// remove its subscription for PV value change events
// from the server tool via caServerPostEvents()
//
void interestDelete ();
aitEnum bestExternalType () const;
//
// chCreate() is called each time that a PV is attached to
// by a client. The server tool must create a casChannel object
// (or a derived class) each time that this routine is called
//
// If the operation must complete asynchronously then return
// the status code S_casApp_asyncCompletion and then
// create the casChannel object at some time in the future
//
//casChannel *createChannel ();
//
// This gets called when the pv gets a new value
//
caStatus update ( const gdd & );
//
// Gets called when we add noise to the current value
//
virtual void scan () = 0;
//
// If no one is watching scan the PV with 10.0
// times the specified period
//
double getScanPeriod ();
caStatus read ( const casCtx &, gdd & protoIn );
caStatus readNoCtx ( smartGDDPointer pProtoIn );
caStatus write ( const casCtx &, const gdd & value );
void destroy ();
const pvInfo & getPVInfo ();
const char * getName() const;
static void initFT();
casChannel * createChannel ( const casCtx &ctx,
const char * const pUserName,
const char * const pHostName );
protected:
smartGDDPointer pValue;
exServer & cas;
epicsTimer & timer;
pvInfo & info;
bool interest;
bool preCreate;
bool scanOn;
static epicsTime currentTime;
virtual caStatus updateValue ( const gdd & ) = 0;
private:
//
// scan timer expire
//
expireStatus expire ( const epicsTime & currentTime );
//
// Std PV Attribute fetch support
//
gddAppFuncTableStatus getPrecision(gdd &value);
gddAppFuncTableStatus getHighLimit(gdd &value);
gddAppFuncTableStatus getLowLimit(gdd &value);
gddAppFuncTableStatus getUnits(gdd &value);
gddAppFuncTableStatus getValue(gdd &value);
gddAppFuncTableStatus getEnums(gdd &value);
exPV & operator = ( const exPV & );
exPV ( const exPV & );
//
// static
//
static gddAppFuncTable<exPV> ft;
static char hasBeenInitialized;
};
//
// exScalarPV
//
class exScalarPV : public exPV {
public:
exScalarPV ( exServer & cas, pvInfo &setup,
bool preCreateFlag, bool scanOnIn ) :
exPV ( cas, setup,
preCreateFlag, scanOnIn) {}
void scan();
private:
caStatus updateValue ( const gdd & );
exScalarPV & operator = ( const exScalarPV & );
exScalarPV ( const exScalarPV & );
};
//
// exVectorPV
//
class exVectorPV : public exPV {
public:
exVectorPV ( exServer & cas, pvInfo &setup,
bool preCreateFlag, bool scanOnIn ) :
exPV ( cas, setup,
preCreateFlag, scanOnIn) {}
void scan();
unsigned maxDimension() const;
aitIndex maxBound (unsigned dimension) const;
private:
caStatus updateValue ( const gdd & );
exVectorPV & operator = ( const exVectorPV & );
exVectorPV ( const exVectorPV & );
};
//
// exServer
//
class exServer : private caServer {
public:
exServer ( const char * const pvPrefix,
unsigned aliasCount, bool scanOn,
bool asyncScan, double asyncDelay,
unsigned maxSimultAsyncIO );
~exServer ();
void show ( unsigned level ) const;
void removeIO ();
void removeAliasName ( pvEntry & entry );
class epicsTimer & createTimer ();
void setDebugLevel ( unsigned level );
void destroyAllPV ();
unsigned maxSimultAsyncIO () const;
private:
resTable < pvEntry, stringId > stringResTbl;
epicsTimerQueueActive * pTimerQueue;
unsigned simultAsychIOCount;
const unsigned _maxSimultAsyncIO;
double asyncDelay;
bool scanOn;
void installAliasName ( pvInfo & info, const char * pAliasName );
pvExistReturn pvExistTest ( const casCtx &,
const caNetAddr &, const char * pPVName );
pvExistReturn pvExistTest ( const casCtx &,
const char * pPVName );
pvAttachReturn pvAttach ( const casCtx &,
const char * pPVName );
exServer & operator = ( const exServer & );
exServer ( const exServer & );
//
// list of pre-created PVs
//
static pvInfo pvList[];
static const unsigned pvListNElem;
//
// on-the-fly PVs
//
static pvInfo bill;
static pvInfo billy;
static pvInfo bloater;
static pvInfo bloaty;
static pvInfo boot;
static pvInfo booty;
};
//
// exAsyncPV
//
class exAsyncPV : public exScalarPV {
public:
exAsyncPV ( exServer & cas, pvInfo &setup,
bool preCreateFlag, bool scanOnIn, double asyncDelay );
caStatus read ( const casCtx & ctxIn, gdd & protoIn );
caStatus write ( const casCtx & ctxIn, const gdd & value );
caStatus writeNotify ( const casCtx & ctxIn, const gdd & value );
void removeReadIO();
void removeWriteIO();
caStatus updateFromAsyncWrite ( const gdd & );
private:
double asyncDelay;
smartConstGDDPointer pStandbyValue;
unsigned simultAsychReadIOCount;
unsigned simultAsychWriteIOCount;
exAsyncPV & operator = ( const exAsyncPV & );
exAsyncPV ( const exAsyncPV & );
};
//
// exChannel
//
class exChannel : public casChannel{
public:
exChannel ( const casCtx & ctxIn );
void setOwner ( const char * const pUserName,
const char * const pHostName );
bool readAccess () const;
bool writeAccess () const;
private:
exChannel & operator = ( const exChannel & );
exChannel ( const exChannel & );
};
//
// exAsyncWriteIO
//
class exAsyncWriteIO : public casAsyncWriteIO, public epicsTimerNotify {
public:
exAsyncWriteIO ( exServer &, const casCtx & ctxIn,
exAsyncPV &, const gdd &, double asyncDelay );
~exAsyncWriteIO ();
private:
exAsyncPV & pv;
epicsTimer & timer;
smartConstGDDPointer pValue;
expireStatus expire ( const epicsTime & currentTime );
exAsyncWriteIO & operator = ( const exAsyncWriteIO & );
exAsyncWriteIO ( const exAsyncWriteIO & );
};
//
// exAsyncReadIO
//
class exAsyncReadIO : public casAsyncReadIO, public epicsTimerNotify {
public:
exAsyncReadIO ( exServer &, const casCtx &,
exAsyncPV &, gdd &, double asyncDelay );
virtual ~exAsyncReadIO ();
private:
exAsyncPV & pv;
epicsTimer & timer;
smartGDDPointer pProto;
expireStatus expire ( const epicsTime & currentTime );
exAsyncReadIO & operator = ( const exAsyncReadIO & );
exAsyncReadIO ( const exAsyncReadIO & );
};
//
// exAsyncExistIO
// (PV exist async IO)
//
class exAsyncExistIO : public casAsyncPVExistIO, public epicsTimerNotify {
public:
exAsyncExistIO ( const pvInfo & pviIn, const casCtx & ctxIn,
exServer & casIn );
virtual ~exAsyncExistIO ();
private:
const pvInfo & pvi;
epicsTimer & timer;
exServer & cas;
expireStatus expire ( const epicsTime & currentTime );
exAsyncExistIO & operator = ( const exAsyncExistIO & );
exAsyncExistIO ( const exAsyncExistIO & );
};
//
// exAsyncCreateIO
// (PV create async IO)
//
class exAsyncCreateIO : public casAsyncPVAttachIO, public epicsTimerNotify {
public:
exAsyncCreateIO ( pvInfo & pviIn, exServer & casIn,
const casCtx & ctxIn, bool scanOnIn, double asyncDelay );
virtual ~exAsyncCreateIO ();
private:
pvInfo & pvi;
epicsTimer & timer;
exServer & cas;
double asyncDelay;
bool scanOn;
expireStatus expire ( const epicsTime & currentTime );
exAsyncCreateIO & operator = ( const exAsyncCreateIO & );
exAsyncCreateIO ( const exAsyncCreateIO & );
};
inline pvInfo::pvInfo ( double scanPeriodIn, const char *pNameIn,
aitFloat32 hoprIn, aitFloat32 loprIn,
aitEnum typeIn, excasIoType ioTypeIn,
unsigned countIn ) :
scanPeriod ( scanPeriodIn ), pName ( pNameIn ),
hopr ( hoprIn ), lopr ( loprIn ), type ( typeIn ),
ioType ( ioTypeIn ), capacity ( countIn ),
elementCount ( 0 ), pPV ( 0 )
{
}
//
// for use when MSVC++ will not build a default copy constructor
// for this class
//
inline pvInfo::pvInfo ( const pvInfo & copyIn ) :
scanPeriod ( copyIn.scanPeriod ), pName ( copyIn.pName ),
hopr ( copyIn.hopr ), lopr ( copyIn.lopr ), type ( copyIn.type ),
ioType ( copyIn.ioType ), capacity ( copyIn.capacity ),
elementCount ( copyIn.elementCount ), pPV ( copyIn.pPV )
{
}
inline pvInfo::~pvInfo ()
{
//
// GDD cleanup gets rid of GDD's that are in use
// by the PV before the file scope destructer for
// this class runs here so this does not seem to
// be a good idea
//
//if ( this->pPV != NULL ) {
// delete this->pPV;
//}
}
inline void pvInfo::deletePV ()
{
if ( this->pPV != NULL ) {
delete this->pPV;
}
}
inline double pvInfo::getScanPeriod () const
{
return this->scanPeriod;
}
inline const char *pvInfo::getName () const
{
return this->pName;
}
inline double pvInfo::getHopr () const
{
return this->hopr;
}
inline double pvInfo::getLopr () const
{
return this->lopr;
}
inline aitEnum pvInfo::getType () const
{
return this->type;
}
inline excasIoType pvInfo::getIOType () const
{
return this->ioType;
}
inline unsigned pvInfo::getCapacity () const
{
return this->capacity;
}
inline unsigned pvInfo::getElementCount () const
{
return this->elementCount;
}
inline void pvInfo::setElementCount (unsigned newCount)
{
this->elementCount = newCount;
}
inline void pvInfo::unlinkPV ()
{
this->pPV = NULL;
}
inline pvEntry::pvEntry ( pvInfo & infoIn, exServer & casIn,
const char * pAliasName ) :
stringId ( pAliasName ), info ( infoIn ), cas ( casIn )
{
assert ( this->stringId::resourceName() != NULL );
}
inline pvEntry::~pvEntry ()
{
this->cas.removeAliasName ( *this );
}
inline void pvEntry::destroy ()
{
delete this;
}
inline void exServer::removeAliasName ( pvEntry & entry )
{
pvEntry * pE;
pE = this->stringResTbl.remove ( entry );
assert ( pE == &entry );
}
inline double exPV::getScanPeriod ()
{
double curPeriod = this->info.getScanPeriod ();
if ( ! this->interest ) {
curPeriod *= 10.0L;
}
return curPeriod;
}
inline caStatus exPV::readNoCtx ( smartGDDPointer pProtoIn )
{
return this->ft.read ( *this, *pProtoIn );
}
inline const pvInfo & exPV::getPVInfo ()
{
return this->info;
}
inline const char * exPV::getName () const
{
return this->info.getName();
}
inline void exServer::removeIO()
{
if ( this->simultAsychIOCount > 0u ) {
this->simultAsychIOCount--;
}
else {
fprintf ( stderr,
"simultAsychIOCount underflow?\n" );
}
}
inline unsigned exServer :: maxSimultAsyncIO () const
{
return this->_maxSimultAsyncIO;
}
inline exChannel::exChannel ( const casCtx & ctxIn ) :
casChannel(ctxIn)
{
}
@@ -1,264 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "exServer.h"
#include "gddApps.h"
#define myPI 3.14159265358979323846
//
// SUN C++ does not have RAND_MAX yet
//
#if ! defined(RAND_MAX)
//
// Apparently SUN C++ is using the SYSV version of rand
//
# if 0
# define RAND_MAX INT_MAX
# else
# define RAND_MAX SHRT_MAX
# endif
#endif
//
// special gddDestructor guarantees same form of new and delete
//
class exVecDestructor: public gddDestructor {
virtual void run (void *);
};
//
// exVectorPV::maxDimension()
//
unsigned exVectorPV::maxDimension() const
{
return 1u;
}
//
// exVectorPV::maxBound()
//
aitIndex exVectorPV::maxBound (unsigned dimension) const
{
if (dimension==0u) {
return this->info.getCapacity();
}
else {
return 0u;
}
}
//
// exVectorPV::scan
//
void exVectorPV::scan()
{
static epicsTime startTime = epicsTime::getCurrent();
// update current time
//
this->currentTime = epicsTime::getCurrent();
// demonstrate a changing array size
unsigned ramp = 15 & (unsigned) (this->currentTime - startTime);
unsigned newSize = this->info.getCapacity();
if (newSize > ramp) {
newSize -= ramp;
}
smartGDDPointer pDD = new gddAtomic (gddAppType_value, aitEnumFloat64,
1u, newSize);
if ( ! pDD.valid () ) {
return;
}
//
// smart pointer class manages reference count after this point
//
gddStatus gdds = pDD->unreference();
assert(!gdds);
//
// allocate array buffer
//
aitFloat64 * pF = new aitFloat64 [newSize];
if (!pF) {
return;
}
exVecDestructor * pDest = new exVecDestructor;
if (!pDest) {
delete [] pF;
return;
}
//
// install the buffer into the DD
// (do this before we increment pF)
//
pDD->putRef(pF, pDest);
//
// double check for reasonable bounds on the
// current value
//
const aitFloat64 *pCF = NULL, *pCFE = NULL;
if (this->pValue.valid () &&
this->pValue->dimension() == 1u) {
const gddBounds *pB = this->pValue->getBounds();
pCF = *this->pValue;
pCFE = &pCF[pB->size()];
}
aitFloat64 * pFE = &pF[newSize];
while (pF < pFE) {
double radians = (rand () * 2.0 * myPI)/RAND_MAX;
double newValue;
if (pCF && pCF < pCFE) {
newValue = *pCF++;
}
else {
newValue = 0.0f;
}
newValue += (sin (radians) / 10.0);
double limit = this->info.getHopr();
newValue = epicsMin (newValue, limit);
limit = this->info.getLopr();
newValue = epicsMax (newValue, limit);
*pF++ = newValue;
}
aitTimeStamp gddts = this->currentTime;
pDD->setTimeStamp ( & gddts );
caStatus status = this->update ( *pDD );
this->info.setElementCount(newSize);
if ( status != S_casApp_success ) {
errMessage (status, "vector scan update failed\n");
}
}
//
// exVectorPV::updateValue ()
//
// NOTES:
// 1) This should have a test which verifies that the
// incoming value in all of its various data types can
// be translated into a real number?
// 2) We prefer to unreference the old PV value here and
// reference the incomming value because this will
// result in value change events each retaining an
// independent value on the event queue. With large arrays
// this may result in too much memory consumtion on
// the event queue.
//
caStatus exVectorPV::updateValue ( const gdd & value )
{
aitUint32 newSize = 0;
//
// Check bounds of incoming request
// (and see if we are replacing all elements -
// replaceOk==true)
//
// Perhaps much of this is unnecessary since the
// server lib checks the bounds of all requests
//
if ( value.isAtomic()) {
if ( value.dimension() != 1u ) {
return S_casApp_badDimension;
}
const gddBounds* pb = value.getBounds ();
if ( pb[0u].first() != 0u ) {
return S_casApp_outOfBounds;
}
newSize = pb[0u].size();
if ( newSize > this->info.getCapacity() ) {
return S_casApp_outOfBounds;
}
}
else if ( ! value.isScalar() ) {
//
// no containers
//
return S_casApp_outOfBounds;
}
//
// Create a new array data descriptor
// (so that old values that may be referenced on the
// event queue are not replaced)
//
smartGDDPointer pNewValue ( new gddAtomic ( gddAppType_value, aitEnumFloat64,
1u, newSize ) );
if ( ! pNewValue.valid() ) {
return S_casApp_noMemory;
}
//
// smart pointer class takes care of the reference count
// from here down
//
gddStatus gdds = pNewValue->unreference( );
assert ( ! gdds );
//
// allocate array buffer
//
aitFloat64 * pF = new aitFloat64 [newSize];
if (!pF) {
return S_casApp_noMemory;
}
//
// Install (and initialize) array buffer
// if no old values exist
//
for ( unsigned i = 0u; i < newSize; i++ ) {
pF[i] = 0.0f;
}
exVecDestructor * pDest = new exVecDestructor;
if (!pDest) {
delete [] pF;
return S_casApp_noMemory;
}
//
// install the buffer into the DD
// (do this before we increment pF)
//
pNewValue->putRef ( pF, pDest );
//
// copy in the values that they are writing
//
gdds = pNewValue->put( & value );
if ( gdds ) {
return S_cas_noConvert;
}
this->pValue = pNewValue;
this->info.setElementCount(newSize);
return S_casApp_success;
}
//
// exVecDestructor::run()
//
// special gddDestructor guarantees same form of new and delete
//
void exVecDestructor::run ( void *pUntyped )
{
aitFloat64 * pf = reinterpret_cast < aitFloat64 * > ( pUntyped );
delete [] pf;
}
-151
View File
@@ -1,151 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "envDefs.h"
#include "errlog.h"
#include "exServer.h"
#include "fdManager.h"
//
// main()
// (example single threaded ca server tool main loop)
//
extern int main ( int argc, const char **argv )
{
epicsTime begin (epicsTime::getCurrent());
exServer *pCAS;
unsigned debugLevel = 0u;
double executionTime = 0.0;
double asyncDelay = 0.1;
char pvPrefix[128] = "";
unsigned aliasCount = 1u;
unsigned scanOn = true;
unsigned syncScan = true;
char arraySize[64] = "";
bool forever = true;
unsigned maxSimultAsyncIO = 1000u;
int i;
i = 1;
while ( i < argc ) {
if ( strcmp ( argv[i], "-d" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%u", & debugLevel ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i],"-t" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%lf", & executionTime ) == 1 ) {
forever = false;
i += 2;
continue;
}
}
if ( strcmp ( argv[i], "-p" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%127s", pvPrefix ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i], "-c" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%u", & aliasCount ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i], "-s" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%u", & scanOn ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i], "-a" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%63s", arraySize ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i],"-ss" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%u", & syncScan ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i],"-ad" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%lf", & asyncDelay ) == 1 ) {
i += 2;
continue;
}
}
if ( strcmp ( argv[i],"-an" ) == 0 ) {
if ( i+1 < argc && sscanf ( argv[i+1], "%u", & maxSimultAsyncIO ) == 1 ) {
i += 2;
continue;
}
}
printf ( "\"%s\"?\n", argv[i] );
if ( i + 1 < argc ) {
printf ( "\"%s\"?\n", argv[i+1] );
}
printf (
"usage: %s [-d <debug level> -t <execution time> -p <PV name prefix> "
"-c <numbered alias count> -s <1=scan on (default), 0=scan off> "
"-ss <1=synchronous scan (default), 0=asynchronous scan> "
"-a <max array size> -ad <async delay> "
"-an <max simultaneous async>\n",
argv[0]);
return (1);
}
if ( arraySize[0] != '\0' ) {
epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", arraySize );
}
try {
pCAS = new exServer ( pvPrefix, aliasCount,
scanOn != 0, syncScan == 0, asyncDelay,
maxSimultAsyncIO );
}
catch ( ... ) {
errlogPrintf ( "Server initialization error\n" );
errlogFlush ();
return (-1);
}
pCAS->setDebugLevel(debugLevel);
if ( forever ) {
//
// loop here forever
//
while (true) {
fileDescriptorManager.process(1000.0);
}
}
else {
double delay = epicsTime::getCurrent() - begin;
//
// loop here untill the specified execution time
// expires
//
while ( delay < executionTime ) {
fileDescriptorManager.process ( executionTime - delay );
delay = epicsTime::getCurrent() - begin;
}
}
//pCAS->show(2u);
delete pCAS;
errlogFlush ();
return (0);
}
-844
View File
@@ -1,844 +0,0 @@
file {
name="test.dl"
}
display {
magic="305419896"
majv="2"
mnrv="4"
ndyng="0"
npc="5"
nstr="8"
ndynamic="12"
nplot="0"
nrd="0"
nes="0"
nkd="0"
object {
x="0"
y="0"
width="421"
height="306"
}
clr="0"
bclr="1"
nwords_dspy="1106"
nwords_sta="28"
nwords_cmap="36"
nwords_crules="106"
odyng="306"
osta="278"
odynamic="306"
oplot="1106"
ord="1106"
oes="1106"
okd="1106"
opc="58"
ostr="88"
ocmap="136"
ocrules="172"
style="solid"
fill="outline"
width="0"
clrmod="static"
vismod="static"
clrrule="alarm"
pv=""
cmap=""
}
"<<color map>>" {
ncolors="8"
dl_color {
r="255"
g="255"
b="255"
inten="255"
blink="off"
RISCpad="128"
}
dl_color {
r="0"
g="0"
b="0"
inten="0"
blink="off"
RISCpad="75"
}
dl_color {
r="255"
g="0"
b="0"
inten="255"
blink="off"
RISCpad="-14684"
}
dl_color {
r="255"
g="0"
b="0"
inten="255"
blink="on"
RISCpad="14744"
}
dl_color {
r="255"
g="255"
b="0"
inten="255"
blink="off"
RISCpad="-16536"
}
dl_color {
r="255"
g="255"
b="0"
inten="255"
blink="on"
RISCpad="-15536"
}
dl_color {
r="0"
g="0"
b="255"
inten="255"
blink="off"
RISCpad="-28408"
}
dl_color {
r="0"
g="0"
b="255"
inten="255"
blink="on"
RISCpad="0"
}
}
"<<color rules>>" {
nrules="1"
dl_color_rule {
name="alarm"
info[0] {
chan="$(C).SEVR"
value="MAJOR"
connector="use"
comparator="equals"
clr="2"
RISCpad="0"
}
info[1] {
chan="$(C).SEVR"
value="MINOR"
connector="use"
comparator="equals"
clr="4"
RISCpad="127"
}
info[2] {
chan="$(C).SEVR"
value="INFO"
connector="use"
comparator="equals"
clr="6"
RISCpad="44"
}
info[3] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="-128"
}
info[4] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="-1"
}
info[5] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="-104"
}
info[6] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="-1"
}
info[7] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="8"
}
info[8] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="120"
}
info[9] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="1"
}
info[10] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="7"
}
info[11] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="19"
}
info[12] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="48"
}
info[13] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="28"
}
info[14] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="-88"
}
info[15] {
chan=""
value=""
connector="use"
comparator="equals"
clr="1"
RISCpad="0"
}
fg_enable="on"
bg_enable="on"
default_fg="0"
default_bg="1"
}
}
"<<basic attribute>>" {
attr {
clr="0"
style="solid"
fill="outline"
width="0"
}
}
"text" {
object {
x="44"
y="16"
width="104"
height="14"
groupid="0"
}
textix="Sync"
align="horiz. left"
RISC_pad="0"
}
"text" {
object {
x="260"
y="13"
width="92"
height="17"
groupid="0"
}
textix="Async"
align="horiz. left"
RISC_pad="0"
}
"indicator" {
object {
x="15"
y="88"
width="170"
height="22"
groupid="0"
}
monitor {
chan="fred"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
RISC_pad="0"
}
"text update" {
object {
x="16"
y="133"
width="169"
height="17"
groupid="0"
}
monitor {
chan="fred"
clr="0"
bclr="1"
label="none"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="append"
decorate="none"
convertFunc=""
convertParams=""
}
align="horiz. left"
format="decimal"
}
"valuator" {
object {
x="15"
y="43"
width="168"
height="26"
groupid="0"
}
control {
chan="fred"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
gain="coarse"
sendMode="send on motion"
increment="0"
}
"indicator" {
object {
x="215"
y="81"
width="170"
height="30"
groupid="0"
}
monitor {
chan="freddy"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
RISC_pad="0"
}
"text update" {
object {
x="216"
y="133"
width="171"
height="18"
groupid="0"
}
monitor {
chan="freddy"
clr="0"
bclr="1"
label="none"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="append"
decorate="none"
convertFunc=""
convertParams=""
}
align="horiz. left"
format="decimal"
}
"valuator" {
object {
x="215"
y="43"
width="168"
height="28"
groupid="0"
}
control {
chan="freddy"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
gain="coarse"
sendMode="send on motion"
increment="0"
}
"indicator" {
object {
x="16"
y="225"
width="171"
height="19"
groupid="0"
}
monitor {
chan="jane"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
RISC_pad="0"
}
"text update" {
object {
x="17"
y="259"
width="170"
height="20"
groupid="0"
}
monitor {
chan="jane"
clr="0"
bclr="1"
label="none"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="append"
decorate="none"
convertFunc=""
convertParams=""
}
align="horiz. left"
format="decimal"
}
"valuator" {
object {
x="15"
y="187"
width="170"
height="19"
groupid="0"
}
control {
chan="jane"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
gain="coarse"
sendMode="send on motion"
increment="0"
}
"indicator" {
object {
x="219"
y="218"
width="173"
height="23"
groupid="0"
}
monitor {
chan="janet"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
RISC_pad="0"
}
"text update" {
object {
x="220"
y="257"
width="174"
height="20"
groupid="0"
}
monitor {
chan="janet"
clr="0"
bclr="1"
label="none"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="append"
decorate="none"
convertFunc=""
convertParams=""
}
align="horiz. left"
format="decimal"
}
"valuator" {
object {
x="219"
y="188"
width="171"
height="21"
groupid="0"
}
control {
chan="janet"
clr="0"
bclr="1"
label="limits"
clrmod="static"
rulechan[0] = ""
rulechan[1] = ""
rulechan[2] = ""
rulechan[3] = ""
rulechan[4] = ""
rulechan[5] = ""
rulechan[6] = ""
rulechan[7] = ""
rulechan[8] = ""
rulechan[9] = ""
rulechan[10] = ""
rulechan[11] = ""
rulechan[12] = ""
rulechan[13] = ""
rulechan[14] = ""
rulechan[15] = ""
clrrule="alarm"
clrargs=""
rulecolorbg="0"
rulecolorfg="0"
hdl="0"
ldl="0"
prec="-1"
newunits=""
units="none"
decorate="none"
convertFunc=""
convertParams=""
}
direction="down"
gain="coarse"
sendMode="send on motion"
increment="0"
}
@@ -1,78 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Author: Jeff HIll (LANL)
//
#include <vxWorks.h>
#include <taskLib.h>
#include "exServer.h"
//
// so we can call this from the vxWorks shell
//
extern "C" {
exServer *pExampleCAS;
//
// excas ()
// (vxWorks example server entry point)
//
int excas (unsigned debugLevel, unsigned delaySec)
{
epicsTime begin(epicsTime::getCurrent());
exServer *pCAS;
pCAS = new exServer(32u,5u,500u);
if (!pCAS) {
return (-1);
}
pCAS->setDebugLevel(debugLevel);
pExampleCAS = pCAS;
if (delaySec==0u) {
//
// loop here forever
//
while (1) {
taskDelay(10);
}
}
else {
epicsTime total( ((float)delaySec) );
epicsTime delay(epicsTime::getCurrent() - begin);
//
// loop here untill the specified execution time
// expires
//
while (delay < total) {
taskDelay(10);
delay = epicsTime::getCurrent() - begin;
}
}
pCAS->show(debugLevel);
pExampleCAS = NULL;
delete pCAS;
return 0;
}
int excasShow(unsigned level)
{
if (pExampleCAS!=NULL) {
pExampleCAS->show(level);
}
return 0;
}
} // extern "C"
-29
View File
@@ -1,29 +0,0 @@
# CONFIG - Load build configuration data
#
# Do not make changes to this file!
# Allow user to override where the build rules come from
RULES = $(EPICS_BASE)
# RELEASE files point to other application tops
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override the Base definition:
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain other build configuration settings
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
@@ -1,43 +0,0 @@
# CONFIG_SITE
# Make any application-specific changes to the EPICS build
# configuration variables in this file.
#
# Host/target specific settings can be specified in files named
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building even if conflicts are found.
CHECK_RELEASE = YES
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc32
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</absolute/path/to/install/top>
# Set this when the IOC and build host use different paths
# to the install location. This may be needed to boot from
# a Microsoft FTP server say, or on some NFS configurations.
#IOCS_APPL_TOP = </IOC's/absolute/path/to/install/top>
# For application debugging purposes, override the HOST_OPT and/
# or CROSS_OPT settings from base/configure/CONFIG_SITE
#HOST_OPT = NO
#CROSS_OPT = NO
# These allow developers to override the CONFIG_SITE variable
# settings without having to modify the configure/CONFIG_SITE
# file itself.
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
-8
View File
@@ -1,8 +0,0 @@
TOP=..
include $(TOP)/configure/CONFIG
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
include $(TOP)/configure/RULES
-43
View File
@@ -1,43 +0,0 @@
# RELEASE - Location of external support modules
#
# IF YOU MAKE ANY CHANGES to this file you must subsequently
# do a "gnumake rebuild" in this application's top level
# directory.
#
# The build process does not check dependencies against files
# that are outside this application, thus you should do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
#
# This file is parsed by both GNUmake and an EPICS Perl script,
# so it can ONLY contain definititions of paths to other support
# modules, variable definitions that are used in module paths,
# and include statements that pull in other RELEASE files.
# Variables may be used before their values have been set.
# Build variables that are NOT used in paths should be set in
# the CONFIG_SITE file.
# Variables and paths to dependent modules:
#MODULES = /path/to/modules
#MYMODULE = $(MODULES)/my-module
# If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ = $(MODULES)/seq-ver
# EPICS_BASE should appear last so earlier modules can override stuff:
EPICS_BASE = _EPICS_BASE_
# Set RULES here if you want to use build rules from somewhere
# other than EPICS_BASE:
#RULES = $(MODULES)/build-rules
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local
-include $(TOP)/configure/RELEASE.local
-6
View File
@@ -1,6 +0,0 @@
# RULES
include $(CONFIG)/RULES
# Library should be rebuilt because LIBOBJS may have changed.
$(LIBNAME): ../Makefile
@@ -1,2 +0,0 @@
#RULES.ioc
include $(CONFIG)/RULES.ioc
@@ -1,2 +0,0 @@
#RULES_DIRS
include $(CONFIG)/RULES_DIRS
@@ -1,3 +0,0 @@
#RULES_TOP
include $(CONFIG)/RULES_TOP
@@ -1,19 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS BELOW HERE
# Install databases, templates & substitutions like this
DB += dbExample1.db
DB += dbExample2.db
DB += _APPNAME_Version.db
DB += dbSubExample.db
DB += user.substitutions
# If <anyname>.db template is not named <anyname>*.template add
# <anyname>_TEMPLATE = <templatename>
include $(TOP)/configure/RULES
#----------------------------------------
# ADD EXTRA GNUMAKE RULES BELOW HERE
@@ -1,6 +0,0 @@
record(lsi, "$(user):_APPNAME_:version") {
field(DTYP, "_APPNAME_ version")
field(DESC, "Version string")
field(SIZV, "$(SIZV=200)")
field(PINI, "YES")
}
@@ -1,62 +0,0 @@
record(ai, "$(user):aiExample")
{
field(DESC, "Analog input")
field(INP, "$(user):calcExample.VAL NPP NMS")
field(EGUF, "10")
field(EGU, "Counts")
field(HOPR, "10")
field(LOPR, "0")
field(HIHI, "8")
field(HIGH, "6")
field(LOW, "4")
field(LOLO, "2")
field(HHSV, "MAJOR")
field(HSV, "MINOR")
field(LSV, "MINOR")
field(LLSV, "MAJOR")
}
record(calc, "$(user):calcExample")
{
field(DESC, "Counter")
field(SCAN,"1 second")
field(FLNK, "$(user):aiExample")
field(CALC, "(A<B)?(A+C):D")
field(INPA, "$(user):calcExample.VAL NPP NMS")
field(INPB, "9")
field(INPC, "1")
field(INPD, "0")
field(EGU, "Counts")
field(HOPR, "10")
field(HIHI, "8")
field(HIGH, "6")
field(LOW, "4")
field(LOLO, "2")
field(HHSV, "MAJOR")
field(HSV, "MINOR")
field(LSV, "MINOR")
field(LLSV, "MAJOR")
}
record(xxx, "$(user):xxxExample")
{
field(DESC, "xxx record")
field(EGU, "Counts")
field(HOPR, "10")
field(HIHI, "8")
field(HIGH, "6")
field(LOW, "4")
field(LOLO, "2")
field(HHSV, "MAJOR")
field(HSV, "MINOR")
field(LSV, "MINOR")
field(LLSV, "MAJOR")
}
record(compress,"$(user):compressExample")
{
field(DESC, "Circular buffer")
field(INP,"$(user):aiExample.VAL CP NMS")
field(ALG,"Circular Buffer")
field(NSAM,"10")
field(HOPR,"10")
field(EGU,"Counts")
}
@@ -1,40 +0,0 @@
record(calc, "$(user):calcExample$(no)")
{
alias("$(user):calc$(no)")
field(DESC, "Counter No. $(no)")
field(SCAN,"$(scan)")
field(FLNK, "$(user):aiExample$(no)")
field(CALC, "(A<B)?(A+C):D")
field(INPA, "$(user):calcExample$(no).VAL NPP NMS")
field(INPB, "9")
field(INPC, "1")
field(INPD, "0")
field(EGU, "Counts")
field(HOPR, "10")
field(HIHI, "8")
field(HIGH, "6")
field(LOW, "4")
field(LOLO, "2")
field(HHSV, "MAJOR")
field(HSV, "MINOR")
field(LSV, "MINOR")
field(LLSV, "MAJOR")
}
record(ai, "$(user):aiExample$(no)")
{
field(DESC, "Analog input No. $(no)")
field(INP, "$(user):calcExample$(no).VAL NPP NMS")
field(EGUF, "10")
field(EGU, "Counts")
field(HOPR, "10")
field(LOPR, "0")
field(HIHI, "8")
field(HIGH, "6")
field(LOW, "4")
field(LOLO, "2")
field(HHSV, "MAJOR")
field(HSV, "MINOR")
field(LSV, "MINOR")
field(LLSV, "MAJOR")
}
alias("$(user):aiExample$(no)","$(user):ai$(no)")
@@ -1,13 +0,0 @@
record(sub,"$(user):subExample")
{
field(INAM,"mySubInit")
field(SNAM,"mySubProcess")
}
record(aSub,"$(user):aSubExample")
{
field(INAM,"myAsubInit")
field(SNAM,"myAsubProcess")
field(FTA,"DOUBLE")
field(NOA,"10")
field(INPA,"$(user):compressExample CPP")
}
@@ -1,12 +0,0 @@
# Example substitutions file
file "db/dbExample1.db" {
{ user = "_USER_" }
}
file db/dbExample2.db {
pattern { user, no, scan }
{ "_USER_", 1, "1 second" }
{ "_USER_", 2, "2 second" }
{ "_USER_", 3, "5 second" }
}
@@ -1,8 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*))
include $(TOP)/configure/RULES_DIRS
@@ -1,91 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS BELOW HERE
# Use typed rset structure (see 3.16.1 release notes)
USR_CPPFLAGS += -DUSE_TYPED_RSET
# xxxRecord.h will be created from xxxRecord.dbd
DBDINC += xxxRecord
# Install xxxSupport.dbd into <top>/dbd
DBD += xxxSupport.dbd
# Build an IOC support library
LIBRARY_IOC += _APPNAME_Support
# Compile and add code to the support library
_APPNAME_Support_SRCS += xxxRecord.c
_APPNAME_Support_SRCS += devXxxSoft.c
# Link locally-provided code into the support library,
# rather than directly into the IOC application, that
# causes problems on Windows DLL builds
_APPNAME_Support_SRCS += dbSubExample.c
_APPNAME_Support_SRCS += dev_APPNAME_Version.c
_APPNAME_Support_SRCS += _APPNAME_Hello.c
_APPNAME_Support_SRCS += initTrace.c
_APPNAME_Support_LIBS += $(EPICS_BASE_IOC_LIBS)
# Auto-generate a header file containing a version string.
# Version comes from the VCS if available, else date+time.
GENVERSION = _APPNAME_Version.h
# Macro name
GENVERSIONMACRO = _APPNAME_VERSION
# Build the IOC application
PROD_IOC = _APPNAME_
# _APPNAME_.dbd will be created and installed
DBD += _APPNAME_.dbd
# _APPNAME_.dbd will include these files:
_APPNAME__DBD += base.dbd
_APPNAME__DBD += xxxSupport.dbd
_APPNAME__DBD += dbSubExample.dbd
_APPNAME__DBD += dev_APPNAME_Version.dbd
_APPNAME__DBD += _APPNAME_Hello.dbd
_APPNAME__DBD += initTrace.dbd
# _APPNAME__registerRecordDeviceDriver.cpp derives from _APPNAME_.dbd
_APPNAME__SRCS += _APPNAME__registerRecordDeviceDriver.cpp
# Build the main IOC entry point where needed
_APPNAME__SRCS_DEFAULT += _APPNAME_Main.cpp
_APPNAME__SRCS_vxWorks += -nil-
# Link in the code from our support library
_APPNAME__LIBS += _APPNAME_Support
# To build SNL programs, SNCSEQ must be defined
# in the <top>/configure/RELEASE file
ifneq ($(SNCSEQ),)
# Build sncExample into _APPNAME_Support
sncExample_SNCFLAGS += +r
_APPNAME__DBD += sncExample.dbd
# A .stt sequence program is *not* pre-processed:
_APPNAME_Support_SRCS += sncExample.stt
_APPNAME_Support_LIBS += seq pv
_APPNAME__LIBS += seq pv
# Build sncProgram as a standalone program
PROD_HOST += sncProgram
sncProgram_SNCFLAGS += +m
# A .st sequence program *is* pre-processed:
sncProgram_SRCS += sncProgram.st
sncProgram_LIBS += seq pv
sncProgram_LIBS += $(EPICS_BASE_HOST_LIBS)
endif
# Finally link IOC to the EPICS Base libraries
_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD EXTRA GNUMAKE RULES BELOW HERE
# Explicit dependency needed for generated header file
dev_APPNAME_Version$(DEP): $(COMMON_DIR)/$(GENVERSION)
@@ -1,31 +0,0 @@
/* Example showing how to register a new command with iocsh */
#include <stdio.h>
#include <epicsExport.h>
#include <iocsh.h>
/* This is the command, which the vxWorks shell will call directly */
void hello(const char *name) {
if (name) {
printf("Hello %s, from _APPNAME_\n", name);
} else {
puts("Hello from _APPNAME_");
}
}
/* Information needed by iocsh */
static const iocshArg helloArg0 = {"name", iocshArgString};
static const iocshArg *helloArgs[] = {&helloArg0};
static const iocshFuncDef helloFuncDef = {"hello", 1, helloArgs};
/* Wrapper called by iocsh, selects the argument types that hello needs */
static void helloCallFunc(const iocshArgBuf *args) {
hello(args[0].sval);
}
/* Registration routine, runs at startup */
static void helloRegister(void) {
iocshRegister(&helloFuncDef, helloCallFunc);
}
epicsExportRegistrar(helloRegister);
@@ -1 +0,0 @@
registrar(helloRegister)
@@ -1,23 +0,0 @@
/* _APPNAME_Main.cpp */
/* Author: Marty Kraimer Date: 17MAR2000 */
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "epicsExit.h"
#include "epicsThread.h"
#include "iocsh.h"
int main(int argc,char *argv[])
{
if(argc>=2) {
iocsh(argv[1]);
epicsThreadSleep(.2);
}
iocsh(NULL);
epicsExit(0);
return(0);
}
@@ -1,49 +0,0 @@
#include <stdio.h>
#include <dbDefs.h>
#include <registryFunction.h>
#include <subRecord.h>
#include <aSubRecord.h>
#include <epicsExport.h>
int mySubDebug;
static long mySubInit(subRecord *precord)
{
if (mySubDebug)
printf("Record %s called mySubInit(%p)\n",
precord->name, (void*) precord);
return 0;
}
static long mySubProcess(subRecord *precord)
{
if (mySubDebug)
printf("Record %s called mySubProcess(%p)\n",
precord->name, (void*) precord);
return 0;
}
static long myAsubInit(aSubRecord *precord)
{
if (mySubDebug)
printf("Record %s called myAsubInit(%p)\n",
precord->name, (void*) precord);
return 0;
}
static long myAsubProcess(aSubRecord *precord)
{
if (mySubDebug)
printf("Record %s called myAsubProcess(%p)\n",
precord->name, (void*) precord);
return 0;
}
/* Register these symbols for use by IOC code: */
epicsExportAddress(int, mySubDebug);
epicsRegisterFunction(mySubInit);
epicsRegisterFunction(mySubProcess);
epicsRegisterFunction(myAsubInit);
epicsRegisterFunction(myAsubProcess);
@@ -1,5 +0,0 @@
variable(mySubDebug)
function(mySubInit)
function(mySubProcess)
function(myAsubInit)
function(myAsubProcess)
@@ -1,58 +0,0 @@
/* devXxxSoft.c */
/* Example device support module */
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "alarm.h"
#include "cvtTable.h"
#include "dbDefs.h"
#include "dbAccess.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
#include "link.h"
#include "xxxRecord.h"
#include "epicsExport.h"
/*Create the dset for devXxxSoft */
static long init_record();
static long read_xxx();
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_xxx;
}devXxxSoft={
5,
NULL,
NULL,
init_record,
NULL,
read_xxx,
};
epicsExportAddress(dset,devXxxSoft);
static long init_record(pxxx)
struct xxxRecord *pxxx;
{
if(recGblInitConstantLink(&pxxx->inp,DBF_DOUBLE,&pxxx->val))
pxxx->udf = FALSE;
return(0);
}
static long read_xxx(pxxx)
struct xxxRecord *pxxx;
{
long status;
status = dbGetLink(&(pxxx->inp),DBF_DOUBLE, &(pxxx->val),0,0);
/*If return was succesful then set undefined false*/
if(!status) pxxx->udf = FALSE;
return(0);
}
@@ -1,38 +0,0 @@
/* dev_APPNAME_Version.c */
/* Example device support for the lsi (long string input) record
* providing the module version string as the value
*/
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "devSup.h"
#include "lsiRecord.h"
#include "_APPNAME_Version.h"
/* must be last include */
#include "epicsExport.h"
const char const version[] = _APPNAME_VERSION;
static long read_string(lsiRecord *prec)
{
size_t N = sizeof version;
char *buf = prec->val;
if (N > prec->sizv)
N = prec->sizv;
prec->len = N;
memcpy(buf, version, N);
buf[N - 1] = '\0';
return 0;
}
static lsidset dev_CSAFEAPPNAME_Version = {
5, NULL, NULL, NULL, NULL, read_string
};
epicsExportAddress(dset,dev_CSAFEAPPNAME_Version);
@@ -1 +0,0 @@
device(lsi,INST_IO,dev_CSAFEAPPNAME_Version,"_APPNAME_ version")
@@ -1,39 +0,0 @@
/* initTrace.c */
/*
* An initHook routine to trace the iocInit() process.
* Prints out the name of each state as it is reached.
*/
#include <stdio.h>
#include "initHooks.h"
#include "epicsExport.h"
#include "iocsh.h"
static void trace(initHookState state) {
printf("iocInit: Reached %s\n", initHookName(state));
}
int traceIocInit(void) {
static int done = 0;
if (done)
return -1;
done = 1;
initHookRegister(trace);
puts("iocInit will be traced");
return 0;
}
static const iocshFuncDef traceInitFuncDef = {"traceIocInit", 0, NULL};
static void traceInitFunc(const iocshArgBuf *args) {
traceIocInit();
}
static void initTraceRegister(void) {
iocshRegister(&traceInitFuncDef, traceInitFunc);
}
epicsExportRegistrar(initTraceRegister);
@@ -1 +0,0 @@
registrar(initTraceRegister)
@@ -1 +0,0 @@
registrar(sncExampleRegistrar)
@@ -1,22 +0,0 @@
program sncExample
double v;
assign v to "{user}:aiExample";
monitor v;
ss ss1 {
state init {
when (delay(10)) {
printf("sncExample: Startup delay over\n");
} state low
}
state low {
when (v > 5.0) {
printf("sncExample: Changing to high\n");
} state high
}
state high {
when (v <= 5.0) {
printf("sncExample: Changing to low\n");
} state low
}
}
@@ -1 +0,0 @@
#include "../sncExample.stt"
@@ -1,273 +0,0 @@
/* xxxRecord.c */
/* Example record support module */
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "epicsMath.h"
#include "alarm.h"
#include "dbAccess.h"
#include "recGbl.h"
#include "dbEvent.h"
#include "dbDefs.h"
#include "dbAccess.h"
#include "devSup.h"
#include "errMdef.h"
#include "recSup.h"
#include "special.h"
#define GEN_SIZE_OFFSET
#include "xxxRecord.h"
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
/* Create RSET - Record Support Entry Table */
#define report NULL
#define initialize NULL
static long init_record(struct dbCommon *, int);
static long process(struct dbCommon *);
#define special NULL
#define get_value NULL
#define cvt_dbaddr NULL
#define get_array_info NULL
#define put_array_info NULL
static long get_units(DBADDR *, char *);
static long get_precision(const DBADDR *, long *);
#define get_enum_str NULL
#define get_enum_strs NULL
#define put_enum_str NULL
static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
rset xxxRSET={
RSETNUMBER,
report,
initialize,
init_record,
process,
special,
get_value,
cvt_dbaddr,
get_array_info,
put_array_info,
get_units,
get_precision,
get_enum_str,
get_enum_strs,
put_enum_str,
get_graphic_double,
get_control_double,
get_alarm_double
};
epicsExportAddress(rset,xxxRSET);
typedef struct xxxset { /* xxx input dset */
long number;
DEVSUPFUN dev_report;
DEVSUPFUN init;
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_xxx;
}xxxdset;
static void checkAlarms(xxxRecord *prec);
static void monitor(xxxRecord *prec);
static long init_record(struct dbCommon *pcommon, int pass)
{
xxxRecord *prec = (xxxRecord *)pcommon;
xxxdset *pdset;
long status;
if (pass==0) return(0);
if(!(pdset = (xxxdset *)(prec->dset))) {
recGblRecordError(S_dev_noDSET,(void *)prec,"xxx: init_record");
return(S_dev_noDSET);
}
/* must have read_xxx function defined */
if( (pdset->number < 5) || (pdset->read_xxx == NULL) ) {
recGblRecordError(S_dev_missingSup,(void *)prec,"xxx: init_record");
return(S_dev_missingSup);
}
if( pdset->init_record ) {
if((status=(*pdset->init_record)(prec))) return(status);
}
return(0);
}
static long process(struct dbCommon *pcommon)
{
xxxRecord *prec = (xxxRecord *)pcommon;
xxxdset *pdset = (xxxdset *)(prec->dset);
long status;
unsigned char pact=prec->pact;
if( (pdset==NULL) || (pdset->read_xxx==NULL) ) {
prec->pact=TRUE;
recGblRecordError(S_dev_missingSup,(void *)prec,"read_xxx");
return(S_dev_missingSup);
}
/* pact must not be set until after calling device support */
status=(*pdset->read_xxx)(prec);
/* check if device support set pact */
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStamp(prec);
/* check for alarms */
checkAlarms(prec);
/* check event list */
monitor(prec);
/* process the forward scan link record */
recGblFwdLink(prec);
prec->pact=FALSE;
return(status);
}
static long get_units(DBADDR *paddr, char *units)
{
xxxRecord *prec=(xxxRecord *)paddr->precord;
strncpy(units,prec->egu,DB_UNITS_SIZE);
return(0);
}
static long get_precision(const DBADDR *paddr, long *precision)
{
xxxRecord *prec=(xxxRecord *)paddr->precord;
*precision = prec->prec;
if(paddr->pfield == (void *)&prec->val) return(0);
recGblGetPrec(paddr,precision);
return(0);
}
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
xxxRecord *prec=(xxxRecord *)paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
if(fieldIndex == xxxRecordVAL
|| fieldIndex == xxxRecordHIHI
|| fieldIndex == xxxRecordHIGH
|| fieldIndex == xxxRecordLOW
|| fieldIndex == xxxRecordLOLO
|| fieldIndex == xxxRecordHOPR
|| fieldIndex == xxxRecordLOPR) {
pgd->upper_disp_limit = prec->hopr;
pgd->lower_disp_limit = prec->lopr;
} else recGblGetGraphicDouble(paddr,pgd);
return(0);
}
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
xxxRecord *prec=(xxxRecord *)paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
if(fieldIndex == xxxRecordVAL
|| fieldIndex == xxxRecordHIHI
|| fieldIndex == xxxRecordHIGH
|| fieldIndex == xxxRecordLOW
|| fieldIndex == xxxRecordLOLO) {
pcd->upper_ctrl_limit = prec->hopr;
pcd->lower_ctrl_limit = prec->lopr;
} else recGblGetControlDouble(paddr,pcd);
return(0);
}
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
{
xxxRecord *prec=(xxxRecord *)paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
if(fieldIndex == xxxRecordVAL) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
} else recGblGetAlarmDouble(paddr,pad);
return(0);
}
static void checkAlarms(xxxRecord *prec)
{
double val;
float hyst, lalm, hihi, high, low, lolo;
unsigned short hhsv, llsv, hsv, lsv;
if(prec->udf == TRUE ){
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
return;
}
hihi = prec->hihi; lolo = prec->lolo; high = prec->high; low = prec->low;
hhsv = prec->hhsv; llsv = prec->llsv; hsv = prec->hsv; lsv = prec->lsv;
val = prec->val; hyst = prec->hyst; lalm = prec->lalm;
/* alarm condition hihi */
if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){
if (recGblSetSevr(prec,HIHI_ALARM,prec->hhsv)) prec->lalm = hihi;
return;
}
/* alarm condition lolo */
if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){
if (recGblSetSevr(prec,LOLO_ALARM,prec->llsv)) prec->lalm = lolo;
return;
}
/* alarm condition high */
if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){
if (recGblSetSevr(prec,HIGH_ALARM,prec->hsv)) prec->lalm = high;
return;
}
/* alarm condition low */
if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){
if (recGblSetSevr(prec,LOW_ALARM,prec->lsv)) prec->lalm = low;
return;
}
/* we get here only if val is out of alarm by at least hyst */
prec->lalm = val;
return;
}
static void monitor(xxxRecord *prec)
{
unsigned short monitor_mask;
double delta;
monitor_mask = recGblResetAlarms(prec);
/* check for value change */
delta = prec->mlst - prec->val;
if(delta<0.0) delta = -delta;
if (delta > prec->mdel) {
/* post events for value change */
monitor_mask |= DBE_VALUE;
/* update last value monitored */
prec->mlst = prec->val;
}
/* check for archive change */
delta = prec->alst - prec->val;
if(delta<0.0) delta = -delta;
if (delta > prec->adel) {
/* post events on value field for archive change */
monitor_mask |= DBE_LOG;
/* update last archive value monitored */
prec->alst = prec->val;
}
/* send out monitors connected to the value field */
if (monitor_mask){
db_post_events(prec,&prec->val,monitor_mask);
}
return;
}
@@ -1,118 +0,0 @@
recordtype(xxx) {
include "dbCommon.dbd"
field(VAL,DBF_DOUBLE) {
prompt("Current EGU Value")
promptgroup("40 - Input")
asl(ASL0)
pp(TRUE)
}
field(INP,DBF_INLINK) {
prompt("Input Specification")
promptgroup("40 - Input")
special(SPC_NOMOD)
interest(1)
}
field(PREC,DBF_SHORT) {
prompt("Display Precision")
promptgroup("80 - Display")
interest(1)
}
field(EGU,DBF_STRING) {
prompt("Engineering Units")
promptgroup("80 - Display")
interest(1)
size(16)
}
field(HOPR,DBF_FLOAT) {
prompt("High Operating Range")
promptgroup("80 - Display")
interest(1)
}
field(LOPR,DBF_FLOAT) {
prompt("Low Operating Range")
promptgroup("80 - Display")
interest(1)
}
field(HIHI,DBF_FLOAT) {
prompt("Hihi Alarm Limit")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
}
field(LOLO,DBF_FLOAT) {
prompt("Lolo Alarm Limit")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
}
field(HIGH,DBF_FLOAT) {
prompt("High Alarm Limit")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
}
field(LOW,DBF_FLOAT) {
prompt("Low Alarm Limit")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
}
field(HHSV,DBF_MENU) {
prompt("Hihi Severity")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
menu(menuAlarmSevr)
}
field(LLSV,DBF_MENU) {
prompt("Lolo Severity")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
menu(menuAlarmSevr)
}
field(HSV,DBF_MENU) {
prompt("High Severity")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
menu(menuAlarmSevr)
}
field(LSV,DBF_MENU) {
prompt("Low Severity")
promptgroup("70 - Alarm")
pp(TRUE)
interest(1)
menu(menuAlarmSevr)
}
field(HYST,DBF_DOUBLE) {
prompt("Alarm Deadband")
promptgroup("70 - Alarm")
interest(1)
}
field(ADEL,DBF_DOUBLE) {
prompt("Archive Deadband")
promptgroup("80 - Display")
interest(1)
}
field(MDEL,DBF_DOUBLE) {
prompt("Monitor Deadband")
promptgroup("80 - Display")
interest(1)
}
field(LALM,DBF_DOUBLE) {
prompt("Last Value Alarmed")
special(SPC_NOMOD)
interest(3)
}
field(ALST,DBF_DOUBLE) {
prompt("Last Value Archived")
special(SPC_NOMOD)
interest(3)
}
field(MLST,DBF_DOUBLE) {
prompt("Last Val Monitored")
special(SPC_NOMOD)
interest(3)
}
}
@@ -1,2 +0,0 @@
include "xxxRecord.dbd"
device(xxx,CONSTANT,devXxxSoft,"SoftChannel")
@@ -1,6 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS += $(wildcard *ioc*)
DIRS += $(wildcard as*)
include $(CONFIG)/RULES_DIRS
@@ -1,4 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
TARGETS = envPaths
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths relPaths.sh
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = cdCommands
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths dllPath.bat
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths dllPath.bat
include $(TOP)/configure/RULES.ioc
@@ -1,9 +0,0 @@
To start the ioc from this directory execute the command
../../bin/_ARCH_/<appname> st.cmd
Alternatively make the st.cmd file directly executable with
chmod +x st.cmd
and check the executable name on the first line of the st.cmd file
You may need to change the name of the .dbd file given in the
st.cmd's dbLoadDatabase() command before starting the ioc.
@@ -1,6 +0,0 @@
Copy the startup script (st.cmd) and top level db and dbd directories and
contents to
<<TFTP_ROOT>>/epics/<<IOC hostname>>/
Then load the executable into the IOC (floppy disk, network boot, debugger,
etc.) and start it.
@@ -1,29 +0,0 @@
#!../../bin/_ARCH_/_APPNAME_
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
< envPaths
cd "${TOP}"
## Register all support components
dbLoadDatabase "dbd/_APPNAME_.dbd"
_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase
## Load record instances
dbLoadTemplate "db/user.substitutions"
dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_"
dbLoadRecords "db/dbSubExample.db", "user=_USER_"
#- Set this to see messages from mySub
#var mySubDebug 1
#- Run this to trace the stages of iocInit
#traceIocInit
cd "${TOP}/iocBoot/${IOC}"
iocInit
## Start any sequence programs
#seq sncExample, "user=_USER_"
@@ -1,26 +0,0 @@
#- Example RTEMS startup script
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths
## Register all support components
dbLoadDatabase("dbd/_APPNAME_.dbd")
_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase)
## Load record instances
dbLoadTemplate("db/user.substitutions")
dbLoadRecords("db/_APPNAME_Version.db", "user=_USER_")
dbLoadRecords("db/dbSubExample.db", "user=_USER_")
#- Set this to see messages from mySub
#var mySubDebug 1
#- Run this to trace the stages of iocInit
#traceIocInit
iocInit
## Start any sequence programs
#seq(sncExample, "user=_USER_")
@@ -1,36 +0,0 @@
#- Example vxWorks startup file
#- The following is needed if your board support package doesn't at boot time
#- automatically cd to the directory containing its startup script
#cd "_TOP_/iocBoot/_IOC_"
< cdCommands
#< ../nfsCommands
cd topbin
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
ld 0,0, "_APPNAME_.munch"
## Register all support components
cd top
dbLoadDatabase "dbd/_APPNAME_.dbd"
_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase
## Load record instances
dbLoadTemplate "db/user.substitutions"
dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_"
dbLoadRecords "db/dbSubExample.db", "user=_USER_"
#- Set this to see messages from mySub
#mySubDebug = 1
#- Run this to trace the stages of iocInit
#traceIocInit
cd startup
iocInit
## Start any sequence programs
#seq &sncExample, "user=_USER_"
@@ -1,26 +0,0 @@
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
@@ -1,29 +0,0 @@
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The nfsMount command has the form:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- You can also mount subdirectories as follows:
#- nfsMountAll("<host>")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
-18
View File
@@ -1,18 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#----------------------------------------------------
# Create and install (or just install) into <top>/db
# databases, templates, substitutions like this
#DB += xxx.db
#----------------------------------------------------
# If <anyname>.db template is not named <anyname>*.template add
# <anyname>_template = <templatename>
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
-8
View File
@@ -1,8 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*))
include $(TOP)/configure/RULES_DIRS
-42
View File
@@ -1,42 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#=============================
# Build the IOC application
PROD_IOC = _APPNAME_
# _APPNAME_.dbd will be created and installed
DBD += _APPNAME_.dbd
# _APPNAME_.dbd will be made up from these files:
_APPNAME__DBD += base.dbd
# Include dbd files from all support applications:
#_APPNAME__DBD += xxx.dbd
# Add all the support libraries needed by this IOC
#_APPNAME__LIBS += xxx
# _APPNAME__registerRecordDeviceDriver.cpp derives from _APPNAME_.dbd
_APPNAME__SRCS += _APPNAME__registerRecordDeviceDriver.cpp
# Build the main IOC entry point on workstation OSs.
_APPNAME__SRCS_DEFAULT += _APPNAME_Main.cpp
_APPNAME__SRCS_vxWorks += -nil-
# Add support from base/src/vxWorks if needed
#_APPNAME__OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
# Finally link to the EPICS Base libraries
_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS)
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
@@ -1,23 +0,0 @@
/* _APPNAME_Main.cpp */
/* Author: Marty Kraimer Date: 17MAR2000 */
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "epicsExit.h"
#include "epicsThread.h"
#include "iocsh.h"
int main(int argc,char *argv[])
{
if(argc>=2) {
iocsh(argv[1]);
epicsThreadSleep(.2);
}
iocsh(NULL);
epicsExit(0);
return(0);
}
-6
View File
@@ -1,6 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS += $(wildcard *ioc*)
DIRS += $(wildcard as*)
include $(CONFIG)/RULES_DIRS
@@ -1,4 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
TARGETS = envPaths
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths relPaths.sh
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = cdCommands
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths dllPath.bat
include $(TOP)/configure/RULES.ioc
@@ -1,5 +0,0 @@
TOP = ../..
include $(TOP)/configure/CONFIG
ARCH = _ARCH_
TARGETS = envPaths dllPath.bat
include $(TOP)/configure/RULES.ioc
@@ -1,21 +0,0 @@
#!../../bin/_ARCH_/_APPNAME_
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
< envPaths
cd "${TOP}"
## Register all support components
dbLoadDatabase "dbd/_APPNAME_.dbd"
_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase
## Load record instances
#dbLoadRecords("db/xxx.db","user=_USER_")
cd "${TOP}/iocBoot/${IOC}"
iocInit
## Start any sequence programs
#seq sncxxx,"user=_USER_"
@@ -1,18 +0,0 @@
#!../../bin/_ARCH_/_APPNAME_
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths
## Register all support components
dbLoadDatabase("../../dbd/_APPNAME_.dbd",0,0)
_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase)
## Load record instances
dbLoadRecords("../../db/_APPNAME_.db","user=_USER_")
iocInit()
## Start any sequence programs
#seq snc_APPNAME_,"user=_USER_"
@@ -1,19 +0,0 @@
#- Example RTEMS startup script
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths
## Register all support components
dbLoadDatabase("dbd/_APPNAME_.dbd")
_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase)
## Load record instances
#dbLoadTemplate("db/_APPNAME_.substitutions")
#dbLoadRecords("db/_APPNAME_.db", "user=_USER_")
iocInit
## Start any sequence programs
#seq(sncxxx, "user=_USER_")
@@ -1,29 +0,0 @@
#- Example vxWorks startup file
#- The following is needed if your board support package doesn't at boot time
#- automatically cd to the directory containing its startup script
#cd "_TOP_/iocBoot/_IOC_"
< cdCommands
#< ../nfsCommands
cd topbin
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
ld 0,0, "_APPNAME_.munch"
## Register all support components
cd top
dbLoadDatabase "dbd/_APPNAME_.dbd"
_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase
## Load record instances
#dbLoadTemplate "db/_APPNAME_.substitutions"
#dbLoadRecords "db/_APPNAME_.db", "user=_USER_"
cd startup
iocInit
## Start any sequence programs
#seq &sncxxx, "user=_USER_"
@@ -1,29 +0,0 @@
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The vxWorks nfsMount command has the form:
#- nfsMount("<host>")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
@@ -1,29 +0,0 @@
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The vxWorks nfsMount command has the form:
#- nfsMount("<host>")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
@@ -1,18 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#----------------------------------------------------
# Create and install (or just install) into <top>/db
# databases, templates, substitutions like this
#DB += xxx.db
#----------------------------------------------------
# If <anyname>.db template is not named <anyname>*.template add
# <anyname>_template = <templatename>
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
@@ -1,7 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*))
DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*))
include $(TOP)/configure/RULES_DIRS
@@ -1,28 +0,0 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#==================================================
# build a support library
LIBRARY_IOC += _APPNAME_
# xxxRecord.h will be created from xxxRecord.dbd
#DBDINC += xxxRecord
# install _APPNAME_.dbd into <top>/dbd
DBD += _APPNAME_.dbd
# specify all source files to be compiled and added to the library
#_APPNAME__SRCS += xxx
_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS)
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
@@ -1,6 +0,0 @@
# provide definitions such as
#include "xxxRecord.dbd"
#device(xxx,CONSTANT,devXxxSoft,"SoftChannel")
#driver(myDriver)
#registrar(myRegistrar)
#variable(myVariable)
-32
View File
@@ -1,32 +0,0 @@
TOP=../../..
include $(TOP)/configure/CONFIG
TEMPLATES_DIR = makeBaseExt
TEMPLATES += top/Makefile
TEMPLATES += top/README
TEMPLATES += top/configure/CONFIG
TEMPLATES += top/configure/CONFIG_SITE
TEMPLATES += top/configure/Makefile
TEMPLATES += top/configure/RELEASE
TEMPLATES += top/configure/RULES
TEMPLATES += top/configure/RULES_DIRS
TEMPLATES += top/configure/RULES_TOP
TEMPLATES += top/configure/RULES_PYTHON
TEMPLATES += top/configure/RULES_IDL
TEMPLATES += $(subst ../,,$(wildcard ../top/configure/os/CONFIG*))
TEMPLATES += top/src/Makefile
TEMPLATES += top/exampleExt/Makefile
TEMPLATES += top/exampleExt/caExample.c
TEMPLATES += top/exampleExt/RELEASE_NOTES.HTM
TEMPLATES += top/simpleExt/Makefile
SCRIPTS_HOST += makeBaseExt.pl
include $(TOP)/configure/RULES
-307
View File
@@ -1,307 +0,0 @@
#!/usr/bin/env perl
# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson
use Cwd;
use Getopt::Std;
use File::Copy;
use File::Find;
use File::Path;
$user = GetUser();
$cwd = cwd();
$eEXTTYPE = $ENV{EPICS_MBE_DEF_EXT_TYPE};
$eTOP = $ENV{EPICS_MBE_TEMPLATE_TOP};
$eBASE = $ENV{EPICS_MBE_BASE};
get_commandline_opts(); # Read and check options
$extname = "@ARGV";
#
# Declare two default callback routines for file copy plus two
# hook routines to add conversions
# These may be overriden within $top/$exttypename/Replace.pl
# First: the hooks
sub ReplaceFilenameHook { return $_[0]; }
sub ReplaceLineHook { return $_[0]; }
# ReplaceFilename
# called with the source (template) file or directory name, returns
# the "real" name (which gets the target after $top is removed)
# Empty string: Don't copy this file
sub ReplaceFilename { # (filename)
my($file) = $_[0];
$file =~ s|.*/CVS/?.*||; # Ignore CVS files
if ($ext) { # exttypenameExt itself is dynamic, too
$file =~ s|/$exttypename|/$extdir|;
$file =~ s|/$extdir/configure|/configure/$exttype|;
}
$file =~ s|_EXTNAME_|$extname|;
$file =~ s|_EXTTYPE_|$exttype|;
# We don't want the Replace overrides
$file =~ s|.*/$extdir/Replace.pl$||;
$file = ReplaceFilenameHook($file); # Call the user-defineable hook
return $file;
}
# ReplaceLine
# called with one line of a file, returns the line after replacing
# this and that
sub ReplaceLine { # (line)
my($line) = $_[0];
$line =~ s/_USER_/$user/o;
$line =~ s/_EPICS_BASE_/$epics_base/o;
$line =~ s/_ARCH_/$arch/o;
$line =~ s/_EXTNAME_/$extname/o;
$line =~ s/_EXTTYPE_/$exttype/o;
$line =~ s/_TEMPLATE_TOP_/$top/o;
$line = ReplaceLineHook($line); # Call the user-defineable hook
return $line;
}
# Source replace overrides for file copy
if (-r "$top/$exttypename/Replace.pl") {
require "$top/$exttypename/Replace.pl";
}
#
# Copy files and trees from <top> (non-Ext) if not present
#
opendir TOPDIR, "$top" or die "Can't open $top: $!";
foreach $f ( grep !/^\.\.?$|^[^\/]*(Ext)/, readdir TOPDIR ) {
if (-f "$f") {
CopyFile("$top/$f") unless (-e "$f");
} else {
$note = yes if ("$f" eq "src" && -e "$f");
find(\&FCopyTree, "$top/$f") unless (-e "$f");
}
}
closedir TOPDIR;
#
# Create ext directories (if any names given)
#
$cwdsave = $cwd;
$cwd = "$cwd/src";
foreach $ext ( @ARGV ) {
($extname = $ext) =~ s/Ext$//;
$extdir = $extname;
if (-d "src/$extdir") {
print "Extention $extname is already there!\n";
next;
}
print "Creating template structure "
. "for $extname (of type $exttypename)\n" if $Debug;
find(\&FCopyTree, "$top/$exttypename/");
if ($note) {
print "\nNOTE: You must add the line \"DIRS += $extname\" to src/Makefile.\n\n";
}
}
$cwd = $cwdsave;
exit 0; # END OF SCRIPT
#
# Get commandline options and check for validity
#
sub get_commandline_opts { #no args
($len = @ARGV) and getopts("ldit:T:b:a:") or Cleanup(1);
# Debug option
$Debug = 1 if $opt_d;
# Locate epics_base
my ($command) = UnixPath($0);
if ($opt_b) { # first choice is -b base
$epics_base = UnixPath($opt_b);
} elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE
open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE";
while (<IN>) {
chomp;
s/EPICS_BASE\s*=\s*// and $epics_base = UnixPath($_), break;
}
close IN;
} elsif ($eBASE) { # third choice is env var EPICS_MBE_BASE
$epics_base = UnixPath($eBASE);
} elsif ($command =~ m|/bin/|) { # assume script was called with full path to base
$epics_base = $command;
$epics_base =~ s|(/.*)/bin/.*makeBaseExt.*|$1|;
}
"$epics_base" or Cleanup(1, "Cannot find EPICS base");
# Locate template top directory
if ($opt_T) { # first choice is -T templ-top
$top = UnixPath($opt_T);
} elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE
open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE";
while (<IN>) {
chomp;
s/TEMPLATE_TOP\s*=\s*// and $top = UnixPath($_), break;
}
close IN;
}
if("$top" eq "") {
if ($eTOP) { # third choice is $ENV{EPICS_MBE_TEMPL_TOP}
$top = UnixPath($eTOP);
} else { # use templates from EPICS base
$top = $epics_base . "/templates/makeBaseExt/top";
}
}
"$top" or Cleanup(1, "Cannot find template top directory");
# Print extension type list?
if ($opt_l) {
ListExtTypes();
exit 0; # finished for -l command
}
# Extention template type
if ($opt_t) { # first choice is -t type
$exttype = $opt_t;
} elsif ($eEXTTYPE) { # second choice is $ENV{EPICS_DEFAULT_EXT_TYPE}
$exttype = $eEXTTYPE;
} elsif (-r "$top/defaultExt") {# third choice is (a link) in the $top dir
$exttype = "default";
} elsif (-r "$top/exampleExt") {# fourth choice is (a link) in the $top dir
$exttype = "example";
}
$exttype =~ s/Ext$//;
"$exttype" or Cleanup(1, "Cannot find default extension type");
$exttypename = $exttype . "Ext";
# Valid $exttypename?
unless (-r "$top/$exttypename") {
print "Template for extension type '$exttype' is unreadable or does not exist.\n";
ListExtTypes();
exit 1;
}
print "\nCommand line / environment options validated:\n"
. " Templ-Top: $top\n"
. "Templ-Type: $exttype\n"
. "Templ-Name: $exttypename\n"
. "EPICS-Base: $epics_base\n\n" if $Debug;
}
#
# List extension types
#
sub ListExtTypes { # no args
print "Valid extension types are:\n";
foreach $name (<$top/*Ext>) {
$name =~ s|$top/||;
$name =~ s|Ext||;
printf "\t$name\n" if ($name && -r "$top/$name" . "Ext");
}
}
#
# Copy a file with replacements
#
sub CopyFile { # (source)
$source = $_[0];
$target = ReplaceFilename($source);
if ($target) {
$target =~ s|$top/||;
open(INP, "<$source") and open(OUT, ">$target")
or die "$! Copying $source -> $target";
print "Copying file $source -> $target\n" if $Debug;
while (<INP>) {
print OUT ReplaceLine($_);
}
close INP; close OUT;
}
}
#
# Find() callback for file or structure copy
#
sub FCopyTree {
chdir $cwd; # Sigh
if (-d $File::Find::name
and ($dir = ReplaceFilename($File::Find::name))) {
$dir =~ s|$top/||;
print "Creating directory $dir\n" if $Debug;
mkpath($dir);
} else {
CopyFile($File::Find::name);
}
chdir $File::Find::dir;
}
#
# Cleanup and exit
#
sub Cleanup { # (return-code [ messsage-line1, line 2, ... ])
my ($rtncode, @message) = @_;
foreach $line ( @message ) {
print "$line\n";
}
print <<EOF;
Usage:
$0 -l [options]
$0 -t type [options] ext ...
create extension directories
where
ext Ext name
-t type Set the extension type (-l for a list of valid types)
If not specified, type is taken from environment
If not found in environment, \"default\" is used
-T top Set the template top directory (where the extension templates are)
If not specified, top path is taken from configure/RELEASE
If configure does not exist, top path is taken from environment
If not found in environment, the templates from EPICS base are used
-l List valid extension types for this installation
If this is specified the other options are not used
-b base Set the location of EPICS base (full path)
If not specified, base path is taken from configure/RELEASE
If configure does not exist, from environment
If not found in environment, from makeBaseApp.pl location
-d Verbose output (useful for debugging)
Environment:
EPICS_MBE_DEF_EXT_TYPE Ext type you want to use as default
EPICS_MBE_TEMPLATE_TOP Template top directory
EPICS_MBE_BASE Location of EPICS base
Example: Create example extension
<base>/bin/<arch>/makeBaseExt.pl -t example example
EOF
exit $rtncode;
}
sub GetUser { # no args
my ($user);
# add to this list if new possibilities arise,
# currently it's UNIX and WIN32:
$user = $ENV{USER} || $ENV{USERNAME} || Win32::LoginName();
unless ($user) {
print "I cannot figure out your user name.\n";
print "What shall you be called ?\n";
print ">";
$user = <STDIN>;
chomp $user;
}
die "No user name" unless $user;
return $user;
}
# replace "\" by "/" (for WINxx)
sub UnixPath { # path
my($newpath) = $_[0];
$newpath =~ s|\\|/|go;
return $newpath;
}
-9
View File
@@ -1,9 +0,0 @@
# Makefile at the top of an extensions tree
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += src
include $(TOP)/configure/RULES_TOP
-5
View File
@@ -1,5 +0,0 @@
Notes:
Each time you add a new extension in the src directory you
must add the extension directory name to src/Makefile.
-43
View File
@@ -1,43 +0,0 @@
# CONFIG - Load build configuration data
#
# Do not make changes in this file, any site-specific
# overrides should be given in a CONFIG_SITE file.
# Where the build rules come from
RULES = $(EPICS_BASE)
INSTALL_IDLFILE = $(INSTALL)
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override some Base definitions
INSTALL_LOCATION = $(TOP)
# CONFIG_SITE files contain build configuration overrides
include $(TOP)/configure/CONFIG_SITE
# Host-arch specific settings
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef INSTALL_LOCATION_EXTENSIONS
INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS)
endif
ifdef T_A
# Target-arch specific settings
-include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A)
# Host & target specific combination settings
-include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
@@ -1,20 +0,0 @@
# CONFIG_SITE
#
# Make any extensions-specific changes to the EPICS build
# configuration variables in this file.
#
# Host/target specific settings are in os subdirectory files named
# os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# os/CONFIG_SITE.Common.$(T_A)
# os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# Extensions are not normally built for cross targets
CROSS_COMPILER_TARGET_ARCHS =
# If you don't want to install into $(TOP) then
# define INSTALL_LOCATION here
#INSTALL_LOCATION=<fullpathname>
# Extensions don't normally build shared libraries
SHARED_LIBRARIES = NO
-10
View File
@@ -1,10 +0,0 @@
# Makefile in extensions/configure directory
TOP=..
include $(TOP)/configure/CONFIG
TARGETS = $(CONFIG_TARGETS)
include $(TOP)/configure/RULES
-23
View File
@@ -1,23 +0,0 @@
# RELEASE Locations of external modules
#
# NOTE: The build does not check dependancies on files
# external to this application. Thus you should run
# "gnumake clean uninstall install" in the top directory
# each time EPICS_BASE or any other external module that
# is defined in a RELEASE* file gets rebuilt.
#
# Host/target specific paths can be specified in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# Define INSTALL_LOCATION in CONFIG_SITE
EPICS_EXTENSIONS = $(TOP)
# Locations of external modules
# OAG_APPS may be needed by the SDDS extension
#OAG_APPS = $(TOP)/../../oag/apps
EPICS_BASE = _EPICS_BASE_
-9
View File
@@ -1,9 +0,0 @@
# extensions/configure/RULES
include $(CONFIG)/RULES
-include $(TOP)/configure/RULES_PYTHON
-include $(TOP)/configure/RULES_IDL
ifdef BASE_3_15
-include $(TOP)/configure/RULES_JAVA
endif
@@ -1,3 +0,0 @@
# extensions/configure/RULES_DIRS
include $(CONFIG)/RULES_DIRS
-30
View File
@@ -1,30 +0,0 @@
# extensions/configure/RULES_IDL
ifdef T_A
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
INSTALL_IDL = $(INSTALL_LOCATION)/idllib
DIRECTORY_TARGETS += $(INSTALL_IDL)
ifneq ($(strip $(IDLS_$(OS_CLASS))),)
IDLS += $(subst -nil-,,$(IDLS_$(OS_CLASS)))
else
ifdef IDLS_DEFAULT
IDLS += $(IDLS_DEFAULT)
endif
endif
INSTALL_IDLS =$(IDLS:%=$(INSTALL_IDL)/%)
buildInstall : $(INSTALL_IDLS)
$(INSTALL_IDL)/%: %
@echo "Installing idl program $@"
@$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL)
$(INSTALL_IDL)/%: ../%
@echo "Installing idl program $@"
@$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL)
endif
endif
-158
View File
@@ -1,158 +0,0 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
ifeq ($(BUILD_CLASS),HOST)
#-------------------------------------------------------
# java jdk1.1.5 definitions
INSTALL_JAVA = $(INSTALL_LOCATION)/javalib
UNINSTALL_DIRS += $(INSTALL_JAVA)
JAVA_INC = $(JAVA_DIR)/include
JAVA_BIN = $(JAVA_DIR)/bin
JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/$(word 1, $(subst -, ,$(T_A))) -I$(COMMON_DIR)
JAVACCMD = $(subst \,/,$(JAVA_BIN)/javac$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVACFLAGS))
JAVAHCMD = $(subst \,/,$(JAVA_BIN)/javah$(EXE) -d $(COMMON_DIR) -force $(CLASSPATH) $(JAVAHFLAGS))
JARCMD = $(subst \,/,$(JAVA_BIN)/jar$(EXE) $(JAR_OPTIONS) $@ $(JARINPUT) $(JARPACKAGES))
#-------------------------------------------------------
vpath %.java ..
vpath %.jar .. $(COMMON_DIR)
empty:=
space:= $(empty) $(empty)
CLASSPATH = -classpath $(subst $(space),:,$(strip $(USR_PRECLASSPATH) $(INSTALL_JAVA) $(USR_CLASSPATH)))
SOURCEPATH = -sourcepath .:..:../..
#-------------------------------------------------------
# Java directory
ifdef JAVA
JAVA_DIRECTORY_TARGETS += $(INSTALL_JAVA)
endif
#-------------------------------------------------------
# Java native method C header files
JAVAHFLAGS += $(USR_JAVAHFLAGS)
JAVAINC_CLASSFILES += $(addprefix $(INSTALL_JAVA)/,$(subst _,/,$(subst .h,.class,$(JAVAINC))))
JAVAINC_CLASSNAMES += $(subst _,.,$(subst .h,,$(JAVAINC)))
COMMON_JAVAINC += $(addprefix $(COMMON_DIR)/,$(JAVAINC))
#-------------------------------------------------------
# Java class files
JAVACFLAGS += $(USR_JAVACFLAGS)
CLASSES += $(subst .java,.class,$(JAVA))
INSTALL_CLASSES = $(addprefix $(INSTALL_JAVA)/,$(CLASSES))
TESTCLASSES += $(subst .java,.class,$(notdir $(TESTJAVA)))
COMMON_TESTCLASSES += $(addprefix $(COMMON_DIR)/,$(TESTCLASSES))
DEPTESTJAVA += $(subst .class,.java,$(TESTCLASSES))
#-------------------------------------------------------
# Java jar file
INSTALL_JAR =$(addprefix $(INSTALL_JAVA)/,$(JAR))
JARMANIFEST += $(firstword $(MANIFEST) $(JAR_MANIFEST))
JARDEPFILES += $(addprefix $(INSTALL_JAVA)/,$(subst .java,.class,$(JAVA)) $(JAR_INPUT))
JARINPUT += $(foreach inp,$(JAR_INPUT),-C $(INSTALL_JAVA) $(subst .java,.class,$(inp)))
JARPACKAGES += $(foreach pkg,$(JAR_PACKAGES),-C $(INSTALL_JAVA) $(subst .,/,$(pkg)))
PACKAGEDIRS += $(foreach pkg,$(JAR_PACKAGES),$(addprefix $(INSTALL_JAVA)/,$(subst .,/,$(pkg))))
ifneq ($(JARMANIFEST),)
JAR_OPTIONS = cvmf $(JARMANIFEST)
else
JAR_OPTIONS = cvf
endif
#-------------------------------------------------------
# Java doc definitions
ifdef JAVADOC
JAVADOCFLAGS += $(USR_JAVADOCFLAGS)
JAVADOCCMD = $(subst \,/,$(JAVA_BIN)/javadoc$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVADOCFLAGS))
INSTALL_JAVADOC = $(addprefix $(INSTALL_HTML)/,$(JAVADOC))/index.html
endif
#-------------------------------------------------------
# Java rules
all: install
install: buildInstall
buildInstall : build
rebuild: clean install
inc: $(JAVA_DIRECTORY_TARGETS) $(INSTALL_CLASSES) $(COMMON_JAVAINC)
build: inc
build: $(COMMON_TESTCLASSES)
buildInstall : $(INSTALL_JAR) $(INSTALL_JAVADOC)
#This clean works only from O.* dirs.
buildclean:
@$(RMDIR) $(INSTALL_CLASSES) $(PACKAGEDIRS)
@$(RM) $(INSTALL_JAR) $(INSTALL_JAVADOC)
@$(RM) $(COMMON_TESTCLASSES) $(COMMON_JAVAINC)
ifdef JAVA_DIRECTORY_TARGETS
$(JAVA_DIRECTORY_TARGETS):
$(MKDIR) $@
endif
$(COMMON_JAVAINC):$(JAVAINC_CLASSFILES)
$(ECHO) Creating header files $(COMMON_JAVAINC)
@$(RM) $@
$(JAVAHCMD) $(JAVAINC_CLASSNAMES)
$(COMMON_TESTCLASSES): $(addprefix ../,$(DEPTESTJAVA))
$(ECHO) Creating test java class files $(COMMON_TESTCLASSES)
@$(RM) $@
$(JAVACCMD) -d $(COMMON_DIR) $^
$(INSTALL_CLASSES): $(addprefix ../,$(JAVA))
$(ECHO) Creating java class files
@$(RM) $@
$(JAVACCMD) -d $(INSTALL_JAVA) $^
$(INSTALL_JAVADOC): $(addprefix ../,$(JAVA))
$(ECHO) Creating java doc files
@$(RM) $@
$(JAVADOCCMD) -d $(addprefix $(INSTALL_HTML)/,$(JAVADOC)) $^
$(COMMON_DIR)/%.jar: $(JARDEPFILES)
$(ECHO) Creating java jar file $@
@$(RM) $@
$(JARCMD)
$(INSTALL_JAVA)/%.jar: $(COMMON_DIR)/%.jar
$(ECHO) "Installing java jar file $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
$(INSTALL_JAVA)/%.jar: %.jar
$(ECHO) "Installing java jar file $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
$(addprefix $(INSTALL_JAVA)/, $(JARINPUT)): $(INSTALL_JAVA)/%: ../%
$(ECHO) "Installing jar input file $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
.PHONY: all install buildInstall rebuild clean build inc
.PRECIOUS: $(COMMON_JAVAINC)
endif
@@ -1,54 +0,0 @@
# extensions/configure/RULES_PYTHON
ifdef T_A
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
SWIG ?= swig
vpath %.py $(USR_VPATH) $(ALL_SRC_DIRS)
# The optional PYTHON_INSTALL_LOCATION environment variable
# should be set to <python install site directory>/site-packages
PYTHON_INSTALL_LOCATION ?= $(INSTALL_LOCATION)/lang/python
INSTALL_PYTHON = $(PYTHON_INSTALL_LOCATION)/$(PYTHON_PACKAGE)
PYTHON_PACKAGE_PTH = $(addsuffix .pth,$(PYTHON_PACKAGE))
INSTALL_PYTHON_PACKAGE_PTH = $(addprefix $(PYTHON_INSTALL_LOCATION)/,$(PYTHON_PACKAGE_PTH))
PYTHON_SCRIPTS = $(filter-out $(LOADABLE_LIBRARY),$(PYTHON_MODULES))
PYTHON_LIBRARY = $(filter $(LOADABLE_LIBRARY),$(PYTHON_MODULES))
PYTHON_SHRLIBNAME = $(PYTHON_LIBRARY:%=$(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX))
INSTALL_PYTHONS = $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SCRIPTS))
INSTALL_PYTHONS += $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SHRLIBNAME))
buildInstall: $(INSTALL_PYTHONS) $(INSTALL_PYTHON_PACKAGE_PTH)
$(INSTALL_PYTHON)/%: %
@echo "Installing python modules $@"
@$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON)
$(INSTALL_PYTHON)/%: ../%
@echo "Installing python modules $@"
@$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON)
$(PYTHON_INSTALL_LOCATION)/%: %
@echo "Installing python pth file $@"
@$(INSTALL) -d -m 644 $< $(PYTHON_INSTALL_LOCATION)
$(PYTHON_PACKAGE_PTH):
@echo $(PYTHON_PACKAGE) > $@
%_wrap.c: ../%.i
$(SWIG) -python -o $@ $<
ifdef BASE_3_15
clean:
else
clean::
endif
@$(RM) *.py *.so *.pth
endif
endif
-4
View File
@@ -1,4 +0,0 @@
# extensions/configure/RULES_TOP
include $(CONFIG)/RULES_TOP
@@ -1,2 +0,0 @@
include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86
@@ -1,10 +0,0 @@
#
# Site Specific Configuration Information
# Only the local epics system manager should modify this file
# java jdk definitions
#CLASSPATH += -classpath .:..:$(INSTALL_JAVA):$(JAVA_DIR)/bin/../classes:$(JAVA_DIR)/bin/../lib/classes.zip
#JAVACCMD = $(subst \,/,$(JAVA_DIR)/bin/javac$(EXE) $(CLASSPATH) $(JAVAC_FLAGS) )
#JAVAHCMD = $(subst \,/,$(JAVA_DIR)/bin/javah$(EXE) -jni $(CLASSPATH) $(JAVAH_FLAGS))
#JARCMD = $(subst \,/,$(JAVA_DIR)/bin/jar$(EXE) $(JAR_OPTIONS) $(MANIFEST) $(JAR) $(JAR_INPUT))
@@ -1,11 +0,0 @@
#
# Site Specific Configuration Information
# Only the local epics system manager should modify this file
# Where to find utilities/libraries
# If you do not have a certain product,
# leave the line empty.
#
-include $(TOP)/configure/os/CONFIG_SITE.aix-ppc.aix-ppc
@@ -1,77 +0,0 @@
#
# Site Specific Configuration Information
# Only the local epics system manager should modify this file
# Where to find utilities/libraries
# If you do not have a certain product,
# leave the line empty.
#
-include $(TOP)/configure/os/CONFIG_SITE.Common.Common
# sun X11
X11_LIB = /usr/openwin/lib
X11_INC = /usr/openwin/include
# mit X11
#X11_LIB = /opt/X11R5/lib
#X11_INC = /opt/X11R5/include
# osf motif
#MOTIF_INC = /opt/local/Motif2.0/include
#MOTIF_LIB = /opt/local/Motif2.0/lib
# sun SDK motif
#MOTIF_INC = /opt/SUNWmotif/include
#MOTIF_LIB = /opt/SUNWmotif/lib
# sun 5.4,5.6 SDK motif
MOTIF_INC = /usr/dt/include
MOTIF_LIB = /usr/dt/lib
OPENWIN = /usr/openwin
INTERVIEWS_BIN=/usr/local/interviews/bin/O.solaris
INTERVIEWS_LIB=/usr/local/interviews/lib/O.solaris
IV_INC=/usr/local/interviews/include
IV-2_6_INC=/usr/local/interviews/include/IV-2_6
IV_BIN=/usr/local/interviews/bin/O.solaris
IV_LIB=/usr/local/interviews/lib/O.solaris
WINGZ_INC = /opt/local/Wingz2/incl
WINGZ_LIB = /opt/local/Wingz2/lib
#MATHEMATICA = /usr/local/math
# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x
# and you want the extensions for MEDM
XRTGRAPH_EXTENSIONS = YES
XRTGRAPH = /opt/local/xrtgraph
QUESTWIN = /usr/local/questwin
TK_LIB = /opt/local/lib
TK_INC = /opt/local/include
TCL_LIB = /opt/local/lib
TCL_INC = /opt/local/include
DP_LIB = /opt/local/lib
DP_INC = /opt/local/include
BLT_LIB = /opt/local/lib
BLT_INC = /opt/local/include
IDL = /usr/local/idl
# IDL=$(IDL)/external/rpc is the sun4 version
IDLRPC = $(IDL)/external/rpc.solaris
ZLIB_PREFIX = /usr/local/oag
ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a))
ifeq ($(ZLIB) , libz.a)
ZLIB_LIB = $(ZLIB_PREFIX)/lib
ZLIB_INC = -I$(ZLIB_PREFIX)/include
ZLIB_CFLAG = -DzLib
ZLIB_PROD_LIB = z
z_DIR=$(ZLIB_PREFIX)/lib
else
ZLIB_LIB =
ZLIB_INC =
ZLIB_CFLAG =
ZLIB_PROD_LIB =
z_DIR=
endif
PYTHON_DIR=/opt/local/lib/python2.2
PYTHON_INCLUDE=/opt/local/include/python2.2
JAVA_DIR=/usr/java

Some files were not shown because too many files have changed in this diff Show More