Structural changes to create ca module
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
@@ -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,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,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);
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Makefile in extensions/configure directory
|
||||
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user