Merged with mirror-3.14
This commit is contained in:
@@ -19,6 +19,29 @@ Added Soft Channel device support.
|
||||
Added SIOL link and proper simulation mode for Soft Channel support.
|
||||
Added MPST, APST and HASH fields for monitor on change support like in waveform record.
|
||||
|
||||
|
||||
<h4>devLib cleanup</h4>
|
||||
|
||||
<ul>
|
||||
<li>Add VME connect/disconnect IRQ calls to the "virtual os" table</li>
|
||||
<li>It is now possible to compile all devLib code on targets without runtime
|
||||
support</li>
|
||||
<li>All internal functions are made static. Some were not before.</li>
|
||||
<li>Move VME calls to <tt>devLibVME.h</tt>. <tt>devLib.h</tt> contains general
|
||||
defintions and error codes.</li>
|
||||
<li>For compatibility <tt>devLib.h</tt> includes <tt>devLibVME.h</tt> unless the
|
||||
macro <tt>NO_DEVLIB_COMPAT</tt> is defined.</li>
|
||||
<li>The "virtual os" table was renamed from <tt>pdevLibVirtualOS</tt> to
|
||||
<tt>pdevLibVME</tt> reflecting the fact that other bus types will need seperate
|
||||
tables.</li>
|
||||
<li>The "virtual os" table API has been moved to a seperate header file,
|
||||
<tt>devLibVMEImpl.h</tt>.</li>
|
||||
</ul>
|
||||
|
||||
<h4>DTYP and INP/OUT order</h4>
|
||||
|
||||
<p>The fields DTYP and INP/OUT can now be specified in any order.</p>
|
||||
|
||||
<h4>Rewrite epicsThreadOnce()</h4>
|
||||
|
||||
<p>Michael Davidsaver suggested a better implementation of epicsThreadOnce()
|
||||
|
||||
@@ -85,7 +85,7 @@ DIRS += gdd
|
||||
gdd_DEPEND_DIRS = ca
|
||||
|
||||
DIRS += cas
|
||||
cas_DEPEND_DIRS = gdd
|
||||
cas_DEPEND_DIRS = gdd dbStatic
|
||||
|
||||
DIRS += excas
|
||||
excas_DEPEND_DIRS = cas as registry
|
||||
|
||||
@@ -144,12 +144,13 @@ int main(int argc, char **argv)
|
||||
if(*pend!='"') errExit("Illegal Header");
|
||||
len = pend - pbeg;
|
||||
if(len<=1) errExit("Illegal Header");
|
||||
pname = calloc(len,sizeof(char));
|
||||
pname = calloc(len+1,sizeof(char));
|
||||
if(!pname) {
|
||||
fprintf(stderr,"calloc failed while processing line %d\n",linenum);
|
||||
exit(-1);
|
||||
}
|
||||
strncpy(pname,pbeg,len);
|
||||
pname[len]='\0';
|
||||
pbeg = pend + 1;
|
||||
if(getNumber(&pbeg,&value)) errExit("Illegal Header");
|
||||
brkCreateInfo.engLow = value;
|
||||
|
||||
@@ -29,6 +29,7 @@ ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),)
|
||||
PERL_SCRIPTS += cainfo.pl
|
||||
PERL_SCRIPTS += caput.pl
|
||||
PERL_SCRIPTS += caget.pl
|
||||
PERL_SCRIPTS += capr.pl
|
||||
PERL_SCRIPTS += camonitor.pl
|
||||
|
||||
PERL_MODULES += CA.pm
|
||||
|
||||
423
src/cap5/capr.pl
Normal file
423
src/cap5/capr.pl
Normal file
@@ -0,0 +1,423 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# capr: A program that attempts to do a "dbpr" command via channel
|
||||
# access.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
use strict;
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib "$Bin/../../lib/perl";
|
||||
|
||||
use Getopt::Std;
|
||||
use EPICS::Path;
|
||||
use CA;
|
||||
|
||||
######### Globals ##########
|
||||
|
||||
our ($opt_h, $opt_f, $opt_r);
|
||||
our $opt_d = $ENV{EPICS_CAPR_DBD_FILE} || "$Bin/../../dbd/softIoc.dbd";
|
||||
our $opt_w = 1;
|
||||
|
||||
my %record = (); # Empty hash to put dbd data in
|
||||
my $iIdx = 0; # Array indexes for interest, data type and base
|
||||
my $tIdx = 1;
|
||||
my $bIdx = 2;
|
||||
my %device = (); # Empty hash to record which rec types have device support
|
||||
|
||||
# EPICS field types
|
||||
my %fieldType = (
|
||||
DBF_CHAR => 'DBF_CHAR',
|
||||
DBF_UCHAR => 'DBF_CHAR',
|
||||
DBF_DOUBLE => 'DBF_FLOAT',
|
||||
DBF_FLOAT => 'DBF_FLOAT',
|
||||
DBF_LONG => 'DBF_LONG',
|
||||
DBF_SHORT => 'DBF_LONG',
|
||||
DBF_ULONG => 'DBF_LONG',
|
||||
DBF_USHORT => 'DBF_LONG',
|
||||
DBF_DEVICE => 'DBF_STRING',
|
||||
DBF_ENUM => 'DBF_STRING',
|
||||
DBF_FWDLINK => 'DBF_STRING',
|
||||
DBF_INLINK => 'DBF_STRING',
|
||||
DBF_MENU => 'DBF_STRING',
|
||||
DBF_OUTLINK => 'DBF_STRING',
|
||||
DBF_STRING => 'DBF_STRING',
|
||||
DBF_NOACCESS => 'DBF_NOACCESS',
|
||||
);
|
||||
|
||||
# globals for sub caget
|
||||
my %callback_data;
|
||||
my %timed_out;
|
||||
my $callback_incomplete;
|
||||
|
||||
######### Main program ############
|
||||
|
||||
HELP_MESSAGE() unless getopts('hd:f:rw:');
|
||||
HELP_MESSAGE() if $opt_h;
|
||||
|
||||
die "File $opt_d not found. (\"capr.pl -h\" gives help)\n"
|
||||
unless -f $opt_d;
|
||||
|
||||
parseDbd($opt_d);
|
||||
print "Using $opt_d\n\n";
|
||||
|
||||
# Print a list of record types
|
||||
if ($opt_r) {
|
||||
print ("Record types found:\n");
|
||||
printList(0);
|
||||
exit;
|
||||
}
|
||||
|
||||
# Print the fields defined for given record
|
||||
if ($opt_f) {
|
||||
printRecordList($opt_f);
|
||||
exit;
|
||||
}
|
||||
|
||||
HELP_MESSAGE() unless @ARGV;
|
||||
|
||||
$_ = shift;
|
||||
if (@ARGV) {
|
||||
# Drop any ".FIELD" part
|
||||
s/\. \w+ $//x;
|
||||
printRecord($_, @ARGV);
|
||||
} else {
|
||||
if (m/^ \s* ([]+:;<>0-9A-Za-z[-]+) (?:\. \w+)? \s* , \s* (\d+) \s* $/x) {
|
||||
# Recognizes ",n" as an interest leve, drops any ".FIELD" part
|
||||
printRecord($1, $2);
|
||||
} else {
|
||||
# Drop any ".FIELD" part
|
||||
s/\. \w+ $//x;
|
||||
printRecord($_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
########## End of main ###########
|
||||
|
||||
|
||||
|
||||
# parseDbd
|
||||
# Takes given dbd file and parses it to produce a hash table of record types
|
||||
# giving their fields, and for each field its interest level and data type.
|
||||
# usage: parseDbd("fileName");
|
||||
# Output goes to the global %record, a hash of references to other hashes
|
||||
# containing the fields of each record type. Those hash values (keyed by
|
||||
# field name) are references to arrays containing the interest level, data
|
||||
# type and number base of the field.
|
||||
sub parseDbd {
|
||||
my $dbdFile = shift;
|
||||
|
||||
open(DBD, "< $dbdFile") or die "Can't open file $dbdFile: $!\n";
|
||||
my @dbd = <DBD>;
|
||||
close(DBD) or die "Can't close $dbdFile: $!\n";
|
||||
|
||||
my $i = 1;
|
||||
my $level = 0;
|
||||
my $isArecord = 0;
|
||||
my $isAfield = 0;
|
||||
my $thisRecord;
|
||||
my $thisField;
|
||||
my $thisType;
|
||||
my $field = {};
|
||||
my $interest = 0;
|
||||
my $thisBase = 'DECIMAL';
|
||||
|
||||
while (@dbd) {
|
||||
$_ = shift @dbd;
|
||||
chomp;
|
||||
if ( m/recordtype \s* \( \s* (\w+) \)/x ) {
|
||||
die "File format error at line $i of file\n $opt_d\n"
|
||||
unless $level == 0;
|
||||
$isArecord = 1;
|
||||
$thisRecord = $1;
|
||||
}
|
||||
elsif ( m/field \s* \( \s* (\w+) \s* , \s* (\w+) \s* \)/x ) {
|
||||
die "File format error at line $i of file\n $opt_d\n"
|
||||
unless $level == 1 && $isArecord;
|
||||
$thisField = $1;
|
||||
$thisType = $2;
|
||||
$isAfield = 1;
|
||||
}
|
||||
elsif ( m/interest \s* \( \s* (\w+) \s* \)/x ) {
|
||||
die "File format error at line $i of file\n $opt_d\n"
|
||||
unless $level == 2 && $isAfield;
|
||||
$interest = $1;
|
||||
}
|
||||
elsif ( m/base \s* \( \s* (\w+) \s* \)/x ) {
|
||||
die "File format error at line $i of file\n $opt_d\n"
|
||||
unless $level == 2 && $isAfield;
|
||||
$thisBase = $1;
|
||||
}
|
||||
elsif ( m/device \s* \( (\w+) \s* ,/x ) {
|
||||
die "File format error at line $i of file\n $opt_d\n"
|
||||
unless $level == 0;
|
||||
$device{$1}++;
|
||||
}
|
||||
if ( m/\{/ ) {
|
||||
$level++;
|
||||
}
|
||||
if ( m/\}/ ) {
|
||||
if ($level == 2 && $isAfield) {
|
||||
my $params = [];
|
||||
$params->[$iIdx] = $interest;
|
||||
$params->[$tIdx] = $thisType;
|
||||
$params->[$bIdx] = $thisBase;
|
||||
$field->{$thisField} = $params;
|
||||
$isAfield = 0;
|
||||
$interest = 0; # reset default
|
||||
$thisBase = 'DECIMAL'; # reset default
|
||||
}
|
||||
elsif ($level == 1 && $isArecord) {
|
||||
$isArecord = 0;
|
||||
$record{$thisRecord} = $field;
|
||||
$field = {}; # start another hash
|
||||
}
|
||||
$level--;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Given a record name, attempts to find the record and its type.
|
||||
# Usage: $recordType = getRecType("recordName");
|
||||
sub getRecType {
|
||||
my $arg = shift;
|
||||
my $name = "$arg.RTYP";
|
||||
|
||||
my $fields_read = caget($name);
|
||||
|
||||
die "Could not determine record type of $arg\n"
|
||||
unless $fields_read == 1;
|
||||
|
||||
return $callback_data{$name};
|
||||
}
|
||||
|
||||
# Given the record type and field, returns the interest level, data type
|
||||
# and number base for the field
|
||||
# Usage: ($dataType, $interest, $base) = getFieldParams($recType, $field);
|
||||
sub getFieldParams {
|
||||
my ($recType, $field) = @_;
|
||||
|
||||
my $params = $record{$recType}{$field} or
|
||||
die "Can't find params for $recType.$field";
|
||||
exists($fieldType{$params->[$tIdx]}) ||
|
||||
die "Field data type $field for $recType not found in dbd file --";
|
||||
exists($params->[$iIdx]) ||
|
||||
die "Interest level for $field in $recType not found in dbd file --";
|
||||
|
||||
my $fType = $fieldType{$params->[$tIdx]};
|
||||
my $fInterest = $params->[$iIdx];
|
||||
my $fBase = $params->[$bIdx];
|
||||
return ($fType, $fInterest, $fBase);
|
||||
}
|
||||
|
||||
# Prints field name and data for given field. Formats output so
|
||||
# that fields align in to 4 columns. Tries to imitate dbpf format
|
||||
# Usage: printField( $fieldName, $data, $dataType, $base, $firstColumnPosn)
|
||||
sub printField {
|
||||
my ($fieldName, $fieldData, $dataType, $base, $col) = @_;
|
||||
|
||||
my $screenWidth = 80;
|
||||
my ($outStr, $wide);
|
||||
|
||||
my $field = "$fieldName:";
|
||||
|
||||
if ( $dataType eq 'DBF_STRING' ) {
|
||||
$outStr = sprintf('%-5s %s', $field, $fieldData);
|
||||
} elsif ( $base eq 'HEX' ) {
|
||||
my $val = ( $dataType eq 'DBF_CHAR' ) ? ord($fieldData) : $fieldData;
|
||||
$outStr = sprintf('%-5s 0x%x', $field, $val);
|
||||
} elsif ( $dataType eq 'DBF_DOUBLE' || $dataType eq 'DBF_FLOAT' ) {
|
||||
$outStr = sprintf('%-5s %.8f', $field, $fieldData);
|
||||
} elsif ( $dataType eq 'DBF_CHAR' ) {
|
||||
$outStr = sprintf('%-5s %d', $field, ord($fieldData));
|
||||
}else {
|
||||
# DBF_LONG, DBF_SHORT, DBF_UCHAR, DBF_ULONG, DBF_USHORT
|
||||
$outStr = sprintf('%-5s %d', $field, $fieldData);
|
||||
}
|
||||
|
||||
my $len = length($outStr);
|
||||
if ($len <= 20) { $wide = 20; }
|
||||
elsif ( $len <= 40 ) { $wide = 40; }
|
||||
elsif ( $len <= 60 ) { $wide = 60; }
|
||||
else { $wide = 80;}
|
||||
|
||||
my $pad = $wide - $len;
|
||||
|
||||
$col += $wide;
|
||||
if ($col > $screenWidth ) {
|
||||
print("\n");
|
||||
$col = $wide;
|
||||
}
|
||||
|
||||
print $outStr, ' ' x $pad;
|
||||
|
||||
return $col;
|
||||
}
|
||||
|
||||
# Query for a list of fields simultaneously.
|
||||
# The results are filled in the the %callback_data global hash
|
||||
# and the result of the operation is the number of read pvs
|
||||
#
|
||||
# NOTE: Not re-entrant because results are written to global hash
|
||||
# %callback_data
|
||||
#
|
||||
# Usage: $fields_read = caget( @pvlist )
|
||||
sub caget {
|
||||
my @chans = map { CA->new($_); } @_;
|
||||
|
||||
#clear results;
|
||||
%callback_data = ();
|
||||
%timed_out = ();
|
||||
|
||||
eval { CA->pend_io($opt_w); };
|
||||
if ($@) {
|
||||
if ($@ =~ m/^ECA_TIMEOUT/) {
|
||||
my $err = (@chans > 1) ? 'some PV(s)' : '"' . $chans[0]->name . '"';
|
||||
print "Channel connect timed out: $err not found.\n";
|
||||
foreach my $chan (@chans) {
|
||||
$timed_out{$chan->name} = $chan->is_connected;
|
||||
}
|
||||
@chans = grep { $_->is_connected } @chans;
|
||||
} else {
|
||||
die $@;
|
||||
}
|
||||
}
|
||||
|
||||
map {
|
||||
my $type;
|
||||
$type = $_->field_type;
|
||||
$_->get_callback(\&caget_callback, $type);
|
||||
} @chans;
|
||||
|
||||
my $fields_read = @chans;
|
||||
$callback_incomplete = @chans;
|
||||
CA->pend_event(0.1) while $callback_incomplete;
|
||||
return $fields_read;
|
||||
}
|
||||
|
||||
sub caget_callback {
|
||||
my ($chan, $status, $data) = @_;
|
||||
die $status if $status;
|
||||
$callback_data{$chan->name} = $data;
|
||||
$callback_incomplete--;
|
||||
}
|
||||
|
||||
# Given record name and interest level prints data from record fields
|
||||
# that are at or below the interest level specified.
|
||||
# Usage: printRecord($recordName, $interestLevel)
|
||||
sub printRecord {
|
||||
my ($name, $interest) = @_;
|
||||
|
||||
my $recType = getRecType($name);
|
||||
print("Record $name type $recType\n");
|
||||
die "Record type $recType not found\n"
|
||||
unless exists $record{$recType};
|
||||
|
||||
#capture list of fields
|
||||
my @readlist = (); #fields to read via CA
|
||||
my @fields_pr = (); #fields for print-out
|
||||
my @ftypes = (); #types, from parser
|
||||
my @bases = (); #bases, from parser
|
||||
foreach my $field (sort keys %{$record{$recType}}) {
|
||||
# Skip DTYP field if this rec type doesn't have device support defined
|
||||
if ($field eq 'DTYP' && !(exists($device{$recType}))) { next; }
|
||||
|
||||
my ($fType, $fInterest, $base) = getFieldParams($recType, $field);
|
||||
unless( $fType eq 'DBF_NOACCESS' ) {
|
||||
if ($interest >= $fInterest ) {
|
||||
my $fToGet = "$name.$field";
|
||||
push @fields_pr, $field;
|
||||
push @readlist, $fToGet;
|
||||
push @ftypes, $fType;
|
||||
push @bases, $base;
|
||||
}
|
||||
}
|
||||
}
|
||||
my $fields_read = caget( @readlist );
|
||||
|
||||
# print while iterating over lists gathered
|
||||
my $col = 0;
|
||||
for (my $i=0; $i < scalar @readlist; $i++) {
|
||||
my $field = $fields_pr[$i];
|
||||
my $fToGet = $readlist[$i];
|
||||
my ($fType, $data, $base);
|
||||
if ($timed_out{$fToGet}) {
|
||||
$fType = $fieldType{DBF_STRING};
|
||||
$data = '<timeout>';
|
||||
}
|
||||
else {
|
||||
$fType = $ftypes[$i];
|
||||
$base = $bases[$i];
|
||||
$data = $callback_data{$fToGet};
|
||||
}
|
||||
$col = printField($field, $data, $fType, $base, $col);
|
||||
}
|
||||
print("\n"); # Final newline
|
||||
}
|
||||
|
||||
# Prints list of record types found in dbd file. If level > 0
|
||||
# then the fields of that record type, their interest levels and types are
|
||||
# also printed.
|
||||
# Diagnostic routine, usage: void printList(level);
|
||||
sub printList {
|
||||
my $level = shift;
|
||||
|
||||
foreach my $rkey (sort keys(%record)) {
|
||||
print(" $rkey\n");
|
||||
if ($level > 0) {
|
||||
foreach my $fkey (keys %{$record{$rkey}}) {
|
||||
print("\tField $fkey - interest $record{$rkey}{$fkey}[$iIdx] ");
|
||||
print("- type $record{$rkey}{$fkey}[$tIdx] ");
|
||||
print("- base $record{$rkey}{$fkey}[$bIdx]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Prints list of fields with interest levels for given record type
|
||||
# Diagnostic routine, usage: void printRecordList("recordType");
|
||||
sub printRecordList {
|
||||
my $type = shift;
|
||||
|
||||
if (exists($record{$type}) ) {
|
||||
print("Record type - $type\n");
|
||||
foreach my $fkey (sort keys %{$record{$type}}) {
|
||||
printf('%-4s', $fkey);
|
||||
printf(" interest = $record{$type}{$fkey}[$iIdx]");
|
||||
printf(" type = %-12s ",$record{$type}{$fkey}[$tIdx]);
|
||||
print (" base = $record{$type}{$fkey}[$bIdx]\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
print("Record type $type not defined in dbd file $opt_d\n");
|
||||
}
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
print STDERR "\n",
|
||||
"Usage: capr.pl -h\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] -r\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] -f record_type\n",
|
||||
" capr.pl [-d file.dbd] [-w seconds] record_name [interest]\n",
|
||||
"Description:\n",
|
||||
" Attempts to perform a \"dbpr\" record print via channel access for \n",
|
||||
" record_name at an interest level which defaults to level 0.\n\n",
|
||||
" The -r or -f options cause it to print record type or field lists.\n",
|
||||
"\n",
|
||||
"Options:\n",
|
||||
" -h Prints this help message.\n",
|
||||
" -r Lists all record types in the dbd file.\n",
|
||||
" -f record_type: Lists all fields plus their interest level, data type\n",
|
||||
" and number base for the given record_type.\n",
|
||||
" -d file.dbd: The dbd file containing record type definitions.\n",
|
||||
" This can be set using the EPICS_CAPR_DBD_FILE environment variable.\n",
|
||||
" Currently ", AbsPath($opt_d), "\n",
|
||||
" -w seconds: CA connection timeout, currently $opt_w\n",
|
||||
"\n";
|
||||
exit 1;
|
||||
}
|
||||
@@ -246,15 +246,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_string *pold = (struct dbr_sts_string *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
DBSTRING *pvalue = (DBSTRING *)pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_STRING, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_STRING, pold->value, &options,
|
||||
@@ -268,15 +268,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_int *pold = (struct dbr_sts_int *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_short_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_SHORT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
|
||||
@@ -289,15 +289,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_float *pold = (struct dbr_sts_float *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_float_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_FLOAT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
|
||||
@@ -310,15 +310,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_enum *pold = (struct dbr_sts_enum *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_enum_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_ENUM, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_ENUM, &pold->value, &options,
|
||||
@@ -331,15 +331,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_char *pold = (struct dbr_sts_char *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_char_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_UCHAR, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
|
||||
@@ -352,15 +352,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_long *pold = (struct dbr_sts_long *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_long_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_LONG, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
|
||||
@@ -373,15 +373,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_sts_double *pold = (struct dbr_sts_double *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_double_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
|
||||
@@ -396,16 +396,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
DBSTRING *pvalue = (DBSTRING *)(pold->value);
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_STRING, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_STRING, pold->value, &options,
|
||||
@@ -420,16 +420,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_short_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_SHORT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
|
||||
@@ -443,16 +443,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_float_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_FLOAT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
|
||||
@@ -466,16 +466,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_enum_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_ENUM, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_ENUM, &pold->value, &options,
|
||||
@@ -489,16 +489,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_char_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_CHAR, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_CHAR, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_CHAR, &pold->value, &options,
|
||||
@@ -512,16 +512,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_long_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_LONG, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
|
||||
@@ -535,16 +535,16 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_double_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_TIME;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->stamp = new.time; /* structure copy */
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->stamp = newSt.time; /* structure copy */
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
|
||||
@@ -563,23 +563,23 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRunits
|
||||
DBRgrLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_short_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_SHORT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
|
||||
@@ -596,25 +596,25 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRprecision
|
||||
DBRgrDouble
|
||||
DBRalDouble
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_float_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
|
||||
DBR_AL_DOUBLE;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_FLOAT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision.dp;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->precision = newSt.precision.dp;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = epicsConvertDoubleToFloat(new.upper_disp_limit);
|
||||
pold->lower_disp_limit = epicsConvertDoubleToFloat(new.lower_disp_limit);
|
||||
pold->upper_alarm_limit = epicsConvertDoubleToFloat(new.upper_alarm_limit);
|
||||
pold->lower_alarm_limit = epicsConvertDoubleToFloat(new.lower_alarm_limit);
|
||||
pold->upper_warning_limit = epicsConvertDoubleToFloat(new.upper_warning_limit);
|
||||
pold->lower_warning_limit = epicsConvertDoubleToFloat(new.lower_warning_limit);
|
||||
pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit);
|
||||
pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit);
|
||||
pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit);
|
||||
pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit);
|
||||
pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit);
|
||||
pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit);
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
|
||||
@@ -631,23 +631,23 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRunits
|
||||
DBRgrLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_char_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_UCHAR, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
|
||||
@@ -663,23 +663,23 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRunits
|
||||
DBRgrLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_long_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_LONG, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
|
||||
@@ -696,25 +696,25 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRprecision
|
||||
DBRgrDouble
|
||||
DBRalDouble
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_double_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
|
||||
DBR_AL_DOUBLE;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision.dp;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->precision = newSt.precision.dp;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
|
||||
@@ -733,26 +733,26 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRgrLong
|
||||
DBRctrlLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_short_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
|
||||
DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_SHORT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = new.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = new.lower_ctrl_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
|
||||
@@ -770,27 +770,27 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRgrDouble
|
||||
DBRctrlDouble
|
||||
DBRalDouble
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_float_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
|
||||
DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_FLOAT, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision.dp;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->precision = newSt.precision.dp;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = epicsConvertDoubleToFloat(new.upper_disp_limit);
|
||||
pold->lower_disp_limit = epicsConvertDoubleToFloat(new.lower_disp_limit);
|
||||
pold->upper_alarm_limit = epicsConvertDoubleToFloat(new.upper_alarm_limit);
|
||||
pold->lower_alarm_limit = epicsConvertDoubleToFloat(new.lower_alarm_limit);
|
||||
pold->upper_warning_limit = epicsConvertDoubleToFloat(new.upper_warning_limit);
|
||||
pold->lower_warning_limit = epicsConvertDoubleToFloat(new.lower_warning_limit);
|
||||
pold->upper_ctrl_limit = epicsConvertDoubleToFloat(new.upper_ctrl_limit);
|
||||
pold->lower_ctrl_limit = epicsConvertDoubleToFloat(new.lower_ctrl_limit);
|
||||
pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit);
|
||||
pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit);
|
||||
pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit);
|
||||
pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit);
|
||||
pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit);
|
||||
pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit);
|
||||
pold->upper_ctrl_limit = epicsConvertDoubleToFloat(newSt.upper_ctrl_limit);
|
||||
pold->lower_ctrl_limit = epicsConvertDoubleToFloat(newSt.lower_ctrl_limit);
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
|
||||
@@ -805,7 +805,7 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRenumStrs
|
||||
} new;
|
||||
} newSt;
|
||||
short no_str;
|
||||
dbr_enum_t *pvalue = &pold->value;
|
||||
|
||||
@@ -813,15 +813,15 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
/* first get status and severity */
|
||||
options = DBR_STATUS | DBR_ENUM_STRS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_ENUM, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
no_str = new.no_str;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
no_str = newSt.no_str;
|
||||
if (no_str>16) no_str=16;
|
||||
pold->no_str = no_str;
|
||||
for (i = 0; i < no_str; i++)
|
||||
strncpy(pold->strs[i], new.strs[i], sizeof(pold->strs[i]));
|
||||
strncpy(pold->strs[i], newSt.strs[i], sizeof(pold->strs[i]));
|
||||
/*now get values*/
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
@@ -839,26 +839,26 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRgrLong
|
||||
DBRctrlLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_char_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
|
||||
DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_UCHAR, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = new.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = new.lower_ctrl_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
|
||||
@@ -875,26 +875,26 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRgrLong
|
||||
DBRctrlLong
|
||||
DBRalLong
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_long_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
|
||||
DBR_AL_LONG;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_LONG, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = new.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = new.lower_ctrl_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
|
||||
@@ -912,27 +912,27 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
DBRgrDouble
|
||||
DBRctrlDouble
|
||||
DBRalDouble
|
||||
} new;
|
||||
} newSt;
|
||||
dbr_double_t *pvalue = &pold->value;
|
||||
|
||||
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
|
||||
DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->precision = new.precision.dp;
|
||||
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->precision = newSt.precision.dp;
|
||||
strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
|
||||
pold->units[MAX_UNITS_SIZE-1] = '\0';
|
||||
pold->upper_disp_limit = new.upper_disp_limit;
|
||||
pold->lower_disp_limit = new.lower_disp_limit;
|
||||
pold->upper_alarm_limit = new.upper_alarm_limit;
|
||||
pold->upper_warning_limit = new.upper_warning_limit;
|
||||
pold->lower_warning_limit = new.lower_warning_limit;
|
||||
pold->lower_alarm_limit = new.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = new.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = new.lower_ctrl_limit;
|
||||
pold->upper_disp_limit = newSt.upper_disp_limit;
|
||||
pold->lower_disp_limit = newSt.lower_disp_limit;
|
||||
pold->upper_alarm_limit = newSt.upper_alarm_limit;
|
||||
pold->upper_warning_limit = newSt.upper_warning_limit;
|
||||
pold->lower_warning_limit = newSt.lower_warning_limit;
|
||||
pold->lower_alarm_limit = newSt.lower_alarm_limit;
|
||||
pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
|
||||
pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
|
||||
@@ -946,17 +946,17 @@ int epicsShareAPI db_get_field(struct dbAddr *paddr,
|
||||
struct dbr_stsack_string *pold = (struct dbr_stsack_string *)pbuffer;
|
||||
struct {
|
||||
DBRstatus
|
||||
} new;
|
||||
} newSt;
|
||||
DBSTRING *pvalue = (DBSTRING *)(pold->value);
|
||||
|
||||
options = DBR_STATUS;
|
||||
nRequest = 0;
|
||||
status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
|
||||
status = dbGetField(paddr, DBR_STRING, &newSt, &options, &nRequest,
|
||||
pfl);
|
||||
pold->status = new.status;
|
||||
pold->severity = new.severity;
|
||||
pold->ackt = new.ackt;
|
||||
pold->acks = new.acks;
|
||||
pold->status = newSt.status;
|
||||
pold->severity = newSt.severity;
|
||||
pold->ackt = newSt.ackt;
|
||||
pold->acks = newSt.acks;
|
||||
options = 0;
|
||||
nRequest = no_elements;
|
||||
status = dbGetField(paddr, DBR_STRING, pold->value,
|
||||
|
||||
@@ -277,6 +277,19 @@ static long setLinkType(DBENTRY *pdbentry)
|
||||
plink = (DBLINK *)pdbentry->pfield;
|
||||
if (plink->type == link_type) goto done;
|
||||
|
||||
if (plink->text)
|
||||
{
|
||||
/* re-parse link text when DTYP has changed */
|
||||
char * link_text;
|
||||
link_text = plink->text;
|
||||
plink->text = NULL;
|
||||
dbFreeLinkContents(plink);
|
||||
plink->type = link_type;
|
||||
dbPutString(pdbentry, link_text);
|
||||
free(link_text);
|
||||
goto done;
|
||||
}
|
||||
|
||||
type = plink->type;
|
||||
if ((type == CONSTANT || type == PV_LINK || type == DB_LINK || type == CA_LINK) &&
|
||||
(link_type == CONSTANT || link_type == PV_LINK)) goto done;
|
||||
@@ -331,6 +344,7 @@ void dbFreeLinkContents(struct link *plink)
|
||||
epicsPrintf("dbFreeLink called but link type unknown\n");
|
||||
}
|
||||
if(parm && (parm != pNullString)) free((void *)parm);
|
||||
if(plink->text) free(plink->text);
|
||||
memset((char *)plink,0,sizeof(struct link));
|
||||
}
|
||||
|
||||
@@ -516,14 +530,14 @@ dbDeviceMenu *dbGetDeviceMenu(DBENTRY *pdbentry)
|
||||
/* Beginning of Public Routines */
|
||||
|
||||
#define INC_SIZE 256
|
||||
void epicsShareAPI dbCatString(char **string,int *stringLength,char *new,char *separator)
|
||||
void epicsShareAPI dbCatString(char **string,int *stringLength,char *src,char *separator)
|
||||
{
|
||||
if((*string==NULL)
|
||||
|| ((strlen(*string)+strlen(new)+2) > (size_t)*stringLength)) {
|
||||
|| ((strlen(*string)+strlen(src)+2) > (size_t)*stringLength)) {
|
||||
char *newString;
|
||||
size_t size;
|
||||
|
||||
size = strlen(new);
|
||||
size = strlen(src);
|
||||
if(*string) size += strlen(*string);
|
||||
/*Make size multiple of INC_SIZE*/
|
||||
size = ((size + 2 + INC_SIZE)/INC_SIZE) * INC_SIZE;
|
||||
@@ -538,8 +552,8 @@ void epicsShareAPI dbCatString(char **string,int *stringLength,char *new,char *s
|
||||
strcat(*string,separator);
|
||||
*stringLength += strlen(separator);
|
||||
}
|
||||
strcat(*string,new);
|
||||
*stringLength += strlen(new);
|
||||
strcat(*string,src);
|
||||
*stringLength += strlen(src);
|
||||
}
|
||||
|
||||
dbBase * epicsShareAPI dbAllocBase(void)
|
||||
@@ -2224,6 +2238,8 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
errMessage(status,"in dbPutString from setLinkType");
|
||||
return status;
|
||||
}
|
||||
/* store link text in case DTYP changes later */
|
||||
plink->text = epicsStrDup(pstring);
|
||||
}
|
||||
if (strlen(pstring) >= sizeof(string)) {
|
||||
status = S_dbLib_badField;
|
||||
|
||||
@@ -183,6 +183,7 @@ union value{
|
||||
struct link{
|
||||
union value value;
|
||||
short type;
|
||||
char *text; /* original INP/OUT link text */
|
||||
};
|
||||
|
||||
typedef struct link DBLINK;
|
||||
|
||||
@@ -192,6 +192,8 @@ INC += epicsStdioRedirect.h
|
||||
INC += epicsGetopt.h
|
||||
|
||||
INC += devLib.h
|
||||
INC += devLibVME.h
|
||||
INC += devLibVMEImpl.h
|
||||
INC += osdVME.h
|
||||
|
||||
SRCS += epicsThread.cpp
|
||||
@@ -230,8 +232,8 @@ SRCS += osdProcess.c
|
||||
SRCS += osdNetIntf.c
|
||||
SRCS += osdMessageQueue.c
|
||||
|
||||
SRCS += devLib.c
|
||||
SRCS += devLibOSD.c
|
||||
SRCS += devLibVME.c
|
||||
SRCS += devLibVMEOSD.c
|
||||
|
||||
SRC_DIRS += $(LIBCOM)/taskwd
|
||||
INC += taskwd.h
|
||||
|
||||
@@ -1,252 +1,27 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devLib.h */
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
*/
|
||||
|
||||
#ifndef INCdevLibh
|
||||
#define INCdevLibh 1
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "osdVME.h"
|
||||
#include "errMdef.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef EPICSDEVLIB_H
|
||||
#define EPICSDEVLIB_H
|
||||
|
||||
/*
|
||||
* epdevAddressType & EPICStovxWorksAddrType
|
||||
* devLib.c must change in unison
|
||||
* Support macros
|
||||
*/
|
||||
typedef enum {
|
||||
atVMEA16,
|
||||
atVMEA24,
|
||||
atVMEA32,
|
||||
atISA, /* memory mapped ISA access (until now only on PC) */
|
||||
atVMECSR, /* VME-64 CR/CSR address space */
|
||||
atLast /* atLast must be the last enum in this list */
|
||||
} epicsAddressType;
|
||||
|
||||
/*
|
||||
* pointer to an array of strings for each of
|
||||
* the above address types
|
||||
*/
|
||||
extern const char *epicsAddressTypeName[];
|
||||
|
||||
epicsShareFunc long devAddressMap(void); /* print an address map */
|
||||
|
||||
/*
|
||||
* devBusToLocalAddr()
|
||||
*
|
||||
* OSI routine to translate bus addresses their local CPU address mapping
|
||||
*/
|
||||
epicsShareFunc long devBusToLocalAddr (
|
||||
epicsAddressType addrType,
|
||||
size_t busAddr,
|
||||
volatile void **ppLocalAddr);
|
||||
/*
|
||||
* devReadProbe()
|
||||
*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
epicsShareFunc long devReadProbe (
|
||||
unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* devNoResponseProbe()
|
||||
*
|
||||
* Verifies that no devices respond at naturally aligned words
|
||||
* within the specified address range. Return success if no devices
|
||||
* respond. Returns an error if a device does respond or if
|
||||
* a physical address for a naturally aligned word cant be mapped.
|
||||
* Checks all naturally aligned word sizes between char and long for
|
||||
* the entire specified range of bytes.
|
||||
*/
|
||||
epicsShareFunc long devNoResponseProbe(
|
||||
epicsAddressType addrType,
|
||||
size_t base,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/*
|
||||
* devWriteProbe
|
||||
*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
epicsShareFunc long devWriteProbe (
|
||||
unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
epicsShareFunc long devRegisterAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
size_t size, /* bytes */
|
||||
volatile void **pPhysicalAddress);
|
||||
|
||||
epicsShareFunc long devUnregisterAddress(
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
const char *pOwnerName);
|
||||
|
||||
/*
|
||||
* allocate and register an unoccupied address block
|
||||
*/
|
||||
epicsShareFunc long devAllocAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t size,
|
||||
unsigned alignment, /*n ls bits zero in addr*/
|
||||
volatile void **pLocalAddress);
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* connect ISR to an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* connect ISR to a PCI interrupt
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptPCI(
|
||||
unsigned bus,
|
||||
unsigned device,
|
||||
unsigned function,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* disconnect ISR from an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* disconnect ISR from a PCI interrupt
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptPCI(
|
||||
unsigned bus,
|
||||
unsigned device,
|
||||
unsigned function,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* determine if a VME interrupt vector is in use
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* determine if an ISA interrupt level is in use
|
||||
* (not implemented)
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
|
||||
/*
|
||||
* determine if a PCI interrupt is in use
|
||||
* (not implemented)
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
epicsShareFunc int devInterruptInUsePCI (unsigned bus, unsigned device,
|
||||
unsigned function);
|
||||
|
||||
typedef enum {intVME, intVXI, intISA} epicsInterruptType;
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* enable ISA interrupt level
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* not implemented - API needs to be reviewed
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelPCI (unsigned level,
|
||||
unsigned bus, unsigned device, unsigned function);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* disable ISA interrupt level
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* not implemented - API needs to be reviewed
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelPCI (unsigned level,
|
||||
unsigned bus, unsigned device, unsigned function);
|
||||
|
||||
/*
|
||||
* Routines to allocate and free memory in the A24 memory region.
|
||||
*
|
||||
*/
|
||||
epicsShareFunc void *devLibA24Malloc(size_t);
|
||||
epicsShareFunc void *devLibA24Calloc(size_t);
|
||||
epicsShareFunc void devLibA24Free(void *pBlock);
|
||||
|
||||
/*
|
||||
* Normalize a digital value and convert it to type TYPE
|
||||
@@ -280,59 +55,6 @@ epicsShareFunc void devLibA24Free(void *pBlock);
|
||||
*/
|
||||
#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR)))
|
||||
|
||||
/*
|
||||
* virtual OS layer for devLib.c
|
||||
*/
|
||||
typedef struct devLibVirtualOS {
|
||||
/*
|
||||
* maps logical address to physical address, but does not detect
|
||||
* two device drivers that are using the same address range
|
||||
*/
|
||||
long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevConnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *), void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long (*pDevEnableInterruptLevelVME) (unsigned level);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long (*pDevDisableInterruptLevelVME) (unsigned level);
|
||||
/* malloc/free A24 address space */
|
||||
void *(*pDevA24Malloc)(size_t nbytes);
|
||||
void (*pDevA24Free)(void *pBlock);
|
||||
long (*pDevInit)(void);
|
||||
}devLibVirtualOS;
|
||||
epicsShareExtern devLibVirtualOS *pdevLibVirtualOS;
|
||||
|
||||
/*
|
||||
* error codes (and messages) associated with devLib.c
|
||||
*/
|
||||
@@ -374,71 +96,12 @@ epicsShareExtern devLibVirtualOS *pdevLibVirtualOS;
|
||||
#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/
|
||||
#define S_dev_vxWorksIntEnFail S_dev_intEnFail
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devConnectInterruptVME, devConnectInterruptPCI,
|
||||
* devConnectInterruptISA etc. devConnectInterrupt will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devConnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
#endif /* EPICSDEVLIB_H */
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI,
|
||||
* devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
|
||||
* in a future release.
|
||||
* Retain compatibility by including VME by default
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI,
|
||||
* devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevel(
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA,
|
||||
* devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevel (
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use devNoResponseProbe(). locationProbe() will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
|
||||
|
||||
/*
|
||||
* Some vxWorks convenience routines
|
||||
*/
|
||||
void bcopyLongs(char *source, char *destination, int nlongs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#ifndef NO_DEVLIB_COMPAT
|
||||
# include "devLibVME.h"
|
||||
#endif
|
||||
|
||||
#endif /* INCdevLibh.h*/
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
@@ -29,7 +31,10 @@ static const char sccsID[] = "@(#) $Id$";
|
||||
#include "epicsMutex.h"
|
||||
#include "errlog.h"
|
||||
#include "ellLib.h"
|
||||
#include "devLib.h"
|
||||
|
||||
#define NO_DEVLIB_COMPAT
|
||||
#include "devLibVME.h"
|
||||
#include "devLibVMEImpl.h"
|
||||
|
||||
static ELLLIST addrAlloc[atLast];
|
||||
static ELLLIST addrFree[atLast];
|
||||
@@ -167,7 +172,7 @@ long devBusToLocalAddr(
|
||||
/*
|
||||
* Call the virtual os routine to map the bus address to a CPU address
|
||||
*/
|
||||
status = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress);
|
||||
status = (*pdevLibVME->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress);
|
||||
if (status) {
|
||||
errPrintf (status, __FILE__, __LINE__, "%s bus address =0X%X\n",
|
||||
epicsAddressTypeName[addrType], (unsigned int)busAddr);
|
||||
@@ -275,7 +280,7 @@ long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVirtualOS->pDevReadProbe) (wordSize, ptr, pValue);
|
||||
return (*pdevLibVME->pDevReadProbe) (wordSize, ptr, pValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -295,7 +300,7 @@ long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVirtualOS->pDevWriteProbe) (wordSize, ptr, pValue);
|
||||
return (*pdevLibVME->pDevWriteProbe) (wordSize, ptr, pValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,7 +337,7 @@ static long devInstallAddr (
|
||||
* always map through the virtual os in case the memory
|
||||
* management is set up there
|
||||
*/
|
||||
status = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, base,
|
||||
status = (*pdevLibVME->pDevMapAddr) (addrType, 0, base,
|
||||
size, &pPhysicalAddress);
|
||||
if (status) {
|
||||
errPrintf (status, __FILE__, __LINE__, "%s base=0X%X size = 0X%X",
|
||||
@@ -697,8 +702,8 @@ static long devLibInit (void)
|
||||
|
||||
|
||||
if(devLibInitFlag) return(SUCCESS);
|
||||
if(!pdevLibVirtualOS) {
|
||||
epicsPrintf ("pdevLibVirtualOS is NULL\n");
|
||||
if(!pdevLibVME) {
|
||||
epicsPrintf ("pdevLibVME is NULL\n");
|
||||
return S_dev_internal;
|
||||
}
|
||||
|
||||
@@ -727,7 +732,7 @@ static long devLibInit (void)
|
||||
}
|
||||
epicsMutexUnlock(addrListLock);
|
||||
devLibInitFlag = TRUE;
|
||||
return pdevLibVirtualOS->pDevInit();
|
||||
return pdevLibVME->pDevInit();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -889,7 +894,7 @@ long devNoResponseProbe (epicsAddressType addrType,
|
||||
* every byte in the block must
|
||||
* map to a physical address
|
||||
*/
|
||||
s = (*pdevLibVirtualOS->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical);
|
||||
s = (*pdevLibVME->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical);
|
||||
if (s!=SUCCESS) {
|
||||
return s;
|
||||
}
|
||||
@@ -897,7 +902,7 @@ long devNoResponseProbe (epicsAddressType addrType,
|
||||
/*
|
||||
* verify that no device is present
|
||||
*/
|
||||
s = (*pdevLibVirtualOS->pDevReadProbe)(wordSize, pPhysical, &allWordSizes);
|
||||
s = (*pdevLibVME->pDevReadProbe)(wordSize, pPhysical, &allWordSizes);
|
||||
if (s==SUCCESS) {
|
||||
return S_dev_addressOverlap;
|
||||
}
|
||||
@@ -907,6 +912,82 @@ long devNoResponseProbe (epicsAddressType addrType,
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
long devConnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter )
|
||||
{
|
||||
long status;
|
||||
|
||||
if (!devLibInitFlag) {
|
||||
status = devLibInit();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber,
|
||||
pFunction, parameter);
|
||||
}
|
||||
|
||||
long devDisconnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *) )
|
||||
{
|
||||
long status;
|
||||
|
||||
if (!devLibInitFlag) {
|
||||
status = devLibInit();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction);
|
||||
}
|
||||
|
||||
int devInterruptInUseVME (unsigned level)
|
||||
{
|
||||
long status;
|
||||
|
||||
if (!devLibInitFlag) {
|
||||
status = devLibInit();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVME->pDevInterruptInUseVME) (level);
|
||||
}
|
||||
|
||||
long devEnableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
long status;
|
||||
|
||||
if (!devLibInitFlag) {
|
||||
status = devLibInit();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVME->pDevEnableInterruptLevelVME) (level);
|
||||
}
|
||||
|
||||
long devDisableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
long status;
|
||||
|
||||
if (!devLibInitFlag) {
|
||||
status = devLibInit();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return (*pdevLibVME->pDevDisableInterruptLevelVME) (level);
|
||||
}
|
||||
|
||||
/*
|
||||
* devConnectInterrupt ()
|
||||
*
|
||||
@@ -930,7 +1011,7 @@ void *parameter)
|
||||
switch(intType){
|
||||
case intVME:
|
||||
case intVXI:
|
||||
return (*pdevLibVirtualOS->pDevConnectInterruptVME) (vectorNumber,
|
||||
return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber,
|
||||
pFunction, parameter);
|
||||
default:
|
||||
return S_dev_uknIntType;
|
||||
@@ -961,7 +1042,7 @@ void (*pFunction)(void *)
|
||||
switch(intType){
|
||||
case intVME:
|
||||
case intVXI:
|
||||
return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber,
|
||||
return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber,
|
||||
pFunction);
|
||||
default:
|
||||
return S_dev_uknIntType;
|
||||
@@ -989,7 +1070,7 @@ unsigned level)
|
||||
switch(intType){
|
||||
case intVME:
|
||||
case intVXI:
|
||||
return (*pdevLibVirtualOS->pDevEnableInterruptLevelVME) (level);
|
||||
return (*pdevLibVME->pDevEnableInterruptLevelVME) (level);
|
||||
default:
|
||||
return S_dev_uknIntType;
|
||||
}
|
||||
@@ -1016,7 +1097,7 @@ unsigned level)
|
||||
switch(intType){
|
||||
case intVME:
|
||||
case intVXI:
|
||||
return (*pdevLibVirtualOS->pDevDisableInterruptLevelVME) (level);
|
||||
return (*pdevLibVME->pDevDisableInterruptLevelVME) (level);
|
||||
default:
|
||||
return S_dev_uknIntType;
|
||||
}
|
||||
@@ -1065,7 +1146,7 @@ void *devLibA24Malloc(size_t size)
|
||||
if (devLibA24Debug)
|
||||
epicsPrintf ("devLibA24Malloc(%u) entered\n", (unsigned int)size);
|
||||
|
||||
ret = pdevLibVirtualOS->pDevA24Malloc(size);
|
||||
ret = pdevLibVME->pDevA24Malloc(size);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@@ -1074,5 +1155,5 @@ void devLibA24Free(void *pBlock)
|
||||
if (devLibA24Debug)
|
||||
epicsPrintf("devLibA24Free(%p) entered\n", pBlock);
|
||||
|
||||
pdevLibVirtualOS->pDevA24Free(pBlock);
|
||||
pdevLibVME->pDevA24Free(pBlock);
|
||||
}
|
||||
312
src/libCom/osi/devLibVME.h
Normal file
312
src/libCom/osi/devLibVME.h
Normal file
@@ -0,0 +1,312 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, 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.
|
||||
\*************************************************************************/
|
||||
/* devLib.h */
|
||||
/* devLib.h,v 1.1.2.8 2009/07/09 15:27:43 anj Exp */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
*/
|
||||
|
||||
#ifndef INCdevLibh
|
||||
#define INCdevLibh 1
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "osdVME.h"
|
||||
#include "errMdef.h"
|
||||
#include "shareLib.h"
|
||||
#include "devLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* epdevAddressType & EPICStovxWorksAddrType
|
||||
* devLib.c must change in unison
|
||||
*/
|
||||
typedef enum {
|
||||
atVMEA16,
|
||||
atVMEA24,
|
||||
atVMEA32,
|
||||
atISA, /* memory mapped ISA access (until now only on PC) */
|
||||
atVMECSR, /* VME-64 CR/CSR address space */
|
||||
atLast /* atLast must be the last enum in this list */
|
||||
} epicsAddressType;
|
||||
|
||||
/*
|
||||
* pointer to an array of strings for each of
|
||||
* the above address types
|
||||
*/
|
||||
epicsShareExtern const char *epicsAddressTypeName[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To retain compatibility include everything by default
|
||||
*/
|
||||
#ifndef NO_DEVLIB_COMPAT
|
||||
# include "devLibVMEImpl.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General API
|
||||
*
|
||||
* This section applies to all bus types
|
||||
*/
|
||||
|
||||
epicsShareFunc long devAddressMap(void); /* print an address map */
|
||||
|
||||
/*
|
||||
* devBusToLocalAddr()
|
||||
*
|
||||
* OSI routine to translate bus addresses their local CPU address mapping
|
||||
*/
|
||||
epicsShareFunc long devBusToLocalAddr (
|
||||
epicsAddressType addrType,
|
||||
size_t busAddr,
|
||||
volatile void **ppLocalAddr);
|
||||
/*
|
||||
* devReadProbe()
|
||||
*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
epicsShareFunc long devReadProbe (
|
||||
unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* devNoResponseProbe()
|
||||
*
|
||||
* Verifies that no devices respond at naturally aligned words
|
||||
* within the specified address range. Return success if no devices
|
||||
* respond. Returns an error if a device does respond or if
|
||||
* a physical address for a naturally aligned word cant be mapped.
|
||||
* Checks all naturally aligned word sizes between char and long for
|
||||
* the entire specified range of bytes.
|
||||
*/
|
||||
epicsShareFunc long devNoResponseProbe(
|
||||
epicsAddressType addrType,
|
||||
size_t base,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/*
|
||||
* devWriteProbe
|
||||
*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
epicsShareFunc long devWriteProbe (
|
||||
unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
epicsShareFunc long devRegisterAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
size_t size, /* bytes */
|
||||
volatile void **pPhysicalAddress);
|
||||
|
||||
epicsShareFunc long devUnregisterAddress(
|
||||
epicsAddressType addrType,
|
||||
size_t logicalBaseAddress,
|
||||
const char *pOwnerName);
|
||||
|
||||
/*
|
||||
* allocate and register an unoccupied address block
|
||||
*/
|
||||
epicsShareFunc long devAllocAddress(
|
||||
const char *pOwnerName,
|
||||
epicsAddressType addrType,
|
||||
size_t size,
|
||||
unsigned alignment, /*n ls bits zero in addr*/
|
||||
volatile void **pLocalAddress);
|
||||
|
||||
/*
|
||||
* VME API
|
||||
*
|
||||
* Functions in this section apply only to the VME bus type
|
||||
*/
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptVME(
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* determine if a VME interrupt vector is in use
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelVME (unsigned level);
|
||||
|
||||
/*
|
||||
* Routines to allocate and free memory in the A24 memory region.
|
||||
*
|
||||
*/
|
||||
epicsShareFunc void *devLibA24Malloc(size_t);
|
||||
epicsShareFunc void *devLibA24Calloc(size_t);
|
||||
epicsShareFunc void devLibA24Free(void *pBlock);
|
||||
|
||||
/*
|
||||
* ISA API
|
||||
*
|
||||
* Functions in this section apply only to the ISA bus type
|
||||
*/
|
||||
|
||||
/*
|
||||
* connect ISR to an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*/
|
||||
epicsShareFunc long devConnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from an ISA interrupt level
|
||||
* (not implemented)
|
||||
* (API should be reviewed)
|
||||
*
|
||||
* The parameter pFunction should be set to the C function pointer that
|
||||
* was connected. It is used as a key to prevent a driver from inadvertently
|
||||
* removing an interrupt handler that it didn't install
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterruptISA(
|
||||
unsigned interruptLevel,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* determine if an ISA interrupt level is in use
|
||||
* (not implemented)
|
||||
*
|
||||
* returns boolean
|
||||
*/
|
||||
epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel);
|
||||
|
||||
/*
|
||||
* enable ISA interrupt level
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* disable ISA interrupt level
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevelISA (unsigned level);
|
||||
|
||||
/*
|
||||
* Deprecated interface
|
||||
*/
|
||||
|
||||
#ifndef NO_DEVLIB_OLD_INTERFACE
|
||||
|
||||
typedef enum {intVME, intVXI, intISA} epicsInterruptType;
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devConnectInterruptVME, devConnectInterruptPCI,
|
||||
* devConnectInterruptISA etc. devConnectInterrupt will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devConnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *),
|
||||
void *parameter);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI,
|
||||
* devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devDisconnectInterrupt(
|
||||
epicsInterruptType intType,
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI,
|
||||
* devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devEnableInterruptLevel(
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA,
|
||||
* devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long devDisableInterruptLevel (
|
||||
epicsInterruptType intType, unsigned level);
|
||||
|
||||
/*
|
||||
* NOTE: this routine has been deprecated. It exists
|
||||
* for backwards compatibility purposes only.
|
||||
*
|
||||
* Please use devNoResponseProbe(). locationProbe() will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation);
|
||||
|
||||
#endif /* NO_DEVLIB_OLD_INTERFACE */
|
||||
|
||||
/*
|
||||
* Some vxWorks convenience routines
|
||||
*/
|
||||
void bcopyLongs(char *source, char *destination, int nlongs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCdevLibh.h*/
|
||||
104
src/libCom/osi/devLibVMEImpl.h
Normal file
104
src/libCom/osi/devLibVMEImpl.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, 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.
|
||||
\*************************************************************************/
|
||||
/* devLibImpl.h */
|
||||
/* */
|
||||
|
||||
/*
|
||||
* Original Author: Marty Kraimer
|
||||
* Author: Jeff Hill
|
||||
* Date: 03-10-93
|
||||
*/
|
||||
|
||||
#ifndef INCdevLibImplh
|
||||
#define INCdevLibImplh 1
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "shareLib.h"
|
||||
#include "devLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* virtual OS layer for devLib.c
|
||||
*
|
||||
* The global virtual OS table pdevLibVME controls
|
||||
* the behaviour of the functions defined in devLib.h.
|
||||
* All of which call into the functions found in this table
|
||||
* to perform system specific tasks.
|
||||
*/
|
||||
typedef struct devLibVME {
|
||||
/*
|
||||
* maps logical address to physical address, but does not detect
|
||||
* two device drivers that are using the same address range
|
||||
*/
|
||||
long (*pDevMapAddr) (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten);
|
||||
|
||||
/*
|
||||
* connect ISR to a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevConnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *), void *parameter);
|
||||
|
||||
/*
|
||||
* disconnect ISR from a VME interrupt vector
|
||||
* (required for backwards compatibility)
|
||||
*/
|
||||
long (*pDevDisconnectInterruptVME) (unsigned vectorNumber,
|
||||
void (*pFunction)(void *));
|
||||
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long (*pDevEnableInterruptLevelVME) (unsigned level);
|
||||
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long (*pDevDisableInterruptLevelVME) (unsigned level);
|
||||
/* malloc/free A24 address space */
|
||||
void *(*pDevA24Malloc)(size_t nbytes);
|
||||
void (*pDevA24Free)(void *pBlock);
|
||||
long (*pDevInit)(void);
|
||||
|
||||
/*
|
||||
* test if VME interrupt has an ISR connected
|
||||
*/
|
||||
int (*pDevInterruptInUseVME) (unsigned vectorNumber);
|
||||
}devLibVME;
|
||||
|
||||
epicsShareExtern devLibVME *pdevLibVME;
|
||||
|
||||
#ifndef NO_DEVLIB_COMPAT
|
||||
# define pdevLibVirtualOS pdevLibVME
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCdevLibImplh */
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <epicsExit.h>
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include "devLib.h"
|
||||
#include "devLibVME.h"
|
||||
#include <epicsInterrupt.h>
|
||||
|
||||
#if defined(__PPC__) || defined(__mcf528x__)
|
||||
@@ -36,7 +36,7 @@ static myISR *isrFetch(unsigned vectorNumber, void **parg);
|
||||
* this routine needs to be in the symbol table
|
||||
* for this code to work correctly
|
||||
*/
|
||||
void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
|
||||
static myISR *defaultHandlerAddr[]={
|
||||
(myISR*)unsolicitedHandlerEPICS,
|
||||
@@ -72,42 +72,58 @@ int EPICStovxWorksAddrType[]
|
||||
* maps logical address to physical address, but does not detect
|
||||
* two device drivers that are using the same address range
|
||||
*/
|
||||
static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options,
|
||||
static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" read at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
|
||||
static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue);
|
||||
|
||||
/*
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
|
||||
static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue);
|
||||
|
||||
static long rtemsDevConnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(),
|
||||
void *parameter);
|
||||
|
||||
static long rtemsDevDisconnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)()
|
||||
);
|
||||
|
||||
static long rtemsDevEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
static long rtemsDevDisableInterruptLevelVME (unsigned level);
|
||||
|
||||
static int rtemsDevInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/* RTEMS specific init */
|
||||
|
||||
/*devA24Malloc and devA24Free are not implemented*/
|
||||
static void *devA24Malloc(size_t size) { return 0;}
|
||||
static void devA24Free(void *pBlock) {};
|
||||
static long rtmsDevInit(void);
|
||||
static long rtemsDevInit(void);
|
||||
|
||||
/*
|
||||
* used by bind in devLib.c
|
||||
*/
|
||||
static devLibVirtualOS rtemsVirtualOS = {
|
||||
rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe,
|
||||
devConnectInterruptVME, devDisconnectInterruptVME,
|
||||
devEnableInterruptLevelVME, devDisableInterruptLevelVME,
|
||||
devA24Malloc,devA24Free,rtmsDevInit
|
||||
static devLibVME rtemsVirtualOS = {
|
||||
rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe,
|
||||
rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME,
|
||||
rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME,
|
||||
devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME
|
||||
};
|
||||
devLibVirtualOS *pdevLibVirtualOS = &rtemsVirtualOS;
|
||||
devLibVME *pdevLibVME = &rtemsVirtualOS;
|
||||
|
||||
/* RTEMS specific initialization */
|
||||
static long
|
||||
rtmsDevInit(void)
|
||||
rtemsDevInit(void)
|
||||
{
|
||||
/* assume the vme bridge has been initialized by bsp */
|
||||
/* init BSP extensions [memProbe etc.] */
|
||||
@@ -119,7 +135,7 @@ rtmsDevInit(void)
|
||||
*
|
||||
* wrapper to minimize driver dependency on OS
|
||||
*/
|
||||
long devConnectInterruptVME (
|
||||
static long rtemsDevConnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(),
|
||||
void *parameter)
|
||||
@@ -152,7 +168,7 @@ long devConnectInterruptVME (
|
||||
* an interrupt handler that was installed by another driver
|
||||
*
|
||||
*/
|
||||
long devDisconnectInterruptVME (
|
||||
static long rtemsDevDisconnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)()
|
||||
)
|
||||
@@ -188,7 +204,7 @@ long devDisconnectInterruptVME (
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long devEnableInterruptLevelVME (unsigned level)
|
||||
static long rtemsDevEnableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
return BSP_enableVME_int_lvl(level);
|
||||
}
|
||||
@@ -196,15 +212,15 @@ long devEnableInterruptLevelVME (unsigned level)
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long devDisableInterruptLevelVME (unsigned level)
|
||||
static long rtemsDevDisableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
return BSP_disableVME_int_lvl(level);
|
||||
}
|
||||
|
||||
/*
|
||||
* rtmsDevMapAddr ()
|
||||
* rtemsDevMapAddr ()
|
||||
*/
|
||||
static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options,
|
||||
static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options,
|
||||
size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress)
|
||||
{
|
||||
long status;
|
||||
@@ -234,7 +250,7 @@ static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options,
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval);
|
||||
long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
|
||||
static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue)
|
||||
{
|
||||
long status;
|
||||
|
||||
@@ -253,7 +269,7 @@ long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue
|
||||
* a bus error safe "wordSize" write at the specified address which returns
|
||||
* unsuccessful status if the device isnt present
|
||||
*/
|
||||
long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
|
||||
static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue)
|
||||
{
|
||||
long status;
|
||||
|
||||
@@ -282,7 +298,7 @@ static myISR *isrFetch(unsigned vectorNumber, void **parg)
|
||||
/*
|
||||
* determine if a VME interrupt vector is in use
|
||||
*/
|
||||
int devInterruptInUseVME (unsigned vectorNumber)
|
||||
static int rtemsDevInterruptInUseVME (unsigned vectorNumber)
|
||||
{
|
||||
int i;
|
||||
myISR *psub;
|
||||
@@ -319,7 +335,7 @@ int devInterruptInUseVME (unsigned vectorNumber)
|
||||
* macro to declare handler prototypes...
|
||||
*
|
||||
*/
|
||||
void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
{
|
||||
/*
|
||||
* call epicInterruptContextMessage()
|
||||
@@ -64,16 +64,16 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
|
||||
startupInfo.wShowWindow = SW_SHOWMINNOACTIVE;
|
||||
|
||||
status = CreateProcess (
|
||||
NULL, // pointer to name of executable module (not required if command line is specified)
|
||||
(char *) pBaseExecutableName, // pointer to command line string
|
||||
NULL, // pointer to process security attributes
|
||||
NULL, // pointer to thread security attributes
|
||||
FALSE, // handle inheritance flag
|
||||
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, // creation flags
|
||||
NULL, // pointer to new environment block (defaults to caller's environement)
|
||||
NULL, // pointer to current directory name (defaults to caller's current directory)
|
||||
&startupInfo, // pointer to STARTUPINFO
|
||||
&processInfo // pointer to PROCESS_INFORMATION
|
||||
NULL, /* pointer to name of executable module (not required if command line is specified) */
|
||||
(char *) pBaseExecutableName, /* pointer to command line string */
|
||||
NULL, /* pointer to process security attributes */
|
||||
NULL, /* pointer to thread security attributes */
|
||||
FALSE, /* handle inheritance flag */
|
||||
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */
|
||||
NULL, /* pointer to new environment block (defaults to caller's environement) */
|
||||
NULL, /* pointer to current directory name (defaults to caller's current directory) */
|
||||
&startupInfo, /* pointer to STARTUPINFO */
|
||||
&processInfo /* pointer to PROCESS_INFORMATION */
|
||||
);
|
||||
if ( status == 0 ) {
|
||||
DWORD W32status;
|
||||
@@ -84,7 +84,7 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
GetLastError (),
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
|
||||
(LPTSTR) &errStrMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
@@ -107,24 +107,24 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
|
||||
FORMAT_MESSAGE_ARGUMENT_ARRAY | 80,
|
||||
"%1 \"%2\". %3 %4 %5 \"%6\"",
|
||||
0,
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
|
||||
(LPTSTR) &complteMsgBuf,
|
||||
0,
|
||||
pFmtArgs
|
||||
);
|
||||
if (W32status) {
|
||||
// Display the string.
|
||||
/* Display the string. */
|
||||
MessageBox (NULL, complteMsgBuf, "Configuration Problem",
|
||||
MB_OK | MB_ICONINFORMATION);
|
||||
LocalFree (complteMsgBuf);
|
||||
}
|
||||
else {
|
||||
// Display the string.
|
||||
/* Display the string. */
|
||||
MessageBox (NULL, errStrMsgBuf, "Failed to start executable",
|
||||
MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
// Free the buffer.
|
||||
/* Free the buffer. */
|
||||
LocalFree (errStrMsgBuf);
|
||||
}
|
||||
else {
|
||||
@@ -137,16 +137,17 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce
|
||||
|
||||
return osiSpawnDetachedProcessSuccess;
|
||||
|
||||
//
|
||||
// use of spawn here causes problems when the ca repeater
|
||||
// inherits open files (and sockets) from the spawning
|
||||
// process
|
||||
//
|
||||
//status = _spawnlp (_P_DETACH, pBaseExecutableName, pBaseExecutableName, NULL);
|
||||
//if (status<0) {
|
||||
// errlogPrintf ("!!WARNING!!\n");
|
||||
// errlogPrintf ("Unable to locate the EPICS executable \"%s\".\n",
|
||||
// pBaseExecutableName);
|
||||
// errlogPrintf ("You may need to modify your environment.\n");
|
||||
//}
|
||||
/*
|
||||
use of spawn here causes problems when the ca repeater
|
||||
inherits open files (and sockets) from the spawning
|
||||
process
|
||||
|
||||
status = _spawnlp (_P_DETACH, pBaseExecutableName, pBaseExecutableName, NULL);
|
||||
if (status<0) {
|
||||
errlogPrintf ("!!WARNING!!\n");
|
||||
errlogPrintf ("Unable to locate the EPICS executable \"%s\".\n",
|
||||
pBaseExecutableName);
|
||||
errlogPrintf ("You may need to modify your environment.\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "devLib.h"
|
||||
#include "devLibVME.h"
|
||||
|
||||
epicsShareDef devLibVirtualOS *pdevLibVirtualOS = NULL;
|
||||
epicsShareDef devLibVME *pdevLibVME = NULL;
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "devLib.h"
|
||||
#include "devLibVME.h"
|
||||
|
||||
/* This file must contain no definitions other than the following: */
|
||||
|
||||
devLibVirtualOS *pdevLibVirtualOS;
|
||||
devLibVME *pdevLibVME;
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <vxLib.h>
|
||||
|
||||
#include "epicsFindSymbol.h"
|
||||
#include "devLib.h"
|
||||
#include "devLibVME.h"
|
||||
#include "errlog.h"
|
||||
|
||||
typedef void myISR (void *pParam);
|
||||
@@ -52,7 +52,7 @@ static myISR *isrFetch(unsigned vectorNumber);
|
||||
* this routine needs to be in the symbol table
|
||||
* for this code to work correctly
|
||||
*/
|
||||
void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber);
|
||||
|
||||
/*
|
||||
* this is in veclist.c
|
||||
@@ -114,23 +114,39 @@ static void *devA24Malloc(size_t size);
|
||||
static void devA24Free(void *pBlock);
|
||||
static long devInit(void) { return 0;}
|
||||
|
||||
static long vxDevConnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(),
|
||||
void *parameter);
|
||||
|
||||
static long vxDevDisconnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)()
|
||||
);
|
||||
|
||||
static long vxDevEnableInterruptLevelVME (unsigned level);
|
||||
|
||||
static long vxDevDisableInterruptLevelVME (unsigned level);
|
||||
|
||||
static int vxDevInterruptInUseVME (unsigned vectorNumber);
|
||||
|
||||
/*
|
||||
* used by dynamic bind in devLib.c
|
||||
*/
|
||||
static devLibVirtualOS vxVirtualOS = {
|
||||
static devLibVME vxVirtualOS = {
|
||||
vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe,
|
||||
devConnectInterruptVME, devDisconnectInterruptVME,
|
||||
devEnableInterruptLevelVME, devDisableInterruptLevelVME,
|
||||
devA24Malloc,devA24Free,devInit
|
||||
vxDevConnectInterruptVME, vxDevDisconnectInterruptVME,
|
||||
vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME,
|
||||
devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME
|
||||
};
|
||||
devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS;
|
||||
devLibVME *pdevLibVME = &vxVirtualOS;
|
||||
|
||||
/*
|
||||
* devConnectInterruptVME
|
||||
*
|
||||
* wrapper to minimize driver dependency on vxWorks
|
||||
*/
|
||||
long devConnectInterruptVME (
|
||||
static long vxDevConnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)(),
|
||||
void *parameter)
|
||||
@@ -154,7 +170,7 @@ long devConnectInterruptVME (
|
||||
|
||||
/*
|
||||
*
|
||||
* devDisconnectInterruptVME()
|
||||
* vxDevDisconnectInterruptVME()
|
||||
*
|
||||
* wrapper to minimize driver dependency on vxWorks
|
||||
*
|
||||
@@ -163,7 +179,7 @@ long devConnectInterruptVME (
|
||||
* an interrupt handler that was installed by another driver
|
||||
*
|
||||
*/
|
||||
long devDisconnectInterruptVME (
|
||||
static long vxDevDisconnectInterruptVME (
|
||||
unsigned vectorNumber,
|
||||
void (*pFunction)()
|
||||
)
|
||||
@@ -198,7 +214,7 @@ long devDisconnectInterruptVME (
|
||||
/*
|
||||
* enable VME interrupt level
|
||||
*/
|
||||
long devEnableInterruptLevelVME (unsigned level)
|
||||
static long vxDevEnableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
# if CPU_FAMILY != I80X86
|
||||
int s;
|
||||
@@ -250,7 +266,7 @@ long devDisableInterruptLevelISA (unsigned level)
|
||||
/*
|
||||
* disable VME interrupt level
|
||||
*/
|
||||
long devDisableInterruptLevelVME (unsigned level)
|
||||
static long vxDevDisableInterruptLevelVME (unsigned level)
|
||||
{
|
||||
# if CPU_FAMILY != I80X86
|
||||
int s;
|
||||
@@ -359,7 +375,7 @@ static myISR *isrFetch(unsigned vectorNumber)
|
||||
/*
|
||||
* determine if a VME interrupt vector is in use
|
||||
*/
|
||||
int devInterruptInUseVME (unsigned vectorNumber)
|
||||
static int vxDevInterruptInUseVME (unsigned vectorNumber)
|
||||
{
|
||||
#if CPU_FAMILY == PPC
|
||||
return FALSE;
|
||||
@@ -397,7 +413,7 @@ int devInterruptInUseVME (unsigned vectorNumber)
|
||||
* disconnected vector
|
||||
*
|
||||
*/
|
||||
void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
static void unsolicitedHandlerEPICS(int vectorNumber)
|
||||
{
|
||||
/*
|
||||
* call logMsg() and not errMessage()
|
||||
Reference in New Issue
Block a user