Merge branch 'rtems-test' into 3.16

This commit is contained in:
Andrew Johnson
2018-10-25 11:39:17 -05:00
38 changed files with 528 additions and 86 deletions
+8
View File
@@ -175,6 +175,8 @@ testHarness_SRCS += epicsRunDbTests.c
dbTestHarness_SRCS += $(testHarness_SRCS)
dbTestHarness_SRCS_RTEMS += rtemsTestHarness.c
PROD_SRCS_RTEMS += rtemsTestData.c
PROD_vxWorks = dbTestHarness
PROD_RTEMS = dbTestHarness
@@ -182,6 +184,10 @@ TESTSPEC_vxWorks = dbTestHarness.munch; epicsRunDbTests
TESTSPEC_RTEMS = dbTestHarness.boot; epicsRunDbTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
TESTPROD_RTEMS = $(TESTPROD_HOST)
TESTSCRIPTS_RTEMS += $(TESTS:%=%.t)
endif
include $(TOP)/configure/RULES
@@ -193,3 +199,5 @@ devx$(DEP): $(COMMON_DIR)/xRecord.h
scanIoTest$(DEP): $(COMMON_DIR)/xRecord.h
xRecord$(DEP): $(COMMON_DIR)/xRecord.h
rtemsTestData.c : $(TESTFILES) $(TOOLS)/epicsMakeMemFs.pl
$(PERL) $(TOOLS)/epicsMakeMemFs.pl $@ epicsRtemsFSImage $(TESTFILES)
+5
View File
@@ -228,6 +228,11 @@ MAIN(dbStressTest)
testPlan(80+nworkers*3);
#if defined(__rtems__)
testSkip(80+nworkers*3, "Test assumes time sliced preempting scheduling");
return testDone();
#endif
priv = callocMustSucceed(nworkers, sizeof(*priv), "no memory");
testDiag("lock set stress test");
+9
View File
@@ -10,7 +10,11 @@ TOP=../../..
include $(TOP)/configure/CONFIG
INC += epicsRtemsInitHooks.h
INC += epicsMemFs.h
ifeq ($(RTEMS_QEMU_FIXUPS),YES)
rtems_init_CPPFLAGS += -DQEMU_FIXUPS
endif
rtemsCom_SRCS += rtems_init.c
rtemsCom_SRCS += rtems_config.c
rtemsCom_SRCS += rtems_netconfig.c
@@ -18,6 +22,11 @@ rtemsCom_SRCS += rtems_util.c
rtemsCom_SRCS += setBootConfigFromNVRAM.c
rtemsCom_SRCS += epicsRtemsInitHookPre.c
rtemsCom_SRCS += epicsRtemsInitHookPost.c
rtemsCom_SRCS += epicsMemFs.c
ifeq ($(RTEMS_BSP),pc386)
rtemsCom_SRCS += ne2kpci.c
endif
LIBRARY_RTEMS = rtemsCom
+110
View File
@@ -0,0 +1,110 @@
/*************************************************************************\
* Copyright (c) 2014 Brookhaven National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include "epicsMemFs.h"
#ifndef PATH_MAX
# define PATH_MAX 100
#endif
int epicsMemFsLoad(const epicsMemFS *fs)
{
char initdir[PATH_MAX];
const epicsMemFile * const *fileptr = fs->files;
if(getcwd(initdir, sizeof(initdir)-1)==NULL) {
perror("getcwd");
return errno;
}
initdir[sizeof(initdir)-1] = '\0';
for(;*fileptr; fileptr++) {
const epicsMemFile *curfile = *fileptr;
int fd;
ssize_t ret;
size_t sofar;
const char * const *dir = curfile->directory;
/* jump back to the root each time,
* slow but simple.
*/
if(chdir(initdir)) {
perror("chdir");
return errno;
}
printf("-> /");
/* traverse directory tree, creating as necessary */
for(;*dir; dir++) {
int ret;
if(**dir=='.') continue; /* ignore '.' and '..' */
printf("%s/", *dir);
ret = chdir(*dir);
if(ret==-1 && errno==ENOENT) {
/* this directory doesn't exist */
if(mkdir(*dir,0744)==-1) {
printf("\n");
perror("mkdir");
return errno;
}
if(chdir(*dir)==-1) {
printf("\n");
perror("chdir2");
return errno;
}
} else if(ret==-1) {
printf("\n");
perror("chdir1");
return errno;
}
}
/* no file name creates an empty directory */
if(!curfile->name) {
printf("\n");
continue;
}
printf("%s", curfile->name);
/* create or overwrite */
fd = open(curfile->name, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if(fd==-1) {
printf("\n");
perror("open");
return errno;
}
sofar = 0;
while(sofar<curfile->size) {
ret = write(fd, curfile->data+sofar, curfile->size-sofar);
if(ret<=0) {
printf("\n");
perror("write");
return errno;
}
sofar += ret;
}
close(fd);
printf(" - ok\n");
}
if(chdir(initdir))
perror("chdir");
return 0;
}
+24
View File
@@ -0,0 +1,24 @@
/*************************************************************************\
* Copyright (c) 2014 Brookhaven National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef EPICSMEMFS_H
#define EPICSMEMFS_H
#include <stdlib.h>
typedef struct {
const char * const *directory; /* NULL terminated list of directories */
const char *name; /* file name */
const char *data; /* file contents */
size_t size; /* size of file contents in bytes */
} epicsMemFile;
typedef struct {
const epicsMemFile * const *files;
} epicsMemFS;
int epicsMemFsLoad(const epicsMemFS *fs);
#endif // EPICSMEMFS_H
+2
View File
@@ -21,3 +21,5 @@ extern char *env_nfsMountPoint;
*/
int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config);
int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config);
/* Return 0 if local file system was setup, or non-zero (will fall back to network */
int epicsRtemsMountLocalFilesystem(char **argv);
+58
View File
@@ -0,0 +1,58 @@
/*************************************************************************\
* Copyright (c) 2015 Brookhaven Science Associates, as Operator of
* Brookhaven National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Wrapper around the ISA ne2000 driver to support detection of the PCI variant.
* Can be used with the ne2k_pci device provided by QEMU.
*
* eg. "qemu-system-i386 ... -net nic,model=ne2k_pci"
*/
#include <stdio.h>
#include <inttypes.h>
#include <bsp.h>
#include <rtems/pci.h>
#include <rtems/rtems_bsdnet.h>
/* The plain ISA driver attach()
* which doesn't (can't?) do any test to see if
* the HW is really present
*/
extern int
rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach);
int
rtems_ne2kpci_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
{
uint8_t irq;
uint32_t bar0;
int B, D, F, ret;
printk("Probing for NE2000 on PCI (aka. Realtek 8029)\n");
if(pci_find_device(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, 0, &B, &D, &F))
{
printk("Not found\n");
return 0;
}
printk("Found %d:%d.%d\n", B, D, F);
ret = pci_read_config_dword(B, D, F, PCI_BASE_ADDRESS_0, &bar0);
ret|= pci_read_config_byte(B, D, F, PCI_INTERRUPT_LINE, &irq);
if(ret || (bar0&PCI_BASE_ADDRESS_SPACE)!=PCI_BASE_ADDRESS_SPACE_IO)
{
printk("Failed reading card config\n");
return 0;
}
config->irno = irq;
config->port = bar0&PCI_BASE_ADDRESS_IO_MASK;
printk("Using port=0x%x irq=%u\n", (unsigned)config->port, config->irno);
return rtems_ne_driver_attach(config, attach);
}
+67 -1
View File
@@ -33,6 +33,7 @@
#include <librtemsNfs.h>
#include <bsp.h>
#include "epicsVersion.h"
#include "epicsThread.h"
#include "epicsTime.h"
#include "epicsExit.h"
@@ -42,9 +43,12 @@
#include "osiUnistd.h"
#include "iocsh.h"
#include "osdTime.h"
#include "epicsMemFs.h"
#include "epicsRtemsInitHooks.h"
#define RTEMS_VERSION_INT VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, 0, 0)
/*
* Prototypes for some functions not in header files
*/
@@ -138,6 +142,31 @@ mustMalloc(int size, const char *msg)
# include <rtems/tftp.h>
#endif
const epicsMemFS *epicsRtemsFSImage __attribute__((weak));
const epicsMemFS *epicsRtemsFSImage = (void*)&epicsRtemsFSImage;
/* hook to allow app specific FS setup */
int
epicsRtemsMountLocalFilesystem(char **argv) __attribute__((weak));
int
epicsRtemsMountLocalFilesystem(char **argv)
{
if(epicsRtemsFSImage==(void*)&epicsRtemsFSImage)
return -1; /* no FS image provided. */
else if(epicsRtemsFSImage==NULL)
return 0; /* no FS image provided, but none is needed. */
else {
printf("***** Using compiled in file data *****\n");
if (epicsMemFsLoad(epicsRtemsFSImage) != 0) {
printf("Can't unpack tar filesystem\n");
return -1;
} else {
argv[1] = "/";
return 0;
}
}
}
static int
initialize_local_filesystem(char **argv)
{
@@ -146,7 +175,9 @@ initialize_local_filesystem(char **argv)
extern char _FlashSize[] __attribute__((weak));
argv[0] = rtems_bsdnet_bootp_boot_file_name;
if (_FlashSize && (_DownloadLocation || _FlashBase)) {
if (epicsRtemsMountLocalFilesystem(argv)==0) {
return 1; /* FS setup successful */
} else if (_FlashSize && (_DownloadLocation || _FlashBase)) {
extern char _edata[];
size_t flashIndex = _edata - _DownloadLocation;
char *header = _FlashBase + flashIndex;
@@ -596,6 +627,7 @@ Init (rtems_task_argument ignored)
}
printf("\n***** Initializing network *****\n");
rtems_bsdnet_initialize_network();
printf("\n***** Setting up file system *****\n");
initialize_remote_filesystem(argv, initialize_local_filesystem(argv));
fixup_hosts();
@@ -666,3 +698,37 @@ Init (rtems_task_argument ignored)
epicsThreadSleep(1.0);
epicsExit(result);
}
#if defined(QEMU_FIXUPS)
/* Override some hooks (weak symbols)
* if BSP defaults aren't configured for running tests.
*/
/* Ensure that stdio goes to serial (so it can be captured) */
#if defined(__i386__) && !USE_COM1_AS_CONSOLE
#include <uart.h>
extern int BSPPrintkPort;
void bsp_predriver_hook(void)
{
BSPConsolePort = BSP_CONSOLE_PORT_COM1;
BSPPrintkPort = BSP_CONSOLE_PORT_COM1;
}
#endif
/* reboot immediately when done. */
#if defined(__i386__) && BSP_PRESS_KEY_FOR_RESET
void bsp_cleanup(void)
{
#if RTEMS_VERSION_INT>=VERSION_INT(4,10,0,0)
void bsp_reset();
bsp_reset();
#else
rtemsReboot();
#endif
}
#endif
#endif /* QEMU_FIXUPS */
int cexpdebug __attribute__((weak));
+9 -1
View File
@@ -36,11 +36,19 @@ static struct rtems_bsdnet_ifconfig loopback_config = {
* application directory and make the appropriate changes.
*/
#if defined(__i386__)
extern int
rtems_ne2kpci_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach);
static struct rtems_bsdnet_ifconfig ne2k_driver_config = {
"ne2", /* name */
rtems_ne2kpci_driver_attach, /* attach function */
&loopback_config, /* link to next interface */
};
extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);
static struct rtems_bsdnet_ifconfig fxp_driver_config = {
"fxp1", /* name */
rtems_fxp_attach, /* attach function */
&loopback_config, /* link to next interface */
&ne2k_driver_config, /* link to next interface */
};
extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);
static struct rtems_bsdnet_ifconfig e3c509_driver_config = {
+7 -1
View File
@@ -27,7 +27,13 @@
* }
*/
#if defined(vxWorks) || defined(__rtems__)
#if defined(__rtems__)
#ifdef __cplusplus
#define MAIN(prog) extern "C" int prog(void); extern "C" int main() __attribute__((weak, alias(#prog))); extern "C" int prog(void)
#else
#define MAIN(prog) int prog(); int main() __attribute__((weak, alias(#prog))); int prog()
#endif
#elif defined(vxWorks)
#ifdef __cplusplus
#define MAIN(prog) extern "C" int prog(void)
#else
+11
View File
@@ -14,11 +14,18 @@ PROD_LIBS += Com
PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32
PROD_SYS_LIBS_solaris += socket nsl
PROD_SRCS_RTEMS += rtemsTestData.c
ifeq ($(EPICS_HOST_ARCH),$(T_A))
# skip except for host arch due to custom .plt
TESTPROD_HOST += epicsUnitTestTest
epicsUnitTestTest_SRCS += epicsUnitTestTest.c
# Not much point running this on vxWorks or RTEMS...
TESTS += epicsUnitTestTest
endif
TESTPROD_HOST += epicsTypesTest
epicsTypesTest_SRCS += epicsTypesTest.cpp
testHarness_SRCS += epicsTypesTest.cpp
@@ -237,6 +244,10 @@ TESTSPEC_vxWorks = libComTestHarness.munch; epicsRunLibComTests
TESTSPEC_RTEMS = libComTestHarness.boot; epicsRunLibComTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
TESTPROD_RTEMS = $(TESTPROD_HOST)
TESTSCRIPTS_RTEMS += $(filter-out epicsUnitTestTest.t, $(TESTS:%=%.t))
endif
# The following are not test programs, they measure performance.
+6
View File
@@ -0,0 +1,6 @@
#include "epicsMemFs.h"
/* no local files needed for these tests,
* so skip local FS setup
*/
const epicsMemFS *epicsRtemsFSImage = NULL;
+9
View File
@@ -62,6 +62,8 @@ testHarness_SRCS += epicsRunFilterTests.c
filterTestHarness_SRCS += $(testHarness_SRCS)
filterTestHarness_SRCS_RTEMS += rtemsTestHarness.c
PROD_SRCS_RTEMS += rtemsTestData.c
PROD_vxWorks = filterTestHarness
PROD_RTEMS = filterTestHarness
@@ -69,6 +71,10 @@ TESTSPEC_vxWorks = filterTestHarness.munch; epicsRunFilterTests
TESTSPEC_RTEMS = filterTestHarness.boot; epicsRunFilterTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
TESTPROD_RTEMS = $(TESTPROD_HOST)
TESTSCRIPTS_RTEMS += $(TESTS:%=%.t)
endif
include $(TOP)/configure/RULES
@@ -78,3 +84,6 @@ dbndTest$(DEP): $(COMMON_DIR)/xRecord.h
syncTest$(DEP): $(COMMON_DIR)/xRecord.h
arrRecord$(DEP): $(COMMON_DIR)/arrRecord.h
arrTest$(DEP): $(COMMON_DIR)/arrRecord.h
rtemsTestData.c : $(TESTFILES) $(TOOLS)/epicsMakeMemFs.pl
$(PERL) $(TOOLS)/epicsMakeMemFs.pl $@ epicsRtemsFSImage $(TESTFILES)
+9
View File
@@ -138,6 +138,8 @@ testHarness_SRCS += epicsRunRecordTests.c
recordTestHarness_SRCS += $(testHarness_SRCS)
recordTestHarness_SRCS_RTEMS += rtemsTestHarness.c
PROD_SRCS_RTEMS += rtemsTestData.c
PROD_vxWorks = recordTestHarness
PROD_RTEMS = recordTestHarness
@@ -145,5 +147,12 @@ TESTSPEC_vxWorks = recordTestHarness.munch; epicsRunRecordTests
TESTSPEC_RTEMS = recordTestHarness.boot; epicsRunRecordTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
TESTPROD_RTEMS = $(TESTPROD_HOST)
TESTSCRIPTS_RTEMS += $(TESTS:%=%.t)
endif
include $(TOP)/configure/RULES
rtemsTestData.c : $(TESTFILES) $(TOOLS)/epicsMakeMemFs.pl
$(PERL) $(TOOLS)/epicsMakeMemFs.pl $@ epicsRtemsFSImage $(TESTFILES)
+1
View File
@@ -51,6 +51,7 @@ PERL_SCRIPTS += mkmf.pl
PERL_SCRIPTS += munch.pl
PERL_SCRIPTS += replaceVAR.pl
PERL_SCRIPTS += tap-to-junit-xml.pl
PERL_SCRIPTS += epicsMakeMemFs.pl
PERL_SCRIPTS += useManifestTool.pl
PERL_SCRIPTS += genVersionHeader.pl
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env perl
#
use File::Basename;
use strict;
my $outfile = shift;
my $varname = shift;
open(my $DST, '>', $outfile) or die "Failed to open $outfile";
print $DST <<EOF;
#include <epicsMemFs.h>
EOF
my $N = 0;
for my $fname (@ARGV) {
print "<- $fname\n";
my $realfname = $fname;
# strip leading "../" "./" or "/"
while ($fname =~ /^\.*\/(.*)$/) { $fname = $1; }
my $file = basename($fname);
my @dirs = split('/', dirname($fname));
print $DST "/* begin $realfname */\nstatic const char * const file_${N}_dir[] = {";
for my $dpart (@dirs) {
print $DST "\"$dpart\", ";
}
print $DST "NULL};\nstatic const char file_${N}_data[] = {\n ";
open(my $SRC, '<', $realfname) or die "Failed to open $realfname";
binmode($SRC);
my $buf;
my $total = 0;
while (my $num = read($SRC, $buf, 32)) {
if($total != 0) {
print $DST ",\n ";
}
$total += $num;
my $out = join(",",map(ord,split(//,$buf)));
print $DST "$out";
}
close($SRC);
print $DST <<EOF;
};
static const epicsMemFile file_${N} = {
file_${N}_dir,
\"$file\",
file_${N}_data,
$total
};
/* end $realfname */
EOF
$N = $N + 1;
}
print $DST <<EOF;
static const epicsMemFile* files[] = {
EOF
$N = $N - 1;
for my $i (0..${N}) {
print $DST " &file_${i},";
}
print $DST <<EOF;
NULL
};
static
const epicsMemFS ${varname}_image = {&files[0]};
const epicsMemFS * $varname = &${varname}_image;
EOF
close($DST);
+29 -11
View File
@@ -15,18 +15,43 @@
# If the script is given an argument -tap it sets HARNESS_ACTIVE in the
# environment to make the epicsUnitTest code generate strict TAP output.
# Usage: makeTestfile.pl target.t executable
# Usage: makeTestfile.pl <target-arch> <host-arch> target.t executable
# target-arch and host-arch are EPICS build target names (eg. linux-x86)
# target.t is the name of the Perl script to generate
# executable is the name of the file the script runs
use strict;
my ($target, $exe) = @ARGV;
my ($TA, $HA, $target, $exe) = @ARGV;
my $exec;
# Use WINE to run windows target executables on non-windows host
if( $TA =~ /^win32-x86/ && $HA !~ /^win/ ) {
# new deb. derivatives have wine32 and wine64
# older have wine and wine64
# prefer wine32 if present
my $wine32 = "/usr/bin/wine32";
$wine32 = "/usr/bin/wine" if ! -x $wine32;
$exec = "$wine32 $exe";
} elsif( $TA =~ /^windows-x64/ && $HA !~ /^win/ ) {
$exec = "wine64 $exe";
# Run pc386 test harness w/ QEMU
} elsif( $TA =~ /^RTEMS-pc386-qemu$/ ) {
$exec = "qemu-system-i386 -m 64 -no-reboot -serial stdio -display none -net nic,model=ne2k_pci -net user,restrict=yes -kernel $exe";
# Explicitly fail for other RTEMS targets
} elsif( $TA =~ /^RTEMS-/ ) {
die "$0: I don't know how to create scripts for testing $TA on $HA\n";
} else {
$exec = "./$exe";
}
open(my $OUT, '>', $target) or die "Can't create $target: $!\n";
print $OUT <<EOF;
#!/usr/bin/perl
#!/usr/bin/env perl
use strict;
use Cwd 'abs_path';
@@ -34,14 +59,7 @@ use Cwd 'abs_path';
\$ENV{HARNESS_ACTIVE} = 1 if scalar \@ARGV && shift eq '-tap';
\$ENV{TOP} = abs_path(\$ENV{TOP}) if exists \$ENV{TOP};
if (\$^O eq 'MSWin32') {
# Use system on Windows, exec doesn't work the same there and
# GNUmake thinks the test has finished as soon as Perl exits.
system('./$exe') == 0 or die "Can't run $exe: \$!\\n";
}
else {
exec './$exe' or die "Can't run $exe: \$!\\n";
}
system('$exec') == 0 or die "Can't run $exec: \$!\\n";
EOF
close $OUT or die "Can't close $target: $!\n";