From ca3138e6171008cef74c62652b4bbbd01764a9c6 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 10:34:14 +0100 Subject: [PATCH 01/36] Adding capr.pl --- src/cap5/capr.pl | 419 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 src/cap5/capr.pl diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl new file mode 100644 index 000000000..f78741412 --- /dev/null +++ b/src/cap5/capr.pl @@ -0,0 +1,419 @@ +#!/usr/bin/perl -w + +####################################################################### +# +# capr: A program that attempts to do a "dbpr" command via channel +# access. +# +####################################################################### + +use strict; +use Getopt::Std; +use lib "/dls_sw/epics/R3.14.11/base/lib/perl"; +use CA; + +######### Globals ########## + +# Non APS users will want to modify theDbdFile default settings + +my $theDbdFile = "/net/helios/iocapps/R3.13.9/ioc/linac/2/dbd/linac.dbd"; + +my $hostArch; +if ( defined $ENV{"EPICS_HOST_ARCH"} ) { + $hostArch = $ENV{"EPICS_HOST_ARCH"} ; +} else { + $hostArch="solaris-sparc"; +} + +our( $opt_d, $opt_f, $opt_r); +my $usage = "Usage:\n $0 [-d dbd_file] ( [-f record_type] | [-r] | [record_name] ) [interest]\n"; +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 +my $DEBUG=0; # DEBUG + +# EPICS field types referenced to their equivalent EZCA types +my %fieldType = ( + DBF_STRING => "ezcaString", + DBF_BYTE => "ezcaByte", + DBF_CHAR => "ezcaByte", + DBF_UCHAR => "ezcaChar", + DBF_SHORT => "ezcaShort", + DBF_USHORT => "ezcaLong", + DBF_LONG => "ezcaLong", + DBF_ULONG => "ezcaDouble", + DBF_FLOAT => "ezcaFloat", + DBF_DOUBLE => "ezcaDouble", + DBF_ENUM => "ezcaString", + DBF_MENU => "ezcaString", + DBF_DEVICE => "ezcaString", + DBF_INLINK => "ezcaString", + DBF_OUTLINK => "ezcaString", + DBF_FWDLINK => "ezcaString", + DBF_NOACCESS => "ezcaNoAccess" +); + + +######### Main program ############ + +getopts('d:f:r') or die "$usage"; + +# Select the dbd file to use +if($opt_d) { # command line has highest priority + $theDbdFile = $opt_d; +} +elsif (exists $ENV{CAPR_DBD_FILE}) { # Use the env var if it exists + $theDbdFile = $ENV{CAPR_DBD_FILE}; +} # Otherwise use the default set above + +parseDbd($theDbdFile); +print "Using $theDbdFile\n\n"; + +# Print a list of record types +if($opt_r) { + print ("Record types defined in $theDbdFile\n"); + printList(0); + exit; +} + +# Print the fields defined for given record +if($opt_f) { + printRecordList($opt_f); + exit; +} +#my @data; +#@data = EZCA::Get("S:BM:TMDispAI.VAL", "ezcaDouble",1); +#if( $data[0] ) { die "ca get error on field --" }; +#print(" $data[1] "); +#die "end"; + +# Do the business +# Allow commas between arguments as in vxWorks dbpr +die "$usage" unless defined $ARGV[0]; +$ARGV[0] =~ s/,/ /; # Get rid of pesky comma if it's there +if($ARGV[0] =~ m/\s+\d/) { # If we replace comma with a space, + ($ARGV[0], $ARGV[1]) = split(/ /, $ARGV[0]); #split it +} +$ARGV[0] =~ s/\s+//; # Remove any spaces +$ARGV[0] =~ s/\..*//; # Get rid of field name if it's there +$ARGV[1] =~ s/\D//g; # Make sure we only use digits +$ARGV[1] = $ARGV[1] || 0; # interest defaults to 0 +printRecord($ARGV[0], $ARGV[1]); # Do the do + + +########## 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: void parseDbd("fileName"); +# Output is in the hash %record. This is a hash of (references to) another. +# hash containing the fields of this record, as keys. The value keyed by +# the field names are (references to) arrays. Each of these arrays contains +# the interest level, data type and base of the field +sub parseDbd { + my $dbdFile = $_[0]; + my @dbd; + my $length; + my $level = 0; + my $i = 0; + my $isArecord = 0; + my $isAfield; + my $thisRecord; + my $thisField; + my $thisType; + my %field = (); + my @params = (); + my $interest = 0; + my $thisBase = "DECIMAL"; + my $item; + my $newDevice; + + open(DBD, "< $dbdFile") || die "Can't open dbd file $dbdFile --"; + @dbd = ; + $length = @dbd; + close(DBD) || die "Can't close $dbdFile --"; + + while ($i < $length) { + $_ = $dbd[$i]; + chomp; + print("line $i - level $level\n") if ($DEBUG); + #$line = $dbd[$i] || die "Unexpected end of file: $dbdFile, line $."; + if( m/recordtype/ ) { + ($level == 0) || die "dbd file format error in or before line $i --"; + m/\((.*)\)/; #get record type + #@records = (@records, $1); + $isArecord = 1; + $thisRecord = $1; + } + if( m/field/ ) { + ($level == 1 && $isArecord) || die "dbd file format error in or before line $i --"; + m/\((.*),/; # get field name + $thisField = $1; + m/,(.*)\)/; # get field type + $thisType = $1; + $isAfield = 1; + #print("$1 , line $i "); + } + if( m/interest/ ) { + ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; + m/\((.*)\)/ ; # get interest level, default = 0 + $interest = $1; + } + if( m/base/ ) { + ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; + m/\((.*)\)/ ; # get base, default = DECIMAL + $thisBase = $1; + } + if( m/\{/ ) { $level++ }; + if( m/\}/ ) { + if( $level == 2 && $isAfield) { + $isAfield = 0; + $params[$iIdx] = $interest; + $params[$tIdx] = $thisType; + $params[$bIdx] = $thisBase; + $field{$thisField} = [@params]; + #print("interest $interest\n"); + $interest = 0; # set up default for next time + $thisBase = "DECIMAL"; # set up default for next time + } + if( $level == 1 && $isArecord) { + $isArecord = 0; + $record{$thisRecord} = { %field }; + #print("record type $thisRecord "); + #foreach $key (keys(%field)) { + # print("Field $key - interest $field{$key}\n"); + #} + %field = (); # set up for next time + } + $level--; + } + # Parse for record types with device support + if( m/device/ ) { + m/\((.*?),/; + if(!exists($device{$1})) { + # Use a hash to make a list of record types with device support + $device{$1} = 1; + } + } + $i++; + } +} + + +# Given a record name attempts to find the record and its type. +# Usage: getRecType(recordName) - returns ($error, $recordType) +sub getRecType { + my $name = $_[0] . ".RTYP"; + my $type; + my $data; + + $data = caget($name); + if ($data =~ m/Invalid channel name/) { die "Record \"$_[0]\" not found\n"; } + chomp $data; + $data =~ s/\s+//; + #print("$name is a \"$data\"type\n"); + return($data); +} + +# Given the record type and the field returns the interest level, data type +# and base for the field +# Usage: ($dataType, $interest, $base) getFieldParams( $recType, $field) +sub getFieldParams { + my $recType = $_[0]; + my $field = $_[1]; + my ($fType, $fInterest, $fBase); + + exists($fieldType{$record{$recType}{$field}[$tIdx]}) || + die "Field data type $field for $recType not found in dbd file --"; + exists($record{$recType}{$field}[$iIdx]) || + die "Interest level for $field in $recType not found in dbd file --"; + + $fType = $fieldType{$record{$recType}{$field}[$tIdx]}; + $fInterest = $record{$recType}{$field}[$iIdx]; + $fBase = $record{$recType}{$field}[$bIdx]; + #print("getFieldParams: $recType, $field, $fType, $fInterest\n"); + 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 = $_[0]; + my $fieldData = $_[1]; + my $dataType = $_[2]; + my $base = $_[3]; # base to display numeric data in + my $col = $_[4]; # first column to print in + + my $screenWidth = 80; + my ($outStr, $len, $wide, $pad, $field); + + $field = $fieldName . ":"; + + if( $dataType eq "ezcaString" ) { + $outStr = sprintf("%-5s %s", $field, $fieldData); + } elsif ( $base eq "HEX" ) { + $outStr = sprintf("%-5s %x", $field, $fieldData); + } elsif ( $dataType eq "ezcaDouble" || $dataType eq "ezcaFloat" ) { + $outStr = sprintf("%-5s %.8f", $field, $fieldData); + } elsif ( $dataType eq "ezcaShort" ) { + $outStr = sprintf("%-5s %d", $field, $fieldData); + } elsif ( $dataType eq "ezcaChar" ) { + $outStr = sprintf("%-5s %d", $field, ord($fieldData)); + }else { + $outStr = sprintf("%-5s %d", $field, $fieldData); + } + + $len = length($outStr); + if($len <= 20) { $wide = 20; } + elsif( $len <= 40 ) { $wide = 40; } + elsif( $len <= 60 ) { $wide = 60; } + else { $wide = 80;} + + $pad = $wide - $len; + #print "outStr=$outStr .. pad=$pad\n"; + + if( $col + $wide > $screenWidth ) { + print("\n"); + $col = 0; + } + + print sprintf("$outStr%*s",$pad," "); + $col = $col + $wide; + + return($col); +} + +# Given record name and interest level prints data from record fields +# that are at or below the interest level specified. +# Useage: printRecord( $recordName, $interestLevel) +sub printRecord { + my $name = $_[0]; + my $interest = $_[1]; + my ($error, $recType, $field, $fType, $fInterest, $data); + my ($fToGet, $col, $base); + #print("checking record $name, interest $interest\n"); + $col = 0; + + $recType = getRecType($name); + print("$name is record type $recType\n"); + exists($record{$recType}) || die "Record type $recType not found in dbd file --"; + + foreach $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; } + + ($fType, $fInterest, $base) = getFieldParams($recType, $field); + unless( $fType eq "ezcaNoAccess" ) { + if( $interest >= $fInterest ) { + $fToGet = $name . "." . $field; + $data = caget($fToGet); + chomp $data; + #$data =~ s/\s+//; + #if( $data[0] ) { die "ca get error on field $field --" }; + $col = printField($field, $data, $fType, $base, $col); + #print ("fType = $fType $data[1]\n"); + } + } + } + print("\n"); # Final line feed +} + +# 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 = $_[0]; + my ($rkey, $fkey); + + foreach $rkey (sort keys(%record)) { + print("$rkey\n"); + if($level > 0) { + foreach $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 ($rkey, $fkey); + my $type = $_[0]; + + if( exists($record{$type}) ) { + print("Record type - $type\n"); + foreach $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 $theDbdFile\n"); + } +} + +# variable to communicate callback handler result +my $callback_data; +my $incomplete; +my $cadebug = 0; + +# returns a terse result of a caget operation +# using perlCA +sub caget { + my $name = $_[0]; + print $name . "\n" if $cadebug; + show_call_stack() if $cadebug; + my $channel = CA->new($name); + my $wait = 1; + eval { CA->pend_io($wait); }; + if ($@) { + if ($@ =~ m/^ECA_TIMEOUT/) { + my $err = "'" . $channel . "'"; + print "Channel connect timed out: $err not found.\n"; + } + die $@; + } + my $type = $channel->field_type; + my $count = $channel->element_count; + $channel->get_callback(\&callback_handler, $type); + $incomplete = 1; + CA->pend_event(0.1) while ($incomplete); + return $callback_data; +} + +sub callback_handler +{ + my ($chan, $status, $data) = @_; + die $status if $status; + #display($chan, $type, $data); + $callback_data = $data; + $incomplete=0; +} + +sub show_call_stack { + my ( $path, $line, $subr ); + my $max_depth = 30; + my $i = 1; + print("--- Begin stack trace ---\n"); + my @call_details; + @call_details = caller($i); + while ( (@call_details) && ($i<$max_depth) ) { + print("$call_details[1] line $call_details[2] in function $call_details[3]\n"); + $i = $i +1; + @call_details = caller($i); + } + print("--- End stack trace ---\n"); +} + From 99605c85fa6a6ffed0c5debd316cc47fa2fb149c Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 11:14:50 +0100 Subject: [PATCH 02/36] relocating library refs within base --- src/cap5/capr.pl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index f78741412..672fd509d 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -8,8 +8,11 @@ ####################################################################### use strict; + +use FindBin qw($Bin); +use lib "$Bin/../../lib/perl"; + use Getopt::Std; -use lib "/dls_sw/epics/R3.14.11/base/lib/perl"; use CA; ######### Globals ########## @@ -83,11 +86,6 @@ if($opt_f) { printRecordList($opt_f); exit; } -#my @data; -#@data = EZCA::Get("S:BM:TMDispAI.VAL", "ezcaDouble",1); -#if( $data[0] ) { die "ca get error on field --" }; -#print(" $data[1] "); -#die "end"; # Do the business # Allow commas between arguments as in vxWorks dbpr From 62d035c3109cca06496119a4faefb3f1b8daa087 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:42 +0100 Subject: [PATCH 03/36] [PATCH 01/12] add jumping VME interrupt routines to independent implementation Adds implementations which use the virtual os table to invoke the OS specific call. rename conflicting functions --- src/libCom/osi/devLib.c | 62 +++++++++++++++++++++++++++ src/libCom/osi/os/RTEMS/devLibOSD.c | 26 ++++++++--- src/libCom/osi/os/vxWorks/devLibOSD.c | 28 +++++++++--- 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/libCom/osi/devLib.c b/src/libCom/osi/devLib.c index 8e03f86d9..6e2f44bbd 100644 --- a/src/libCom/osi/devLib.c +++ b/src/libCom/osi/devLib.c @@ -907,6 +907,68 @@ 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 (*pdevLibVirtualOS->pDevConnectInterruptVME) (vectorNumber, + pFunction, parameter); +} + +long devDisconnectInterruptVME( +unsigned vectorNumber, +void (*pFunction)(void *) ) +{ + long status; + + if (!devLibInitFlag) { + status = devLibInit(); + if (status) { + return status; + } + } + + return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber, pFunction); +} + +long devEnableInterruptLevelVME (unsigned level) +{ + long status; + + if (!devLibInitFlag) { + status = devLibInit(); + if (status) { + return status; + } + } + + return (*pdevLibVirtualOS->pDevEnableInterruptLevelVME) (level); +} + +long devDisableInterruptLevelVME (unsigned level) +{ + long status; + + if (!devLibInitFlag) { + status = devLibInit(); + if (status) { + return status; + } + } + + return (*pdevLibVirtualOS->pDevDisableInterruptLevelVME) (level); +} + /* * devConnectInterrupt () * diff --git a/src/libCom/osi/os/RTEMS/devLibOSD.c b/src/libCom/osi/os/RTEMS/devLibOSD.c index 633736d24..5f8ceb9ad 100644 --- a/src/libCom/osi/os/RTEMS/devLibOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibOSD.c @@ -87,6 +87,20 @@ long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue */ long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); +static long rtmsDevConnectInterruptVME ( + unsigned vectorNumber, + void (*pFunction)(), + void *parameter); + +static long rtmsDevDisconnectInterruptVME ( + unsigned vectorNumber, + void (*pFunction)() +); + +static long rtmsDevEnableInterruptLevelVME (unsigned level); + +static long rtmsDevDisableInterruptLevelVME (unsigned level); + /* RTEMS specific init */ /*devA24Malloc and devA24Free are not implemented*/ @@ -99,8 +113,8 @@ static long rtmsDevInit(void); */ static devLibVirtualOS rtemsVirtualOS = { rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe, - devConnectInterruptVME, devDisconnectInterruptVME, - devEnableInterruptLevelVME, devDisableInterruptLevelVME, + rtmsDevConnectInterruptVME, rtmsDevDisconnectInterruptVME, + rtmsDevEnableInterruptLevelVME, rtmsDevDisableInterruptLevelVME, devA24Malloc,devA24Free,rtmsDevInit }; devLibVirtualOS *pdevLibVirtualOS = &rtemsVirtualOS; @@ -119,7 +133,7 @@ rtmsDevInit(void) * * wrapper to minimize driver dependency on OS */ -long devConnectInterruptVME ( +static long rtmsDevConnectInterruptVME ( unsigned vectorNumber, void (*pFunction)(), void *parameter) @@ -152,7 +166,7 @@ long devConnectInterruptVME ( * an interrupt handler that was installed by another driver * */ -long devDisconnectInterruptVME ( +static long rtmsDevDisconnectInterruptVME ( unsigned vectorNumber, void (*pFunction)() ) @@ -188,7 +202,7 @@ long devDisconnectInterruptVME ( /* * enable VME interrupt level */ -long devEnableInterruptLevelVME (unsigned level) +static long rtmsDevEnableInterruptLevelVME (unsigned level) { return BSP_enableVME_int_lvl(level); } @@ -196,7 +210,7 @@ long devEnableInterruptLevelVME (unsigned level) /* * disable VME interrupt level */ -long devDisableInterruptLevelVME (unsigned level) +static long rtmsDevDisableInterruptLevelVME (unsigned level) { return BSP_disableVME_int_lvl(level); } diff --git a/src/libCom/osi/os/vxWorks/devLibOSD.c b/src/libCom/osi/os/vxWorks/devLibOSD.c index 871045fb6..28a32c660 100644 --- a/src/libCom/osi/os/vxWorks/devLibOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibOSD.c @@ -114,13 +114,27 @@ 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); + /* * used by dynamic bind in devLib.c */ static devLibVirtualOS vxVirtualOS = { vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, - devConnectInterruptVME, devDisconnectInterruptVME, - devEnableInterruptLevelVME, devDisableInterruptLevelVME, + vxDevConnectInterruptVME, vxDevDisconnectInterruptVME, + vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME, devA24Malloc,devA24Free,devInit }; devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS; @@ -130,7 +144,7 @@ devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS; * * wrapper to minimize driver dependency on vxWorks */ -long devConnectInterruptVME ( +static long vxDevConnectInterruptVME ( unsigned vectorNumber, void (*pFunction)(), void *parameter) @@ -154,7 +168,7 @@ long devConnectInterruptVME ( /* * - * devDisconnectInterruptVME() + * vxDevDisconnectInterruptVME() * * wrapper to minimize driver dependency on vxWorks * @@ -163,7 +177,7 @@ long devConnectInterruptVME ( * an interrupt handler that was installed by another driver * */ -long devDisconnectInterruptVME ( +static long vxDevDisconnectInterruptVME ( unsigned vectorNumber, void (*pFunction)() ) @@ -198,7 +212,7 @@ long devDisconnectInterruptVME ( /* * enable VME interrupt level */ -long devEnableInterruptLevelVME (unsigned level) +static long vxDevEnableInterruptLevelVME (unsigned level) { # if CPU_FAMILY != I80X86 int s; @@ -250,7 +264,7 @@ long devDisableInterruptLevelISA (unsigned level) /* * disable VME interrupt level */ -long devDisableInterruptLevelVME (unsigned level) +static long vxDevDisableInterruptLevelVME (unsigned level) { # if CPU_FAMILY != I80X86 int s; From acb905fcfcd8c63e0d04061b25087f371327d662 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:43 +0100 Subject: [PATCH 04/36] [PATCH 02/12] add devInterruptInUseVME to function table Add test for interrupt handler function to the virtual os table. Adds a stub implementation to devLib.c Renames OS implementations functions for RTEMS and vxWorks to avoid symbol name conflicts --- src/libCom/osi/devLib.c | 14 ++++++++++++++ src/libCom/osi/devLib.h | 5 +++++ src/libCom/osi/os/RTEMS/devLibOSD.c | 6 ++++-- src/libCom/osi/os/vxWorks/devLibOSD.c | 6 ++++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/libCom/osi/devLib.c b/src/libCom/osi/devLib.c index 6e2f44bbd..6a8aa68e6 100644 --- a/src/libCom/osi/devLib.c +++ b/src/libCom/osi/devLib.c @@ -941,6 +941,20 @@ void (*pFunction)(void *) ) return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber, pFunction); } +int devInterruptInUseVME (unsigned level) +{ + long status; + + if (!devLibInitFlag) { + status = devLibInit(); + if (status) { + return status; + } + } + + return (*pdevLibVirtualOS->pDevInterruptInUseVME) (level); +} + long devEnableInterruptLevelVME (unsigned level) { long status; diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h index f9dd85751..2cd2471e8 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLib.h @@ -330,6 +330,11 @@ typedef struct devLibVirtualOS { void *(*pDevA24Malloc)(size_t nbytes); void (*pDevA24Free)(void *pBlock); long (*pDevInit)(void); + + /* + * test if VME interrupt has an ISR connected + */ + int (*pDevInterruptInUseVME) (unsigned vectorNumber); }devLibVirtualOS; epicsShareExtern devLibVirtualOS *pdevLibVirtualOS; diff --git a/src/libCom/osi/os/RTEMS/devLibOSD.c b/src/libCom/osi/os/RTEMS/devLibOSD.c index 5f8ceb9ad..50f1ffe36 100644 --- a/src/libCom/osi/os/RTEMS/devLibOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibOSD.c @@ -101,6 +101,8 @@ static long rtmsDevEnableInterruptLevelVME (unsigned level); static long rtmsDevDisableInterruptLevelVME (unsigned level); +static int rtemsDevInterruptInUseVME (unsigned vectorNumber); + /* RTEMS specific init */ /*devA24Malloc and devA24Free are not implemented*/ @@ -115,7 +117,7 @@ static devLibVirtualOS rtemsVirtualOS = { rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe, rtmsDevConnectInterruptVME, rtmsDevDisconnectInterruptVME, rtmsDevEnableInterruptLevelVME, rtmsDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,rtmsDevInit + devA24Malloc,devA24Free,rtmsDevInit,rtemsDevInterruptInUseVME }; devLibVirtualOS *pdevLibVirtualOS = &rtemsVirtualOS; @@ -296,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; diff --git a/src/libCom/osi/os/vxWorks/devLibOSD.c b/src/libCom/osi/os/vxWorks/devLibOSD.c index 28a32c660..ca95b3b60 100644 --- a/src/libCom/osi/os/vxWorks/devLibOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibOSD.c @@ -128,6 +128,8 @@ static long vxDevEnableInterruptLevelVME (unsigned level); static long vxDevDisableInterruptLevelVME (unsigned level); +static int vxDevInterruptInUseVME (unsigned vectorNumber); + /* * used by dynamic bind in devLib.c */ @@ -135,7 +137,7 @@ static devLibVirtualOS vxVirtualOS = { vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, vxDevConnectInterruptVME, vxDevDisconnectInterruptVME, vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,devInit + devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME }; devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS; @@ -373,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; From ad8cd28f7d3a18b4f4428e6180d1addc1d080c48 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:43 +0100 Subject: [PATCH 05/36] [PATCH 03/12] mark all implimentation functions as static --- src/libCom/osi/os/RTEMS/devLibOSD.c | 12 ++++++------ src/libCom/osi/os/vxWorks/devLibOSD.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libCom/osi/os/RTEMS/devLibOSD.c b/src/libCom/osi/os/RTEMS/devLibOSD.c index 50f1ffe36..d3c4b9287 100644 --- a/src/libCom/osi/os/RTEMS/devLibOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibOSD.c @@ -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, @@ -79,13 +79,13 @@ static long rtmsDevMapAddr (epicsAddressType addrType, unsigned options, * 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 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 rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); static long rtmsDevConnectInterruptVME ( unsigned vectorNumber, @@ -250,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 rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) { long status; @@ -269,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 rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) { long status; @@ -335,7 +335,7 @@ static int rtemsDevInterruptInUseVME (unsigned vectorNumber) * macro to declare handler prototypes... * */ -void unsolicitedHandlerEPICS(int vectorNumber) +static void unsolicitedHandlerEPICS(int vectorNumber) { /* * call epicInterruptContextMessage() diff --git a/src/libCom/osi/os/vxWorks/devLibOSD.c b/src/libCom/osi/os/vxWorks/devLibOSD.c index ca95b3b60..ebce458ea 100644 --- a/src/libCom/osi/os/vxWorks/devLibOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibOSD.c @@ -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 @@ -413,7 +413,7 @@ static int vxDevInterruptInUseVME (unsigned vectorNumber) * disconnected vector * */ -void unsolicitedHandlerEPICS(int vectorNumber) +static void unsolicitedHandlerEPICS(int vectorNumber) { /* * call logMsg() and not errMessage() From 83adda7e6c66abaa175e3db54dc7f46d6392facf Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:44 +0100 Subject: [PATCH 06/36] [PATCH 04/12] move "virtual os" definition to a seperate file The virtual os table is not something ordinary devLib users should know or care about. --- src/libCom/Makefile | 1 + src/libCom/osi/devLib.c | 3 ++ src/libCom/osi/devLib.h | 73 ++++++------------------- src/libCom/osi/devLibVMEImpl.h | 97 ++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 58 deletions(-) create mode 100644 src/libCom/osi/devLibVMEImpl.h diff --git a/src/libCom/Makefile b/src/libCom/Makefile index 3d251f35c..01e517080 100644 --- a/src/libCom/Makefile +++ b/src/libCom/Makefile @@ -192,6 +192,7 @@ INC += epicsStdioRedirect.h INC += epicsGetopt.h INC += devLib.h +INC += devLibImpl.h INC += osdVME.h SRCS += epicsThread.cpp diff --git a/src/libCom/osi/devLib.c b/src/libCom/osi/devLib.c index 6a8aa68e6..f56c63968 100644 --- a/src/libCom/osi/devLib.c +++ b/src/libCom/osi/devLib.c @@ -29,7 +29,10 @@ static const char sccsID[] = "@(#) $Id$"; #include "epicsMutex.h" #include "errlog.h" #include "ellLib.h" + +#define NO_DEVLIB_COMPAT #include "devLib.h" +#include "devLibImpl.h" static ELLLIST addrAlloc[atLast]; static ELLLIST addrFree[atLast]; diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h index 2cd2471e8..d0f444fc3 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLib.h @@ -46,6 +46,21 @@ typedef enum { */ extern const char *epicsAddressTypeName[]; +#ifdef __cplusplus +} +#endif + +/* + * To retain compatibility include everything by default + */ +#ifndef NO_DEVLIB_COMPAT +# include "devLibImpl.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + epicsShareFunc long devAddressMap(void); /* print an address map */ /* @@ -280,64 +295,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); - - /* - * test if VME interrupt has an ISR connected - */ - int (*pDevInterruptInUseVME) (unsigned vectorNumber); -}devLibVirtualOS; -epicsShareExtern devLibVirtualOS *pdevLibVirtualOS; - /* * error codes (and messages) associated with devLib.c */ diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h new file mode 100644 index 000000000..775bc3b42 --- /dev/null +++ b/src/libCom/osi/devLibVMEImpl.h @@ -0,0 +1,97 @@ +/*************************************************************************\ +* 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 pdevLibVirtualOS 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 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); + + /* + * test if VME interrupt has an ISR connected + */ + int (*pDevInterruptInUseVME) (unsigned vectorNumber); +}devLibVirtualOS; + +epicsShareExtern devLibVirtualOS *pdevLibVirtualOS; + +#ifdef __cplusplus +} +#endif + +#endif /* INCdevLibImplh */ From e21cde013dfcc1caea7c797f3b076d417056a09b Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:45 +0100 Subject: [PATCH 07/36] [PATCH 05/12] reorganize devLib.h Group functions by bus type with general functions at the top add macro to exclude deprecated api --- src/libCom/osi/devLib.h | 166 +++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 63 deletions(-) diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h index d0f444fc3..d37d20deb 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLib.h @@ -61,6 +61,12 @@ extern const char *epicsAddressTypeName[]; extern "C" { #endif +/* + * General API + * + * This section applies to all bus types + */ + epicsShareFunc long devAddressMap(void); /* print an address map */ /* @@ -128,6 +134,12 @@ epicsShareFunc long devAllocAddress( 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 */ @@ -136,28 +148,6 @@ epicsShareFunc long devConnectInterruptVME( 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 * @@ -169,6 +159,47 @@ 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) @@ -182,6 +213,43 @@ 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); + + +/* + * PCI API + * + * Functions in this section apply only to the ISA bus type + */ + +/* + * 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 PCI interrupt * (not implemented) @@ -197,21 +265,6 @@ epicsShareFunc long devDisconnectInterruptPCI( 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) @@ -221,17 +274,6 @@ epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel); 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 @@ -239,29 +281,16 @@ epicsShareFunc long devEnableInterruptLevelISA (unsigned level); 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. - * + * Support macros */ -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 @@ -336,6 +365,15 @@ epicsShareFunc void devLibA24Free(void *pBlock); #define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/ #define S_dev_vxWorksIntEnFail S_dev_intEnFail + +/* + * 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. @@ -394,6 +432,8 @@ epicsShareFunc long devDisableInterruptLevel ( */ epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation); +#endif /* NO_DEVLIB_OLD_INTERFACE */ + /* * Some vxWorks convenience routines */ From 46ec38756bb42c2cfe3bd2b6e4170d37063f2a3f Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:46 +0100 Subject: [PATCH 08/36] [PATCH 06/12] use epics extern macro --- src/libCom/osi/devLib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h index d37d20deb..47a71eac3 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLib.h @@ -44,7 +44,7 @@ typedef enum { * pointer to an array of strings for each of * the above address types */ -extern const char *epicsAddressTypeName[]; +epicsShareExtern const char *epicsAddressTypeName[]; #ifdef __cplusplus } From 4a3b4358c3f2d01d0414b8487075fa6a30c6f30b Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:49 +0100 Subject: [PATCH 09/36] [PATCH 07/12] rename devLib to devLibVME --- src/libCom/Makefile | 7 ++++--- src/libCom/osi/{devLib.c => devLibVME.c} | 4 ++-- src/libCom/osi/{devLib.h => devLibVME.h} | 2 +- src/libCom/osi/os/RTEMS/{devLibOSD.c => devLibVMEOSD.c} | 2 +- src/libCom/osi/os/cygwin32/{devLibOSD.c => devLibVMEOSD.c} | 2 +- src/libCom/osi/os/default/{devLibOSD.c => devLibVMEOSD.c} | 2 +- src/libCom/osi/os/vxWorks/{devLibOSD.c => devLibVMEOSD.c} | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) rename src/libCom/osi/{devLib.c => devLibVME.c} (99%) rename src/libCom/osi/{devLib.h => devLibVME.h} (99%) rename src/libCom/osi/os/RTEMS/{devLibOSD.c => devLibVMEOSD.c} (99%) rename src/libCom/osi/os/cygwin32/{devLibOSD.c => devLibVMEOSD.c} (90%) rename src/libCom/osi/os/default/{devLibOSD.c => devLibVMEOSD.c} (90%) rename src/libCom/osi/os/vxWorks/{devLibOSD.c => devLibVMEOSD.c} (99%) diff --git a/src/libCom/Makefile b/src/libCom/Makefile index 01e517080..7f0168fb0 100644 --- a/src/libCom/Makefile +++ b/src/libCom/Makefile @@ -192,7 +192,8 @@ INC += epicsStdioRedirect.h INC += epicsGetopt.h INC += devLib.h -INC += devLibImpl.h +INC += devLibVME.h +INC += devLibVMEImpl.h INC += osdVME.h SRCS += epicsThread.cpp @@ -231,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 diff --git a/src/libCom/osi/devLib.c b/src/libCom/osi/devLibVME.c similarity index 99% rename from src/libCom/osi/devLib.c rename to src/libCom/osi/devLibVME.c index f56c63968..5a4965380 100644 --- a/src/libCom/osi/devLib.c +++ b/src/libCom/osi/devLibVME.c @@ -7,7 +7,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ /* devLib.c - support for allocation of common device resources */ -/* $Id$ */ +/* devLib.c,v 1.1.2.11 2009/07/09 16:37:23 anj Exp */ /* * Original Author: Marty Kraimer @@ -18,7 +18,7 @@ * .01 06-14-93 joh needs devAllocInterruptVector() routine */ -static const char sccsID[] = "@(#) $Id$"; +static const char sccsID[] = "@(#) devLib.c,v 1.1.2.11 2009/07/09 16:37:23 anj Exp"; #include #include diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLibVME.h similarity index 99% rename from src/libCom/osi/devLib.h rename to src/libCom/osi/devLibVME.h index 47a71eac3..85347f81f 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLibVME.h @@ -7,7 +7,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ /* devLib.h */ -/* $Id$ */ +/* devLib.h,v 1.1.2.8 2009/07/09 15:27:43 anj Exp */ /* * Original Author: Marty Kraimer diff --git a/src/libCom/osi/os/RTEMS/devLibOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c similarity index 99% rename from src/libCom/osi/os/RTEMS/devLibOSD.c rename to src/libCom/osi/os/RTEMS/devLibVMEOSD.c index d3c4b9287..2abb3de38 100644 --- a/src/libCom/osi/os/RTEMS/devLibOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c @@ -6,7 +6,7 @@ * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* $Id$ */ +/* devLibOSD.c,v 1.1.2.8 2009/07/09 16:37:23 anj Exp */ /* RTEMS port by Till Straumann, * 3/2002 diff --git a/src/libCom/osi/os/cygwin32/devLibOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c similarity index 90% rename from src/libCom/osi/os/cygwin32/devLibOSD.c rename to src/libCom/osi/os/cygwin32/devLibVMEOSD.c index ac2dda63e..90844de61 100644 --- a/src/libCom/osi/os/cygwin32/devLibOSD.c +++ b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c @@ -5,7 +5,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* $Id$ */ +/* devLibOSD.c,v 1.1.2.1 2009/06/15 16:10:05 anj Exp */ #include diff --git a/src/libCom/osi/os/default/devLibOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c similarity index 90% rename from src/libCom/osi/os/default/devLibOSD.c rename to src/libCom/osi/os/default/devLibVMEOSD.c index bcb24e179..064f1e7d6 100644 --- a/src/libCom/osi/os/default/devLibOSD.c +++ b/src/libCom/osi/os/default/devLibVMEOSD.c @@ -6,7 +6,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* $Id$ */ +/* devLibOSD.c,v 1.1.2.1 2006/02/17 22:51:24 anj Exp */ #include diff --git a/src/libCom/osi/os/vxWorks/devLibOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c similarity index 99% rename from src/libCom/osi/os/vxWorks/devLibOSD.c rename to src/libCom/osi/os/vxWorks/devLibVMEOSD.c index ebce458ea..6bf6fbd66 100644 --- a/src/libCom/osi/os/vxWorks/devLibOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c @@ -7,7 +7,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ /* - * $Id$ + * devLibOSD.c,v 1.1.2.9 2009/07/09 16:37:23 anj Exp * * Archictecture dependent support for common device driver resources * From 000c98dbaad769971f8874ff977e6462a7bb3bf7 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:50 +0100 Subject: [PATCH 10/36] [PATCH 08/12] fix includes --- src/libCom/osi/devLibVME.c | 4 ++-- src/libCom/osi/devLibVME.h | 3 ++- src/libCom/osi/os/RTEMS/devLibVMEOSD.c | 2 +- src/libCom/osi/os/cygwin32/devLibVMEOSD.c | 2 +- src/libCom/osi/os/default/devLibVMEOSD.c | 2 +- src/libCom/osi/os/vxWorks/devLibVMEOSD.c | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libCom/osi/devLibVME.c b/src/libCom/osi/devLibVME.c index 5a4965380..53f55dd99 100644 --- a/src/libCom/osi/devLibVME.c +++ b/src/libCom/osi/devLibVME.c @@ -31,8 +31,8 @@ static const char sccsID[] = "@(#) devLib.c,v 1.1.2.11 2009/07/09 16:37:23 anj E #include "ellLib.h" #define NO_DEVLIB_COMPAT -#include "devLib.h" -#include "devLibImpl.h" +#include "devLibVME.h" +#include "devLibVMEImpl.h" static ELLLIST addrAlloc[atLast]; static ELLLIST addrFree[atLast]; diff --git a/src/libCom/osi/devLibVME.h b/src/libCom/osi/devLibVME.h index 85347f81f..847949d07 100644 --- a/src/libCom/osi/devLibVME.h +++ b/src/libCom/osi/devLibVME.h @@ -22,6 +22,7 @@ #include "osdVME.h" #include "errMdef.h" #include "shareLib.h" +#include "devLib.h" #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ epicsShareExtern const char *epicsAddressTypeName[]; * To retain compatibility include everything by default */ #ifndef NO_DEVLIB_COMPAT -# include "devLibImpl.h" +# include "devLibVMEImpl.h" #endif #ifdef __cplusplus diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c index 2abb3de38..20b81bc3a 100644 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c @@ -17,7 +17,7 @@ #include #include #include -#include "devLib.h" +#include "devLibVME.h" #include #if defined(__PPC__) || defined(__mcf528x__) diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c index 90844de61..9192eac8b 100644 --- a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c +++ b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c @@ -10,6 +10,6 @@ #include #define epicsExportSharedSymbols -#include "devLib.h" +#include "devLibVME.h" epicsShareDef devLibVirtualOS *pdevLibVirtualOS = NULL; diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c index 064f1e7d6..e373325a8 100644 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ b/src/libCom/osi/os/default/devLibVMEOSD.c @@ -10,7 +10,7 @@ #include -#include "devLib.h" +#include "devLibVME.h" /* This file must contain no definitions other than the following: */ diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c index 6bf6fbd66..7ce0ce663 100644 --- a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c @@ -28,7 +28,7 @@ #include #include "epicsFindSymbol.h" -#include "devLib.h" +#include "devLibVME.h" #include "errlog.h" typedef void myISR (void *pParam); From 50bcef9c634bf7fe6cd68875afc8ad0a08871372 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:50 +0100 Subject: [PATCH 11/36] [PATCH 09/12] rename vme pointer table --- src/libCom/osi/devLibVME.c | 40 +++++++++++------------ src/libCom/osi/devLibVMEImpl.h | 8 ++--- src/libCom/osi/os/RTEMS/devLibVMEOSD.c | 4 +-- src/libCom/osi/os/cygwin32/devLibVMEOSD.c | 2 +- src/libCom/osi/os/default/devLibVMEOSD.c | 2 +- src/libCom/osi/os/vxWorks/devLibVMEOSD.c | 4 +-- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/libCom/osi/devLibVME.c b/src/libCom/osi/devLibVME.c index 53f55dd99..7d5c9981a 100644 --- a/src/libCom/osi/devLibVME.c +++ b/src/libCom/osi/devLibVME.c @@ -170,7 +170,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); @@ -278,7 +278,7 @@ long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) } } - return (*pdevLibVirtualOS->pDevReadProbe) (wordSize, ptr, pValue); + return (*pdevLibVME->pDevReadProbe) (wordSize, ptr, pValue); } /* @@ -298,7 +298,7 @@ long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) } } - return (*pdevLibVirtualOS->pDevWriteProbe) (wordSize, ptr, pValue); + return (*pdevLibVME->pDevWriteProbe) (wordSize, ptr, pValue); } /* @@ -335,7 +335,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", @@ -700,8 +700,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; } @@ -730,7 +730,7 @@ static long devLibInit (void) } epicsMutexUnlock(addrListLock); devLibInitFlag = TRUE; - return pdevLibVirtualOS->pDevInit(); + return pdevLibVME->pDevInit(); } /* @@ -892,7 +892,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; } @@ -900,7 +900,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; } @@ -924,7 +924,7 @@ void *parameter ) } } - return (*pdevLibVirtualOS->pDevConnectInterruptVME) (vectorNumber, + return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, pFunction, parameter); } @@ -941,7 +941,7 @@ void (*pFunction)(void *) ) } } - return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber, pFunction); + return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction); } int devInterruptInUseVME (unsigned level) @@ -955,7 +955,7 @@ int devInterruptInUseVME (unsigned level) } } - return (*pdevLibVirtualOS->pDevInterruptInUseVME) (level); + return (*pdevLibVME->pDevInterruptInUseVME) (level); } long devEnableInterruptLevelVME (unsigned level) @@ -969,7 +969,7 @@ long devEnableInterruptLevelVME (unsigned level) } } - return (*pdevLibVirtualOS->pDevEnableInterruptLevelVME) (level); + return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); } long devDisableInterruptLevelVME (unsigned level) @@ -983,7 +983,7 @@ long devDisableInterruptLevelVME (unsigned level) } } - return (*pdevLibVirtualOS->pDevDisableInterruptLevelVME) (level); + return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); } /* @@ -1009,7 +1009,7 @@ void *parameter) switch(intType){ case intVME: case intVXI: - return (*pdevLibVirtualOS->pDevConnectInterruptVME) (vectorNumber, + return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, pFunction, parameter); default: return S_dev_uknIntType; @@ -1040,7 +1040,7 @@ void (*pFunction)(void *) switch(intType){ case intVME: case intVXI: - return (*pdevLibVirtualOS->pDevDisconnectInterruptVME) (vectorNumber, + return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction); default: return S_dev_uknIntType; @@ -1068,7 +1068,7 @@ unsigned level) switch(intType){ case intVME: case intVXI: - return (*pdevLibVirtualOS->pDevEnableInterruptLevelVME) (level); + return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); default: return S_dev_uknIntType; } @@ -1095,7 +1095,7 @@ unsigned level) switch(intType){ case intVME: case intVXI: - return (*pdevLibVirtualOS->pDevDisableInterruptLevelVME) (level); + return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); default: return S_dev_uknIntType; } @@ -1144,7 +1144,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); } @@ -1153,5 +1153,5 @@ void devLibA24Free(void *pBlock) if (devLibA24Debug) epicsPrintf("devLibA24Free(%p) entered\n", pBlock); - pdevLibVirtualOS->pDevA24Free(pBlock); + pdevLibVME->pDevA24Free(pBlock); } diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h index 775bc3b42..b75aa1ba9 100644 --- a/src/libCom/osi/devLibVMEImpl.h +++ b/src/libCom/osi/devLibVMEImpl.h @@ -29,12 +29,12 @@ extern "C" { /* * virtual OS layer for devLib.c * - * The global virtual OS table pdevLibVirtualOS controls + * 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 devLibVirtualOS { +typedef struct devLibVME { /* * maps logical address to physical address, but does not detect * two device drivers that are using the same address range @@ -86,9 +86,9 @@ typedef struct devLibVirtualOS { * test if VME interrupt has an ISR connected */ int (*pDevInterruptInUseVME) (unsigned vectorNumber); -}devLibVirtualOS; +}devLibVME; -epicsShareExtern devLibVirtualOS *pdevLibVirtualOS; +epicsShareExtern devLibVME *pdevLibVME; #ifdef __cplusplus } diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c index 20b81bc3a..44ebb3adf 100644 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c @@ -113,13 +113,13 @@ static long rtmsDevInit(void); /* * used by bind in devLib.c */ -static devLibVirtualOS rtemsVirtualOS = { +static devLibVME rtemsVirtualOS = { rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe, rtmsDevConnectInterruptVME, rtmsDevDisconnectInterruptVME, rtmsDevEnableInterruptLevelVME, rtmsDevDisableInterruptLevelVME, devA24Malloc,devA24Free,rtmsDevInit,rtemsDevInterruptInUseVME }; -devLibVirtualOS *pdevLibVirtualOS = &rtemsVirtualOS; +devLibVME *pdevLibVME = &rtemsVirtualOS; /* RTEMS specific initialization */ static long diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c index 9192eac8b..3058292a5 100644 --- a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c +++ b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c @@ -12,4 +12,4 @@ #define epicsExportSharedSymbols #include "devLibVME.h" -epicsShareDef devLibVirtualOS *pdevLibVirtualOS = NULL; +epicsShareDef devLibVME *pdevLibVME = NULL; diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c index e373325a8..0ae3e56cf 100644 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ b/src/libCom/osi/os/default/devLibVMEOSD.c @@ -14,4 +14,4 @@ /* This file must contain no definitions other than the following: */ -devLibVirtualOS *pdevLibVirtualOS; +devLibVME *pdevLibVME; diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c index 7ce0ce663..525678419 100644 --- a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c @@ -133,13 +133,13 @@ static int vxDevInterruptInUseVME (unsigned vectorNumber); /* * used by dynamic bind in devLib.c */ -static devLibVirtualOS vxVirtualOS = { +static devLibVME vxVirtualOS = { vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, vxDevConnectInterruptVME, vxDevDisconnectInterruptVME, vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME, devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME }; -devLibVirtualOS *pdevLibVirtualOS = &vxVirtualOS; +devLibVME *pdevLibVME = &vxVirtualOS; /* * devConnectInterruptVME From c1142675b68963d2e07ea941277d743a733e515e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:51 +0100 Subject: [PATCH 12/36] [PATCH 10/12] move general macros and error codes to devLib.h includes devLibVME.h for compatibility --- src/libCom/osi/devLib.h | 90 ++++++++++++++++++++++++++++++++++++++ src/libCom/osi/devLibVME.h | 78 --------------------------------- 2 files changed, 90 insertions(+), 78 deletions(-) create mode 100644 src/libCom/osi/devLib.h diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h new file mode 100644 index 000000000..12e583e45 --- /dev/null +++ b/src/libCom/osi/devLib.h @@ -0,0 +1,90 @@ + +#ifndef EPICSDEVLIB_H +#define EPICSDEVLIB_H + +/* + * Support macros + */ + +/* + * Normalize a digital value and convert it to type TYPE + * + * Ex: + * float f; + * int d; + * f = devNormalizeDigital(d,12) + * + */ +#define devCreateMask(NBITS) ((1<<(NBITS))-1) +#define devDigToNml(DIGITAL,NBITS) \ + (((double)(DIGITAL))/devCreateMask(NBITS)) +#define devNmlToDig(NORMAL,NBITS) \ + (((long)(NORMAL)) * devCreateMask(NBITS)) + +/* + * + * Alignment mask + * (for use when testing to see if the proper number of least + * significant bits are zero) + * + */ +#define devCreateAlignmentMask(CTYPE)\ +(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1) + +/* + * pointer aligned test + * (returns true if the pointer is on the worst case alignemnt + * boundary for its type) + */ +#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR))) + +/* + * error codes (and messages) associated with devLib.c + */ +#define S_dev_success 0 +#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/ +#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/ +#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/ +#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/ +#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/ +#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/ +#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/ +#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/ +#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/ +#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/ +#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/ +#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/ +#define S_dev_internal (M_devLib| 13) /*Internal failure*/ +#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/ +#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/ +#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/ +#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/ +#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/ +#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/ +#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/ +#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/ +#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/ +#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/ +#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/ +#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/ +#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/ +#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/ +#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/ +#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/ +#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/ +#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/ +#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/ +#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/ +#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/ +#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/ +#define S_dev_vxWorksIntEnFail S_dev_intEnFail + + +#endif /* EPICSDEVLIB_H */ + +/* + * Retain compatibility by including VME by default + */ +#ifndef NO_DEVLIB_COMPAT +# include "devLibVME.h" +#endif diff --git a/src/libCom/osi/devLibVME.h b/src/libCom/osi/devLibVME.h index 847949d07..3644f5b7c 100644 --- a/src/libCom/osi/devLibVME.h +++ b/src/libCom/osi/devLibVME.h @@ -289,84 +289,6 @@ epicsShareFunc long devDisableInterruptLevelPCI (unsigned level, unsigned bus, unsigned device, unsigned function); -/* - * Support macros - */ - -/* - * Normalize a digital value and convert it to type TYPE - * - * Ex: - * float f; - * int d; - * f = devNormalizeDigital(d,12) - * - */ -#define devCreateMask(NBITS) ((1<<(NBITS))-1) -#define devDigToNml(DIGITAL,NBITS) \ - (((double)(DIGITAL))/devCreateMask(NBITS)) -#define devNmlToDig(NORMAL,NBITS) \ - (((long)(NORMAL)) * devCreateMask(NBITS)) - -/* - * - * Alignment mask - * (for use when testing to see if the proper number of least - * significant bits are zero) - * - */ -#define devCreateAlignmentMask(CTYPE)\ -(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1) - -/* - * pointer aligned test - * (returns true if the pointer is on the worst case alignemnt - * boundary for its type) - */ -#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR))) - -/* - * error codes (and messages) associated with devLib.c - */ -#define S_dev_success 0 -#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/ -#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/ -#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/ -#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/ -#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/ -#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/ -#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/ -#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/ -#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/ -#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/ -#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/ -#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/ -#define S_dev_internal (M_devLib| 13) /*Internal failure*/ -#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/ -#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/ -#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/ -#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/ -#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/ -#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/ -#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/ -#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/ -#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/ -#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/ -#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/ -#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/ -#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/ -#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/ -#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/ -#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/ -#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/ -#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/ -#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/ -#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/ -#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/ -#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/ -#define S_dev_vxWorksIntEnFail S_dev_intEnFail - - /* * Deprecated interface */ From a161e42e828da756f424d29d8f153433d643bd16 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:52 +0100 Subject: [PATCH 13/36] [PATCH 11/12] remove unimplimented PCI api --- src/libCom/osi/devLibVME.h | 57 -------------------------------------- 1 file changed, 57 deletions(-) diff --git a/src/libCom/osi/devLibVME.h b/src/libCom/osi/devLibVME.h index 3644f5b7c..6d7476098 100644 --- a/src/libCom/osi/devLibVME.h +++ b/src/libCom/osi/devLibVME.h @@ -232,63 +232,6 @@ epicsShareFunc long devEnableInterruptLevelISA (unsigned level); */ epicsShareFunc long devDisableInterruptLevelISA (unsigned level); - -/* - * PCI API - * - * Functions in this section apply only to the ISA bus type - */ - -/* - * 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 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 PCI interrupt is in use - * (not implemented) - * - * returns boolean - */ -epicsShareFunc int devInterruptInUsePCI (unsigned bus, unsigned device, - unsigned function); - - -/* - * not implemented - API needs to be reviewed - */ -epicsShareFunc long devEnableInterruptLevelPCI (unsigned level, - unsigned bus, unsigned device, unsigned function); - -/* - * not implemented - API needs to be reviewed - */ -epicsShareFunc long devDisableInterruptLevelPCI (unsigned level, - unsigned bus, unsigned device, unsigned function); - - /* * Deprecated interface */ From 43f5cfed7ef9a3a8d0d5777af1f4aa8166db03a4 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 25 May 2010 13:58:53 +0100 Subject: [PATCH 14/36] [PATCH 12/12] add entry to release notes --- documentation/RELEASE_NOTES.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9b3ce378e..dfc825d68 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -12,6 +12,19 @@

Changes between 3.14.11 and 3.14.12

+

devLib cleanup

+ +
    +
  • Add VME connect/disconnect IRQ calls to the "virtual os" table
  • +
  • It is now possible to compile all devLib code on targets without runtime support
  • +
  • All internal functions are made static. Some were not before.
  • +
  • Move VME calls to devLibVME.h. devLib.h contains general defintions and error codes.
  • +
  • For compatibility devLib.h includes devLibVME.h unless the macro NO_DEVLIB_COMPAT is defined.
  • +
  • The "virtual os" table is renamed from pdevLibVirtualOS to pdevLibVME to reflect the fact +that other bus types would use seperate tables.
  • +
  • The "virtual os" table API has been moved to a seperate header devLibVMEImpl.h.
  • +
+

Rewrite epicsThreadOnce()

Michael Davidsaver suggested a better implementation of epicsThreadOnce() From 797d263f0469fcfbd560ba1f492651cbd63de9ed Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 21:00:43 +0100 Subject: [PATCH 15/36] Comment removed --- src/cap5/capr.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 672fd509d..5c999eda3 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -234,7 +234,6 @@ sub getFieldParams { $fType = $fieldType{$record{$recType}{$field}[$tIdx]}; $fInterest = $record{$recType}{$field}[$iIdx]; $fBase = $record{$recType}{$field}[$bIdx]; - #print("getFieldParams: $recType, $field, $fType, $fInterest\n"); return($fType, $fInterest, $fBase); } From 408721daec68c69cf6e38b7ee4d4bb5b426424f7 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 21:44:38 +0100 Subject: [PATCH 16/36] Install capr.pl Parallel caget --- src/cap5/Makefile | 1 + src/cap5/capr.pl | 96 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/cap5/Makefile b/src/cap5/Makefile index ec2330607..05f3de1e3 100644 --- a/src/cap5/Makefile +++ b/src/cap5/Makefile @@ -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 diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 5c999eda3..8986cf1f4 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -31,7 +31,7 @@ if ( defined $ENV{"EPICS_HOST_ARCH"} ) { our( $opt_d, $opt_f, $opt_r); my $usage = "Usage:\n $0 [-d dbd_file] ( [-f record_type] | [-r] | [record_name] ) [interest]\n"; my %record = (); # Empty hash to put dbd data in -my $iIdx = 0; # Array indexes for interest, data type and base +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 @@ -58,6 +58,13 @@ my %fieldType = ( DBF_NOACCESS => "ezcaNoAccess" ); +# globals for parallel_caget +my %callback_data; +my $callback_incomplete; +# globals for caget +my $caget_data; +my $caget_incomplete; +my $cadebug = 0; ######### Main program ############ @@ -286,6 +293,49 @@ sub printField { return($col); } +# grab a list of pvs simultaneously +# The results are filled in the the %callback_data global hash +# and the result of the operation is the number of read pvs +# Usage: $read_pvs = parallel_caget( @pvlist ) +sub parallel_caget { + my @chans = map { CA->new($_); } @_; + my $wait = 1; + + eval { CA->pend_io($wait); }; + 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) { + $callback_data{$chan->name} = "" + unless $chan->is_connected; + } + @chans = grep { $_->is_connected } @chans; + } else { + die $@; + } + } + + map { + my $type; + $type = $_->field_type; + #$callback_data{$_->name} = undef; + $_->get_callback(\&caget_callback, $type); + } @chans; + + my $read_pvs = @chans; + $callback_incomplete = @chans; + CA->pend_event(0.1) while $callback_incomplete; + return $read_pvs; +} + +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. # Useage: printRecord( $recordName, $interestLevel) @@ -295,12 +345,16 @@ sub printRecord { my ($error, $recType, $field, $fType, $fInterest, $data); my ($fToGet, $col, $base); #print("checking record $name, interest $interest\n"); - $col = 0; $recType = getRecType($name); print("$name is record type $recType\n"); exists($record{$recType}) || die "Record type $recType not found in dbd file --"; - + + #capture list of fields to obtain + my @list = (); #fiels to read + my @fields_pr = (); #fields for print-out + my @ftypes = (); #types, from parser + my @bases = (); #bases, from parser foreach $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; } @@ -309,15 +363,25 @@ sub printRecord { unless( $fType eq "ezcaNoAccess" ) { if( $interest >= $fInterest ) { $fToGet = $name . "." . $field; - $data = caget($fToGet); - chomp $data; - #$data =~ s/\s+//; - #if( $data[0] ) { die "ca get error on field $field --" }; - $col = printField($field, $data, $fType, $base, $col); - #print ("fType = $fType $data[1]\n"); + push @fields_pr, $field; + push @list, $fToGet; + push @ftypes, $fType; + push @bases, $base; } } } + my $read_pvs; + $read_pvs = parallel_caget( @list ); + + $col = 0; + for (my $i=0; $i < scalar @list; $i++) { + $field = $fields_pr[$i]; + $fToGet = $list[$i]; + $data = $callback_data{$fToGet}; + $fType = $ftypes[$i]; + chomp $data; + $col = printField($field, $data, $fType, $base, $col); + } print("\n"); # Final line feed } @@ -361,10 +425,6 @@ sub printRecordList { } } -# variable to communicate callback handler result -my $callback_data; -my $incomplete; -my $cadebug = 0; # returns a terse result of a caget operation # using perlCA @@ -385,9 +445,9 @@ sub caget { my $type = $channel->field_type; my $count = $channel->element_count; $channel->get_callback(\&callback_handler, $type); - $incomplete = 1; - CA->pend_event(0.1) while ($incomplete); - return $callback_data; + $caget_incomplete = 1; + CA->pend_event(0.1) while ($caget_incomplete); + return $caget_data; } sub callback_handler @@ -395,8 +455,8 @@ sub callback_handler my ($chan, $status, $data) = @_; die $status if $status; #display($chan, $type, $data); - $callback_data = $data; - $incomplete=0; + $caget_data = $data; + $caget_incomplete=0; } sub show_call_stack { From 18a63f8754367d66adb62aeeeec3668196b93d60 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 22:20:18 +0100 Subject: [PATCH 17/36] re-organizing print out and diagnostics --- src/cap5/capr.pl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 8986cf1f4..d2a5f0e35 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -265,11 +265,10 @@ sub printField { $outStr = sprintf("%-5s %x", $field, $fieldData); } elsif ( $dataType eq "ezcaDouble" || $dataType eq "ezcaFloat" ) { $outStr = sprintf("%-5s %.8f", $field, $fieldData); - } elsif ( $dataType eq "ezcaShort" ) { - $outStr = sprintf("%-5s %d", $field, $fieldData); } elsif ( $dataType eq "ezcaChar" ) { $outStr = sprintf("%-5s %d", $field, ord($fieldData)); }else { + # ezcaByte, ezcaShort, ezcaLong $outStr = sprintf("%-5s %d", $field, $fieldData); } @@ -280,7 +279,6 @@ sub printField { else { $wide = 80;} $pad = $wide - $len; - #print "outStr=$outStr .. pad=$pad\n"; if( $col + $wide > $screenWidth ) { print("\n"); @@ -373,6 +371,18 @@ sub printRecord { my $read_pvs; $read_pvs = parallel_caget( @list ); + print "====-------------===="; + for (my $i=0; $i < scalar @list; $i++) { + $field = $fields_pr[$i]; + $fToGet = $list[$i]; + $data = $callback_data{$fToGet}; + $fType = $ftypes[$i]; + $base = $bases[$i]; + my $len = length $data; + chomp $data; + print "$field ($fType-$len): $data\n"; + } + print "-------------===="; $col = 0; for (my $i=0; $i < scalar @list; $i++) { $field = $fields_pr[$i]; From c6255ef0ac187d1fccdad4e1872447e2f6899080 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 22:23:22 +0100 Subject: [PATCH 18/36] removing diagnostics --- src/cap5/capr.pl | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index d2a5f0e35..41b929908 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -368,21 +368,8 @@ sub printRecord { } } } - my $read_pvs; - $read_pvs = parallel_caget( @list ); + my $read_pvs = parallel_caget( @list ); - print "====-------------===="; - for (my $i=0; $i < scalar @list; $i++) { - $field = $fields_pr[$i]; - $fToGet = $list[$i]; - $data = $callback_data{$fToGet}; - $fType = $ftypes[$i]; - $base = $bases[$i]; - my $len = length $data; - chomp $data; - print "$field ($fType-$len): $data\n"; - } - print "-------------===="; $col = 0; for (my $i=0; $i < scalar @list; $i++) { $field = $fields_pr[$i]; From 5dc869bbcc2361d3fa055b9269c9ed88ae0c9188 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 22:44:58 +0100 Subject: [PATCH 19/36] Require default dbd --- src/cap5/capr.pl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 41b929908..23cfab8e2 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -17,10 +17,6 @@ use CA; ######### Globals ########## -# Non APS users will want to modify theDbdFile default settings - -my $theDbdFile = "/net/helios/iocapps/R3.13.9/ioc/linac/2/dbd/linac.dbd"; - my $hostArch; if ( defined $ENV{"EPICS_HOST_ARCH"} ) { $hostArch = $ENV{"EPICS_HOST_ARCH"} ; @@ -30,6 +26,7 @@ if ( defined $ENV{"EPICS_HOST_ARCH"} ) { our( $opt_d, $opt_f, $opt_r); my $usage = "Usage:\n $0 [-d dbd_file] ( [-f record_type] | [-r] | [record_name] ) [interest]\n"; +my $theDbdFile; my %record = (); # Empty hash to put dbd data in my $iIdx = 0; # Array indexes for interest, data type and base my $tIdx = 1; @@ -77,6 +74,11 @@ if($opt_d) { # command line has highest priority elsif (exists $ENV{CAPR_DBD_FILE}) { # Use the env var if it exists $theDbdFile = $ENV{CAPR_DBD_FILE}; } # Otherwise use the default set above +else { + die "Error: no default dbd defined\n". + "Specify dbd with -d option or CAPR_DBD_FILE environment variable\n". + $usage; +} parseDbd($theDbdFile); print "Using $theDbdFile\n\n"; From 30a58e4d4cf6f3083c99fa5486c47c25fd9dd801 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 22:59:17 +0100 Subject: [PATCH 20/36] Default interest level, clean up Removing one-parameter caget. Interest level zero if not specified --- src/cap5/capr.pl | 63 ++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 23cfab8e2..10b2f3cec 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -55,12 +55,9 @@ my %fieldType = ( DBF_NOACCESS => "ezcaNoAccess" ); -# globals for parallel_caget +# globals for sub caget my %callback_data; my $callback_incomplete; -# globals for caget -my $caget_data; -my $caget_incomplete; my $cadebug = 0; ######### Main program ############ @@ -105,6 +102,7 @@ if($ARGV[0] =~ m/\s+\d/) { # If we replace comma with a space, } $ARGV[0] =~ s/\s+//; # Remove any spaces $ARGV[0] =~ s/\..*//; # Get rid of field name if it's there +$ARGV[1] = 0 unless defined $ARGV[1]; # default interest level is 0 $ARGV[1] =~ s/\D//g; # Make sure we only use digits $ARGV[1] = $ARGV[1] || 0; # interest defaults to 0 printRecord($ARGV[0], $ARGV[1]); # Do the do @@ -219,8 +217,10 @@ sub getRecType { my $type; my $data; - $data = caget($name); - if ($data =~ m/Invalid channel name/) { die "Record \"$_[0]\" not found\n"; } + my $read_pvs = caget( $name ); + + if ( $read_pvs != 1 ) { die "Record \"$_[0]\" not found\n"; } + $data = $callback_data{ $name }; chomp $data; $data =~ s/\s+//; #print("$name is a \"$data\"type\n"); @@ -293,14 +293,21 @@ sub printField { return($col); } -# grab a list of pvs simultaneously +# Query for a list of pvs simultaneously # The results are filled in the the %callback_data global hash # and the result of the operation is the number of read pvs -# Usage: $read_pvs = parallel_caget( @pvlist ) -sub parallel_caget { +# +# NOTE: Not re-entrant because results are written to global hash +# %callback_data +# +# Usage: $read_pvs = caget( @pvlist ) +sub caget { my @chans = map { CA->new($_); } @_; my $wait = 1; - + + #clear results; + %callback_data = (); + eval { CA->pend_io($wait); }; if ($@) { if ($@ =~ m/^ECA_TIMEOUT/) { @@ -370,7 +377,7 @@ sub printRecord { } } } - my $read_pvs = parallel_caget( @list ); + my $read_pvs = caget( @list ); $col = 0; for (my $i=0; $i < scalar @list; $i++) { @@ -424,40 +431,6 @@ sub printRecordList { } } - -# returns a terse result of a caget operation -# using perlCA -sub caget { - my $name = $_[0]; - print $name . "\n" if $cadebug; - show_call_stack() if $cadebug; - my $channel = CA->new($name); - my $wait = 1; - eval { CA->pend_io($wait); }; - if ($@) { - if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = "'" . $channel . "'"; - print "Channel connect timed out: $err not found.\n"; - } - die $@; - } - my $type = $channel->field_type; - my $count = $channel->element_count; - $channel->get_callback(\&callback_handler, $type); - $caget_incomplete = 1; - CA->pend_event(0.1) while ($caget_incomplete); - return $caget_data; -} - -sub callback_handler -{ - my ($chan, $status, $data) = @_; - die $status if $status; - #display($chan, $type, $data); - $caget_data = $data; - $caget_incomplete=0; -} - sub show_call_stack { my ( $path, $line, $subr ); my $max_depth = 30; From b45e6b818e54393806246e98b896f092e048e5b1 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Tue, 25 May 2010 23:13:47 +0100 Subject: [PATCH 21/36] renaming variables and cleaning-up --- src/cap5/capr.pl | 54 ++++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 10b2f3cec..aa2fc0dce 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -217,9 +217,9 @@ sub getRecType { my $type; my $data; - my $read_pvs = caget( $name ); - - if ( $read_pvs != 1 ) { die "Record \"$_[0]\" not found\n"; } + my $fields_read = caget( $name ); + + if ( $fields_read != 1 ) { die "Record \"$_[0]\" not found\n"; } $data = $callback_data{ $name }; chomp $data; $data =~ s/\s+//; @@ -267,10 +267,10 @@ sub printField { $outStr = sprintf("%-5s %x", $field, $fieldData); } elsif ( $dataType eq "ezcaDouble" || $dataType eq "ezcaFloat" ) { $outStr = sprintf("%-5s %.8f", $field, $fieldData); - } elsif ( $dataType eq "ezcaChar" ) { + } elsif ( $dataType eq "ezcaChar" ) { $outStr = sprintf("%-5s %d", $field, ord($fieldData)); }else { - # ezcaByte, ezcaShort, ezcaLong + # ezcaByte, ezcaShort, ezcaLong $outStr = sprintf("%-5s %d", $field, $fieldData); } @@ -293,21 +293,21 @@ sub printField { return($col); } -# Query for a list of pvs simultaneously +# 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: $read_pvs = caget( @pvlist ) +# Usage: $fields_read = caget( @pvlist ) sub caget { my @chans = map { CA->new($_); } @_; my $wait = 1; - + #clear results; %callback_data = (); - + eval { CA->pend_io($wait); }; if ($@) { if ($@ =~ m/^ECA_TIMEOUT/) { @@ -330,10 +330,10 @@ sub caget { $_->get_callback(\&caget_callback, $type); } @chans; - my $read_pvs = @chans; + my $fields_read = @chans; $callback_incomplete = @chans; CA->pend_event(0.1) while $callback_incomplete; - return $read_pvs; + return $fields_read; } sub caget_callback { @@ -356,10 +356,10 @@ sub printRecord { $recType = getRecType($name); print("$name is record type $recType\n"); exists($record{$recType}) || die "Record type $recType not found in dbd file --"; - - #capture list of fields to obtain - my @list = (); #fiels to read - my @fields_pr = (); #fields for print-out + + #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 $field (sort keys %{$record{$recType}}) { @@ -371,18 +371,19 @@ sub printRecord { if( $interest >= $fInterest ) { $fToGet = $name . "." . $field; push @fields_pr, $field; - push @list, $fToGet; + push @readlist, $fToGet; push @ftypes, $fType; push @bases, $base; } } } - my $read_pvs = caget( @list ); + my $fields_read = caget( @readlist ); + # print while iterating over lists gathered $col = 0; - for (my $i=0; $i < scalar @list; $i++) { + for (my $i=0; $i < scalar @readlist; $i++) { $field = $fields_pr[$i]; - $fToGet = $list[$i]; + $fToGet = $readlist[$i]; $data = $callback_data{$fToGet}; $fType = $ftypes[$i]; chomp $data; @@ -431,18 +432,3 @@ sub printRecordList { } } -sub show_call_stack { - my ( $path, $line, $subr ); - my $max_depth = 30; - my $i = 1; - print("--- Begin stack trace ---\n"); - my @call_details; - @call_details = caller($i); - while ( (@call_details) && ($i<$max_depth) ) { - print("$call_details[1] line $call_details[2] in function $call_details[3]\n"); - $i = $i +1; - @call_details = caller($i); - } - print("--- End stack trace ---\n"); -} - From ce4ba8bbaf5de2832600515b842bf5568501018b Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Wed, 26 May 2010 00:10:06 +0100 Subject: [PATCH 22/36] Help or capr.pl --- src/cap5/capr.pl | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index aa2fc0dce..c418a0f82 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -24,8 +24,8 @@ if ( defined $ENV{"EPICS_HOST_ARCH"} ) { $hostArch="solaris-sparc"; } -our( $opt_d, $opt_f, $opt_r); -my $usage = "Usage:\n $0 [-d dbd_file] ( [-f record_type] | [-r] | [record_name] ) [interest]\n"; +our( $opt_h, $opt_d, $opt_f, $opt_r); + my $theDbdFile; my %record = (); # Empty hash to put dbd data in my $iIdx = 0; # Array indexes for interest, data type and base @@ -62,7 +62,8 @@ my $cadebug = 0; ######### Main program ############ -getopts('d:f:r') or die "$usage"; +HELP_MESSAGE() unless getopts('hd:f:r'); +HELP_MESSAGE() if $opt_h; # Select the dbd file to use if($opt_d) { # command line has highest priority @@ -72,9 +73,7 @@ elsif (exists $ENV{CAPR_DBD_FILE}) { # Use the env var if it exists $theDbdFile = $ENV{CAPR_DBD_FILE}; } # Otherwise use the default set above else { - die "Error: no default dbd defined\n". - "Specify dbd with -d option or CAPR_DBD_FILE environment variable\n". - $usage; + die "No dbd file defined. ('capr.pl -h' gives help)\n"; } parseDbd($theDbdFile); @@ -95,7 +94,7 @@ if($opt_f) { # Do the business # Allow commas between arguments as in vxWorks dbpr -die "$usage" unless defined $ARGV[0]; +HELP_MESSAGE() unless defined $ARGV[0]; $ARGV[0] =~ s/,/ /; # Get rid of pesky comma if it's there if($ARGV[0] =~ m/\s+\d/) { # If we replace comma with a space, ($ARGV[0], $ARGV[1]) = split(/ /, $ARGV[0]); #split it @@ -345,7 +344,7 @@ sub caget_callback { # Given record name and interest level prints data from record fields # that are at or below the interest level specified. -# Useage: printRecord( $recordName, $interestLevel) +# Usage: printRecord( $recordName, $interestLevel) sub printRecord { my $name = $_[0]; my $interest = $_[1]; @@ -432,3 +431,25 @@ sub printRecordList { } } +sub HELP_MESSAGE { + print STDERR "\n", +"Usage: capr.pl -h\n", +" capr.pl [-d dbd_file] -r\n", +" capr.pl [-d dbd_file] -f \n", +" capr.pl [-d dbd_file] \n", +"Description:\n", +" Attempts to perform a record print \"dbpr\" via channel access\n", +" for record_name at a given interest level.\n", +" The default interest level is 0.\n\n", +" If used with the f or r options, prints fields/record type lists.\n", +"\n", +"Options:\n", +" -h: Help: Prints this message\n", +" -d Dbd file: specify dbd file used to read record definitions.\n", +" If omitted, the environment variable CAPR_DBD_FILE must be defined\n", +" -r Prints the list of record types\n", +" -f Prints list of fields, interest level, type and base for the\n", +" given record type\n", +"\n"; + exit 1; +} From eaf07d4f05b72ad340b5a5eec4288a25ef81b79a Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 26 May 2010 17:17:26 +0100 Subject: [PATCH 23/36] copyright boilerplate for devLibVME --- src/libCom/osi/devLib.h | 17 +++++++++++++++++ src/libCom/osi/devLibVME.c | 6 ++++-- src/libCom/osi/devLibVMEImpl.h | 2 ++ src/libCom/osi/os/RTEMS/devLibVMEOSD.c | 2 +- src/libCom/osi/os/cygwin32/devLibVMEOSD.c | 2 +- src/libCom/osi/os/default/devLibVMEOSD.c | 2 +- src/libCom/osi/os/vxWorks/devLibVMEOSD.c | 2 +- 7 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h index 12e583e45..e642afe5a 100644 --- a/src/libCom/osi/devLib.h +++ b/src/libCom/osi/devLib.h @@ -1,4 +1,21 @@ +/*************************************************************************\ +* 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. +\*************************************************************************/ +/* devLib.h */ +/* $Id$ */ +/* + * Original Author: Marty Kraimer + * Author: Jeff Hill + * Date: 03-10-93 + */ #ifndef EPICSDEVLIB_H #define EPICSDEVLIB_H diff --git a/src/libCom/osi/devLibVME.c b/src/libCom/osi/devLibVME.c index 7d5c9981a..730b65447 100644 --- a/src/libCom/osi/devLibVME.c +++ b/src/libCom/osi/devLibVME.c @@ -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 @@ -7,7 +9,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ /* devLib.c - support for allocation of common device resources */ -/* devLib.c,v 1.1.2.11 2009/07/09 16:37:23 anj Exp */ +/* $Id$ */ /* * Original Author: Marty Kraimer @@ -18,7 +20,7 @@ * .01 06-14-93 joh needs devAllocInterruptVector() routine */ -static const char sccsID[] = "@(#) devLib.c,v 1.1.2.11 2009/07/09 16:37:23 anj Exp"; +static const char sccsID[] = "@(#) $Id$"; #include #include diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h index b75aa1ba9..1f5db3bb4 100644 --- a/src/libCom/osi/devLibVMEImpl.h +++ b/src/libCom/osi/devLibVMEImpl.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 diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c index 44ebb3adf..44861b83d 100644 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c @@ -6,7 +6,7 @@ * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* devLibOSD.c,v 1.1.2.8 2009/07/09 16:37:23 anj Exp */ +/* $Id$ */ /* RTEMS port by Till Straumann, * 3/2002 diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c index 3058292a5..5c327b939 100644 --- a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c +++ b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c @@ -5,7 +5,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* devLibOSD.c,v 1.1.2.1 2009/06/15 16:10:05 anj Exp */ +/* $Id$ */ #include diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c index 0ae3e56cf..40ae6b589 100644 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ b/src/libCom/osi/os/default/devLibVMEOSD.c @@ -6,7 +6,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* devLibOSD.c,v 1.1.2.1 2006/02/17 22:51:24 anj Exp */ +/* $Id$ */ #include diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c index 525678419..11b17fe57 100644 --- a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c +++ b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c @@ -7,7 +7,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ /* - * devLibOSD.c,v 1.1.2.9 2009/07/09 16:37:23 anj Exp + * $Id$ * * Archictecture dependent support for common device driver resources * From 31931330a802acee1cecbec5c3e17170539e6859 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Wed, 26 May 2010 23:20:36 +0100 Subject: [PATCH 24/36] removing ezca strings mapping --- src/cap5/capr.pl | 98 +++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index c418a0f82..a445e55ad 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -17,13 +17,6 @@ use CA; ######### Globals ########## -my $hostArch; -if ( defined $ENV{"EPICS_HOST_ARCH"} ) { - $hostArch = $ENV{"EPICS_HOST_ARCH"} ; -} else { - $hostArch="solaris-sparc"; -} - our( $opt_h, $opt_d, $opt_f, $opt_r); my $theDbdFile; @@ -34,29 +27,29 @@ my $bIdx = 2; my %device = (); # Empty hash to record which rec types have device support my $DEBUG=0; # DEBUG -# EPICS field types referenced to their equivalent EZCA types +# EPICS field types my %fieldType = ( - DBF_STRING => "ezcaString", - DBF_BYTE => "ezcaByte", - DBF_CHAR => "ezcaByte", - DBF_UCHAR => "ezcaChar", - DBF_SHORT => "ezcaShort", - DBF_USHORT => "ezcaLong", - DBF_LONG => "ezcaLong", - DBF_ULONG => "ezcaDouble", - DBF_FLOAT => "ezcaFloat", - DBF_DOUBLE => "ezcaDouble", - DBF_ENUM => "ezcaString", - DBF_MENU => "ezcaString", - DBF_DEVICE => "ezcaString", - DBF_INLINK => "ezcaString", - DBF_OUTLINK => "ezcaString", - DBF_FWDLINK => "ezcaString", - DBF_NOACCESS => "ezcaNoAccess" + 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; my $cadebug = 0; @@ -69,9 +62,12 @@ HELP_MESSAGE() if $opt_h; if($opt_d) { # command line has highest priority $theDbdFile = $opt_d; } -elsif (exists $ENV{CAPR_DBD_FILE}) { # Use the env var if it exists - $theDbdFile = $ENV{CAPR_DBD_FILE}; +elsif (exists $ENV{EPICS_CAPR_DBD_FILE}) { # Use the env var if it exists + $theDbdFile = $ENV{EPICS_CAPR_DBD_FILE}; } # Otherwise use the default set above +elsif (exists $ENV{EPICS_BASE}) { + $theDbdFile = $ENV{EPICS_BASE} . "/dbd/softIoc.dbd"; +} else { die "No dbd file defined. ('capr.pl -h' gives help)\n"; } @@ -101,12 +97,15 @@ if($ARGV[0] =~ m/\s+\d/) { # If we replace comma with a space, } $ARGV[0] =~ s/\s+//; # Remove any spaces $ARGV[0] =~ s/\..*//; # Get rid of field name if it's there -$ARGV[1] = 0 unless defined $ARGV[1]; # default interest level is 0 -$ARGV[1] =~ s/\D//g; # Make sure we only use digits -$ARGV[1] = $ARGV[1] || 0; # interest defaults to 0 +if ( defined $ARGV[1] ) { + $ARGV[1] =~ s/\D//g; # Make sure we only use digits + $ARGV[1] = $ARGV[1] || 0; # blank => interest level set to 0 +} +else { + $ARGV[1] = 0; # interest defaults to 0 +} printRecord($ARGV[0], $ARGV[1]); # Do the do - ########## End of main ########### @@ -260,16 +259,17 @@ sub printField { $field = $fieldName . ":"; - if( $dataType eq "ezcaString" ) { + if( $dataType eq "DBF_STRING" ) { $outStr = sprintf("%-5s %s", $field, $fieldData); } elsif ( $base eq "HEX" ) { - $outStr = sprintf("%-5s %x", $field, $fieldData); - } elsif ( $dataType eq "ezcaDouble" || $dataType eq "ezcaFloat" ) { + my $val = ( $dataType eq "DBF_CHAR" ) ? ord($fieldData) : $fieldData; + $outStr = sprintf("%-5s %x", $field, $val); + } elsif ( $dataType eq "DBF_DOUBLE" || $dataType eq "DBF_FLOAT" ) { $outStr = sprintf("%-5s %.8f", $field, $fieldData); - } elsif ( $dataType eq "ezcaChar" ) { + } elsif ( $dataType eq "DBF_CHAR" ) { $outStr = sprintf("%-5s %d", $field, ord($fieldData)); }else { - # ezcaByte, ezcaShort, ezcaLong + # DBF_LONG, DBF_SHORT, DBF_UCHAR, DBF_ULONG, DBF_USHORT $outStr = sprintf("%-5s %d", $field, $fieldData); } @@ -306,6 +306,7 @@ sub caget { #clear results; %callback_data = (); + %timed_out = (); eval { CA->pend_io($wait); }; if ($@) { @@ -313,8 +314,7 @@ sub caget { my $err = (@chans > 1) ? 'some PV(s)' : "'" . $chans[0]->name . "'"; print "Channel connect timed out: $err not found.\n"; foreach my $chan (@chans) { - $callback_data{$chan->name} = "" - unless $chan->is_connected; + $timed_out{$chan->name} = ( $chan->is_connected ) ? 0 : 1; } @chans = grep { $_->is_connected } @chans; } else { @@ -366,7 +366,7 @@ sub printRecord { if($field eq "DTYP" && !(exists($device{$recType}))) { next; } ($fType, $fInterest, $base) = getFieldParams($recType, $field); - unless( $fType eq "ezcaNoAccess" ) { + unless( $fType eq "DBF_NOACCESS" ) { if( $interest >= $fInterest ) { $fToGet = $name . "." . $field; push @fields_pr, $field; @@ -383,9 +383,15 @@ sub printRecord { for (my $i=0; $i < scalar @readlist; $i++) { $field = $fields_pr[$i]; $fToGet = $readlist[$i]; - $data = $callback_data{$fToGet}; - $fType = $ftypes[$i]; - chomp $data; + if ( $timed_out{$fToGet} ) { + $fType = $fieldType{DBF_STRING}; + $data = ""; + } + else { + $fType = $ftypes[$i]; + $data = $callback_data{$fToGet}; + chomp $data; + } $col = printField($field, $data, $fType, $base, $col); } print("\n"); # Final line feed @@ -438,15 +444,15 @@ sub HELP_MESSAGE { " capr.pl [-d dbd_file] -f \n", " capr.pl [-d dbd_file] \n", "Description:\n", -" Attempts to perform a record print \"dbpr\" via channel access\n", -" for record_name at a given interest level.\n", -" The default interest level is 0.\n\n", +" Attempts to perform a 'dbpr' record print via channel access for record_name at a given\n", +" interest level. The default interest level is 0.\n\n", " If used with the f or r options, prints fields/record type lists.\n", "\n", "Options:\n", " -h: Help: Prints this message\n", " -d Dbd file: specify dbd file used to read record definitions.\n", -" If omitted, the environment variable CAPR_DBD_FILE must be defined\n", +" The default can be specified with the EPICS_CAPR_DBD_FILE environment\n", +" variable. The default file is \$(EPICS_BASE)/dbd/softIoc.dbd\n", " -r Prints the list of record types\n", " -f Prints list of fields, interest level, type and base for the\n", " given record type\n", From 07d51b65b249fd2c503643e315dd51508dae0149 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Wed, 26 May 2010 23:49:21 +0100 Subject: [PATCH 25/36] consistently use double quotes --- src/cap5/capr.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index a445e55ad..9519078e1 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -55,7 +55,7 @@ my $cadebug = 0; ######### Main program ############ -HELP_MESSAGE() unless getopts('hd:f:r'); +HELP_MESSAGE() unless getopts("hd:f:r"); HELP_MESSAGE() if $opt_h; # Select the dbd file to use @@ -69,7 +69,7 @@ elsif (exists $ENV{EPICS_BASE}) { $theDbdFile = $ENV{EPICS_BASE} . "/dbd/softIoc.dbd"; } else { - die "No dbd file defined. ('capr.pl -h' gives help)\n"; + die "No dbd file defined. (\"capr.pl -h\" gives help)\n"; } parseDbd($theDbdFile); @@ -217,7 +217,7 @@ sub getRecType { my $fields_read = caget( $name ); - if ( $fields_read != 1 ) { die "Record \"$_[0]\" not found\n"; } + if ( $fields_read != 1 ) { die "Could not determine \"$_[0]\" record type.\n"; } $data = $callback_data{ $name }; chomp $data; $data =~ s/\s+//; @@ -311,7 +311,7 @@ sub caget { eval { CA->pend_io($wait); }; if ($@) { if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = (@chans > 1) ? 'some PV(s)' : "'" . $chans[0]->name . "'"; + 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 ) ? 0 : 1; @@ -444,7 +444,7 @@ sub HELP_MESSAGE { " capr.pl [-d dbd_file] -f \n", " capr.pl [-d dbd_file] \n", "Description:\n", -" Attempts to perform a 'dbpr' record print via channel access for record_name at a given\n", +" Attempts to perform a \"dbpr\" record print via channel access for record_name at a given\n", " interest level. The default interest level is 0.\n\n", " If used with the f or r options, prints fields/record type lists.\n", "\n", From 7d3986664e1249f361596f36e51ab4e4cb7c6a81 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 27 May 2010 09:35:29 +0100 Subject: [PATCH 26/36] fix typo in rtems internal function names Not externally visible so no reason not to fix --- src/libCom/osi/os/RTEMS/devLibVMEOSD.c | 42 +++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c index 44861b83d..0143780b4 100644 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c @@ -72,34 +72,34 @@ 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 */ -static 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 */ -static long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); +static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); -static long rtmsDevConnectInterruptVME ( +static long rtemsDevConnectInterruptVME ( unsigned vectorNumber, void (*pFunction)(), void *parameter); -static long rtmsDevDisconnectInterruptVME ( +static long rtemsDevDisconnectInterruptVME ( unsigned vectorNumber, void (*pFunction)() ); -static long rtmsDevEnableInterruptLevelVME (unsigned level); +static long rtemsDevEnableInterruptLevelVME (unsigned level); -static long rtmsDevDisableInterruptLevelVME (unsigned level); +static long rtemsDevDisableInterruptLevelVME (unsigned level); static int rtemsDevInterruptInUseVME (unsigned vectorNumber); @@ -108,22 +108,22 @@ static int rtemsDevInterruptInUseVME (unsigned vectorNumber); /*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 devLibVME rtemsVirtualOS = { - rtmsDevMapAddr, rtmsDevReadProbe, rtmsDevWriteProbe, - rtmsDevConnectInterruptVME, rtmsDevDisconnectInterruptVME, - rtmsDevEnableInterruptLevelVME, rtmsDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,rtmsDevInit,rtemsDevInterruptInUseVME + rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe, + rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME, + rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME, + devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME }; 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.] */ @@ -135,7 +135,7 @@ rtmsDevInit(void) * * wrapper to minimize driver dependency on OS */ -static long rtmsDevConnectInterruptVME ( +static long rtemsDevConnectInterruptVME ( unsigned vectorNumber, void (*pFunction)(), void *parameter) @@ -168,7 +168,7 @@ static long rtmsDevConnectInterruptVME ( * an interrupt handler that was installed by another driver * */ -static long rtmsDevDisconnectInterruptVME ( +static long rtemsDevDisconnectInterruptVME ( unsigned vectorNumber, void (*pFunction)() ) @@ -204,7 +204,7 @@ static long rtmsDevDisconnectInterruptVME ( /* * enable VME interrupt level */ -static long rtmsDevEnableInterruptLevelVME (unsigned level) +static long rtemsDevEnableInterruptLevelVME (unsigned level) { return BSP_enableVME_int_lvl(level); } @@ -212,15 +212,15 @@ static long rtmsDevEnableInterruptLevelVME (unsigned level) /* * disable VME interrupt level */ -static long rtmsDevDisableInterruptLevelVME (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; @@ -250,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); -static long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) +static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) { long status; @@ -269,7 +269,7 @@ static long rtmsDevReadProbe (unsigned wordSize, volatile const void *ptr, void * a bus error safe "wordSize" write at the specified address which returns * unsuccessful status if the device isnt present */ -static long rtmsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) +static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) { long status; From ba42c501df82a6333e4a7a38c5d0cb68ea93681e Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Thu, 27 May 2010 11:52:21 +0100 Subject: [PATCH 27/36] Simplistic solution to parser problems --- src/cap5/capr.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 9519078e1..692d89c1b 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -146,14 +146,14 @@ sub parseDbd { chomp; print("line $i - level $level\n") if ($DEBUG); #$line = $dbd[$i] || die "Unexpected end of file: $dbdFile, line $."; - if( m/recordtype/ ) { + if( m/recordtype\(/ ) { ($level == 0) || die "dbd file format error in or before line $i --"; m/\((.*)\)/; #get record type #@records = (@records, $1); $isArecord = 1; $thisRecord = $1; } - if( m/field/ ) { + if( m/field\(/ ) { ($level == 1 && $isArecord) || die "dbd file format error in or before line $i --"; m/\((.*),/; # get field name $thisField = $1; @@ -162,12 +162,12 @@ sub parseDbd { $isAfield = 1; #print("$1 , line $i "); } - if( m/interest/ ) { + if( m/interest\(/ ) { ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; m/\((.*)\)/ ; # get interest level, default = 0 $interest = $1; } - if( m/base/ ) { + if( m/base\(/ ) { ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; m/\((.*)\)/ ; # get base, default = DECIMAL $thisBase = $1; @@ -196,7 +196,7 @@ sub parseDbd { $level--; } # Parse for record types with device support - if( m/device/ ) { + if( m/device\(/ ) { m/\((.*?),/; if(!exists($device{$1})) { # Use a hash to make a list of record types with device support From 5ad3391be259b6d37678115ab119f3c06e810e43 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Thu, 27 May 2010 14:03:17 +0100 Subject: [PATCH 28/36] create test cases from I02 beamline --- src/cap5/test-cases.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/cap5/test-cases.pl diff --git a/src/cap5/test-cases.pl b/src/cap5/test-cases.pl new file mode 100644 index 000000000..118f5d808 --- /dev/null +++ b/src/cap5/test-cases.pl @@ -0,0 +1,11 @@ +grep record BL02I-MO-IOC-02.db |\ +grep -v '^#' |\ +perl -e ' +%h = (); +while(<>){ + @a = split /,/; + $a[0] =~ s/record\(//; + $h{$a[0]}=$a[1]; +} +print %h;' + From a24f6371ac463db8faa8709cffa309dbdb50ee99 Mon Sep 17 00:00:00 2001 From: Ronaldo Mercado Date: Thu, 27 May 2010 16:24:09 +0100 Subject: [PATCH 29/36] Removes complaints when the string to print has dollars. --- src/cap5/capr.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 692d89c1b..84a843322 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -286,7 +286,7 @@ sub printField { $col = 0; } - print sprintf("$outStr%*s",$pad," "); + print $outStr . sprintf("%*s",$pad," "); $col = $col + $wide; return($col); From 5ce74f2a414295f800c6743b41780e33bbdf96fd Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 28 May 2010 12:04:46 +0100 Subject: [PATCH 30/36] include compatibility definition of pdevLibVirtualOS --- src/libCom/osi/devLibVMEImpl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h index 1f5db3bb4..63d794ca3 100644 --- a/src/libCom/osi/devLibVMEImpl.h +++ b/src/libCom/osi/devLibVMEImpl.h @@ -92,6 +92,11 @@ typedef struct devLibVME { epicsShareExtern devLibVME *pdevLibVME; +#ifndef NO_DEVLIB_COMPAT +# define pdevLibVirtualOS pdevLibVME +#endif + + #ifdef __cplusplus } #endif From bb740373bc17815cf5a086bd541dfc5ff300392f Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Wed, 16 Jun 2010 15:46:09 -0400 Subject: [PATCH 31/36] Fix: Replaced C++ style comments in C code with standard C comments. --- src/libCom/osi/os/WIN32/osdProcess.c | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/libCom/osi/os/WIN32/osdProcess.c index 0fb9886eb..cfeb927c9 100644 --- a/src/libCom/osi/os/WIN32/osdProcess.c +++ b/src/libCom/osi/os/WIN32/osdProcess.c @@ -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"); + } + */ } From 60be4921c8b0ae82fdc470a360497d64573ba2d0 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Wed, 16 Jun 2010 15:58:00 -0400 Subject: [PATCH 32/36] Fix: Replaced C++ reserved word 'new' as variable name. --- src/db/db_access.c | 398 ++++++++++++++++++------------------- src/dbStatic/dbStaticLib.c | 10 +- 2 files changed, 204 insertions(+), 204 deletions(-) diff --git a/src/db/db_access.c b/src/db/db_access.c index 55f415543..6f389257f 100644 --- a/src/db/db_access.c +++ b/src/db/db_access.c @@ -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, diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c index 1f937a81f..8871ad64c 100644 --- a/src/dbStatic/dbStaticLib.c +++ b/src/dbStatic/dbStaticLib.c @@ -516,14 +516,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 +538,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) From 320ff29c4aafd9783a0af53c4041acfe79d6d912 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 22 Jun 2010 11:43:42 -0500 Subject: [PATCH 33/36] Fix bad string handling in makeBpt. This behaved badly when confronted with windows CR+LF end of lines. Using fgets() left a stray CR at the end of the returned string. --- src/bpt/makeBpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bpt/makeBpt.c b/src/bpt/makeBpt.c index 7f5c39602..b88e82a74 100644 --- a/src/bpt/makeBpt.c +++ b/src/bpt/makeBpt.c @@ -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; From f1ba442133731313e31c98756ff4e459860d5f90 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 22 Jun 2010 17:35:48 -0500 Subject: [PATCH 34/36] Store original INP/OUT text in link in case DTYP changes later. --- documentation/RELEASE_NOTES.html | 4 ++++ src/dbStatic/dbStaticLib.c | 16 ++++++++++++++++ src/dbStatic/link.h | 1 + 3 files changed, 21 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9b3ce378e..70b24ac5c 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -12,6 +12,10 @@

Changes between 3.14.11 and 3.14.12

+

DTYP and INP/OUT order

+ +

The fields DTYP and INP/OUT can now be specified in any order.

+

Rewrite epicsThreadOnce()

Michael Davidsaver suggested a better implementation of epicsThreadOnce() diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c index 8871ad64c..67275bbd8 100644 --- a/src/dbStatic/dbStaticLib.c +++ b/src/dbStatic/dbStaticLib.c @@ -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)); } @@ -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; diff --git a/src/dbStatic/link.h b/src/dbStatic/link.h index a43c5711e..3d97fa1a9 100644 --- a/src/dbStatic/link.h +++ b/src/dbStatic/link.h @@ -183,6 +183,7 @@ union value{ struct link{ union value value; short type; + char *text; /* original INP/OUT link text */ }; typedef struct link DBLINK; From cfb8e694a5b935501cb38be0abc5c5407590a5c6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 2 Jul 2010 11:34:38 -0500 Subject: [PATCH 35/36] Several cleanups. * Fixed number base issue * DBD file parser accepts spaces * Added -w seconds option for CA timeout * Improved argument parsing * More perlish, should start up faster --- src/cap5/capr.pl | 422 +++++++++++++++++++++-------------------------- 1 file changed, 192 insertions(+), 230 deletions(-) diff --git a/src/cap5/capr.pl b/src/cap5/capr.pl index 84a843322..4f8abac3d 100644 --- a/src/cap5/capr.pl +++ b/src/cap5/capr.pl @@ -13,283 +13,250 @@ use FindBin qw($Bin); use lib "$Bin/../../lib/perl"; use Getopt::Std; +use EPICS::Path; use CA; ######### Globals ########## -our( $opt_h, $opt_d, $opt_f, $opt_r); +our ($opt_h, $opt_f, $opt_r); +our $opt_d = $ENV{EPICS_CAPR_DBD_FILE} || "$Bin/../../dbd/softIoc.dbd"; +our $opt_w = 1; -my $theDbdFile; 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 -my $DEBUG=0; # DEBUG # 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", + 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; -my $cadebug = 0; ######### Main program ############ -HELP_MESSAGE() unless getopts("hd:f:r"); +HELP_MESSAGE() unless getopts('hd:f:rw:'); HELP_MESSAGE() if $opt_h; -# Select the dbd file to use -if($opt_d) { # command line has highest priority - $theDbdFile = $opt_d; -} -elsif (exists $ENV{EPICS_CAPR_DBD_FILE}) { # Use the env var if it exists - $theDbdFile = $ENV{EPICS_CAPR_DBD_FILE}; -} # Otherwise use the default set above -elsif (exists $ENV{EPICS_BASE}) { - $theDbdFile = $ENV{EPICS_BASE} . "/dbd/softIoc.dbd"; -} -else { - die "No dbd file defined. (\"capr.pl -h\" gives help)\n"; -} +die "File $opt_d not found. (\"capr.pl -h\" gives help)\n" + unless -f $opt_d; -parseDbd($theDbdFile); -print "Using $theDbdFile\n\n"; +parseDbd($opt_d); +print "Using $opt_d\n\n"; # Print a list of record types -if($opt_r) { - print ("Record types defined in $theDbdFile\n"); +if ($opt_r) { + print ("Record types found:\n"); printList(0); exit; } # Print the fields defined for given record -if($opt_f) { +if ($opt_f) { printRecordList($opt_f); exit; } -# Do the business -# Allow commas between arguments as in vxWorks dbpr -HELP_MESSAGE() unless defined $ARGV[0]; -$ARGV[0] =~ s/,/ /; # Get rid of pesky comma if it's there -if($ARGV[0] =~ m/\s+\d/) { # If we replace comma with a space, - ($ARGV[0], $ARGV[1]) = split(/ /, $ARGV[0]); #split it +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); + } } -$ARGV[0] =~ s/\s+//; # Remove any spaces -$ARGV[0] =~ s/\..*//; # Get rid of field name if it's there -if ( defined $ARGV[1] ) { - $ARGV[1] =~ s/\D//g; # Make sure we only use digits - $ARGV[1] = $ARGV[1] || 0; # blank => interest level set to 0 -} -else { - $ARGV[1] = 0; # interest defaults to 0 -} -printRecord($ARGV[0], $ARGV[1]); # Do the do ########## 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: void parseDbd("fileName"); -# Output is in the hash %record. This is a hash of (references to) another. -# hash containing the fields of this record, as keys. The value keyed by -# the field names are (references to) arrays. Each of these arrays contains -# the interest level, data type and base of the field +# 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 = $_[0]; - my @dbd; - my $length; + my $dbdFile = shift; + + open(DBD, "< $dbdFile") or die "Can't open file $dbdFile: $!\n"; + my @dbd = ; + close(DBD) or die "Can't close $dbdFile: $!\n"; + + my $i = 1; my $level = 0; - my $i = 0; my $isArecord = 0; - my $isAfield; + my $isAfield = 0; my $thisRecord; my $thisField; my $thisType; - my %field = (); - my @params = (); + my $field = {}; my $interest = 0; - my $thisBase = "DECIMAL"; - my $item; - my $newDevice; + my $thisBase = 'DECIMAL'; - open(DBD, "< $dbdFile") || die "Can't open dbd file $dbdFile --"; - @dbd = ; - $length = @dbd; - close(DBD) || die "Can't close $dbdFile --"; - - while ($i < $length) { - $_ = $dbd[$i]; + while (@dbd) { + $_ = shift @dbd; chomp; - print("line $i - level $level\n") if ($DEBUG); - #$line = $dbd[$i] || die "Unexpected end of file: $dbdFile, line $."; - if( m/recordtype\(/ ) { - ($level == 0) || die "dbd file format error in or before line $i --"; - m/\((.*)\)/; #get record type - #@records = (@records, $1); + 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; } - if( m/field\(/ ) { - ($level == 1 && $isArecord) || die "dbd file format error in or before line $i --"; - m/\((.*),/; # get field name + 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; - m/,(.*)\)/; # get field type - $thisType = $1; + $thisType = $2; $isAfield = 1; - #print("$1 , line $i "); } - if( m/interest\(/ ) { - ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; - m/\((.*)\)/ ; # get interest level, default = 0 + 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; } - if( m/base\(/ ) { - ($level == 2 && $isAfield) || die "dbd file format error in or before line $i --"; - m/\((.*)\)/ ; # get base, default = DECIMAL + 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; } - if( m/\{/ ) { $level++ }; - if( m/\}/ ) { - if( $level == 2 && $isAfield) { + 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; - $params[$iIdx] = $interest; - $params[$tIdx] = $thisType; - $params[$bIdx] = $thisBase; - $field{$thisField} = [@params]; - #print("interest $interest\n"); - $interest = 0; # set up default for next time - $thisBase = "DECIMAL"; # set up default for next time + $interest = 0; # reset default + $thisBase = 'DECIMAL'; # reset default } - if( $level == 1 && $isArecord) { + elsif ($level == 1 && $isArecord) { $isArecord = 0; - $record{$thisRecord} = { %field }; - #print("record type $thisRecord "); - #foreach $key (keys(%field)) { - # print("Field $key - interest $field{$key}\n"); - #} - %field = (); # set up for next time + $record{$thisRecord} = $field; + $field = {}; # start another hash } $level--; } - # Parse for record types with device support - if( m/device\(/ ) { - m/\((.*?),/; - if(!exists($device{$1})) { - # Use a hash to make a list of record types with device support - $device{$1} = 1; - } - } $i++; } } -# Given a record name attempts to find the record and its type. -# Usage: getRecType(recordName) - returns ($error, $recordType) +# Given a record name, attempts to find the record and its type. +# Usage: $recordType = getRecType("recordName"); sub getRecType { - my $name = $_[0] . ".RTYP"; - my $type; - my $data; + my $arg = shift; + my $name = "$arg.RTYP"; - my $fields_read = caget( $name ); + my $fields_read = caget($name); - if ( $fields_read != 1 ) { die "Could not determine \"$_[0]\" record type.\n"; } - $data = $callback_data{ $name }; - chomp $data; - $data =~ s/\s+//; - #print("$name is a \"$data\"type\n"); - return($data); + die "Could not determine record type of $arg\n" + unless $fields_read == 1; + + return $callback_data{$name}; } -# Given the record type and the field returns the interest level, data type -# and base for the field -# Usage: ($dataType, $interest, $base) getFieldParams( $recType, $field) +# 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 = $_[0]; - my $field = $_[1]; - my ($fType, $fInterest, $fBase); + my ($recType, $field) = @_; - exists($fieldType{$record{$recType}{$field}[$tIdx]}) || + 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($record{$recType}{$field}[$iIdx]) || + exists($params->[$iIdx]) || die "Interest level for $field in $recType not found in dbd file --"; - $fType = $fieldType{$record{$recType}{$field}[$tIdx]}; - $fInterest = $record{$recType}{$field}[$iIdx]; - $fBase = $record{$recType}{$field}[$bIdx]; - return($fType, $fInterest, $fBase); + 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 = $_[0]; - my $fieldData = $_[1]; - my $dataType = $_[2]; - my $base = $_[3]; # base to display numeric data in - my $col = $_[4]; # first column to print in + my ($fieldName, $fieldData, $dataType, $base, $col) = @_; my $screenWidth = 80; - my ($outStr, $len, $wide, $pad, $field); + my ($outStr, $wide); - $field = $fieldName . ":"; + 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 %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)); + 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); + $outStr = sprintf('%-5s %d', $field, $fieldData); } - $len = length($outStr); - if($len <= 20) { $wide = 20; } - elsif( $len <= 40 ) { $wide = 40; } - elsif( $len <= 60 ) { $wide = 60; } + my $len = length($outStr); + if ($len <= 20) { $wide = 20; } + elsif ( $len <= 40 ) { $wide = 40; } + elsif ( $len <= 60 ) { $wide = 60; } else { $wide = 80;} - $pad = $wide - $len; + my $pad = $wide - $len; - if( $col + $wide > $screenWidth ) { + $col += $wide; + if ($col > $screenWidth ) { print("\n"); - $col = 0; + $col = $wide; } - print $outStr . sprintf("%*s",$pad," "); - $col = $col + $wide; + print $outStr, ' ' x $pad; - return($col); + return $col; } # Query for a list of fields simultaneously. @@ -302,19 +269,18 @@ sub printField { # Usage: $fields_read = caget( @pvlist ) sub caget { my @chans = map { CA->new($_); } @_; - my $wait = 1; #clear results; %callback_data = (); %timed_out = (); - eval { CA->pend_io($wait); }; + eval { CA->pend_io($opt_w); }; if ($@) { if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = (@chans > 1) ? "some PV(s)" : "\"" . $chans[0]->name . "\""; + 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 ) ? 0 : 1; + $timed_out{$chan->name} = $chan->is_connected; } @chans = grep { $_->is_connected } @chans; } else { @@ -325,7 +291,6 @@ sub caget { map { my $type; $type = $_->field_type; - #$callback_data{$_->name} = undef; $_->get_callback(\&caget_callback, $type); } @chans; @@ -344,31 +309,28 @@ sub caget_callback { # Given record name and interest level prints data from record fields # that are at or below the interest level specified. -# Usage: printRecord( $recordName, $interestLevel) +# Usage: printRecord($recordName, $interestLevel) sub printRecord { - my $name = $_[0]; - my $interest = $_[1]; - my ($error, $recType, $field, $fType, $fInterest, $data); - my ($fToGet, $col, $base); - #print("checking record $name, interest $interest\n"); + my ($name, $interest) = @_; - $recType = getRecType($name); - print("$name is record type $recType\n"); - exists($record{$recType}) || die "Record type $recType not found in dbd file --"; + 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 $field (sort keys %{$record{$recType}}) { + 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; } + if ($field eq 'DTYP' && !(exists($device{$recType}))) { next; } - ($fType, $fInterest, $base) = getFieldParams($recType, $field); - unless( $fType eq "DBF_NOACCESS" ) { - if( $interest >= $fInterest ) { - $fToGet = $name . "." . $field; + 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; @@ -379,22 +341,23 @@ sub printRecord { my $fields_read = caget( @readlist ); # print while iterating over lists gathered - $col = 0; + my $col = 0; for (my $i=0; $i < scalar @readlist; $i++) { - $field = $fields_pr[$i]; - $fToGet = $readlist[$i]; - if ( $timed_out{$fToGet} ) { + my $field = $fields_pr[$i]; + my $fToGet = $readlist[$i]; + my ($fType, $data, $base); + if ($timed_out{$fToGet}) { $fType = $fieldType{DBF_STRING}; - $data = ""; + $data = ''; } else { $fType = $ftypes[$i]; + $base = $bases[$i]; $data = $callback_data{$fToGet}; - chomp $data; } $col = printField($field, $data, $fType, $base, $col); } - print("\n"); # Final line feed + print("\n"); # Final newline } # Prints list of record types found in dbd file. If level > 0 @@ -402,13 +365,12 @@ sub printRecord { # also printed. # Diagnostic routine, usage: void printList(level); sub printList { - my $level = $_[0]; - my ($rkey, $fkey); + my $level = shift; - foreach $rkey (sort keys(%record)) { - print("$rkey\n"); - if($level > 0) { - foreach $fkey (keys %{$record{$rkey}}) { + 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"); @@ -420,42 +382,42 @@ sub printList { # Prints list of fields with interest levels for given record type # Diagnostic routine, usage: void printRecordList("recordType"); sub printRecordList { - my ($rkey, $fkey); - my $type = $_[0]; + my $type = shift; - if( exists($record{$type}) ) { + if (exists($record{$type}) ) { print("Record type - $type\n"); - foreach $fkey (sort keys %{$record{$type}}) { - printf("%-4s", $fkey); + 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 $theDbdFile\n"); + 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 dbd_file] -r\n", -" capr.pl [-d dbd_file] -f \n", -" capr.pl [-d dbd_file] \n", -"Description:\n", -" Attempts to perform a \"dbpr\" record print via channel access for record_name at a given\n", -" interest level. The default interest level is 0.\n\n", -" If used with the f or r options, prints fields/record type lists.\n", -"\n", -"Options:\n", -" -h: Help: Prints this message\n", -" -d Dbd file: specify dbd file used to read record definitions.\n", -" The default can be specified with the EPICS_CAPR_DBD_FILE environment\n", -" variable. The default file is \$(EPICS_BASE)/dbd/softIoc.dbd\n", -" -r Prints the list of record types\n", -" -f Prints list of fields, interest level, type and base for the\n", -" given record type\n", -"\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; } From 40b83759de7203cd6f3c92567b16c4eef2c0747a Mon Sep 17 00:00:00 2001 From: Janet Anderson Date: Tue, 6 Jul 2010 17:23:24 -0500 Subject: [PATCH 36/36] Added dBStatic to cas depend dirs. Needs alarm.h --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 49b8b5ea7..3aaaf1fdf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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