Enable Epics for RTEMS5 (posix)

This commit is contained in:
Heinz Junkes
2020-09-05 20:17:30 +02:00
committed by Brendan Chandler
parent 077b41e6c1
commit bba7d8c8f8
56 changed files with 2645 additions and 12 deletions

View File

@ -142,9 +142,10 @@ BUILDLIB_SUFFIX = $(BUILDLIB_SUFFIX_$(SHARED_LIBRARIES))
#--------------------------------------------------
# vpath directories
POSIX_YES = os/posix
OS_IMPL_DIRS = $(if $(OS_API),os/$(OS_CLASS)-$(OS_API),) os/$(OS_CLASS)
GENERIC_SRC_DIRS = .. $(SRC_DIRS)
OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \
$(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default ))
$(addprefix $(dir)/, $(OS_IMPL_DIRS) $(POSIX_$(POSIX)) os/default ))
CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \
$(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default ))
ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)
@ -306,7 +307,7 @@ LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS)\
CPPFLAGS = $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
$(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS)\
$(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS) $(API_CPPFLAGS)
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS)
#--------------------------------------------------
# ar definition default

View File

@ -33,7 +33,7 @@ RTEMS_BSP ?= $(subst RTEMS-,,$(T_A))
#-------------------------------------------------------
# Pick up the RTEMS tool/path definitions from the RTEMS BSP directory.
include $(RTEMS_BASE)/$(RTEMS_TARGET_CPU)-rtems$(RTEMS_VERSION)/$(RTEMS_BSP)/Makefile.inc
include $(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/$(RTEMS_BSP)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(CONFIG.CC)
@ -94,16 +94,46 @@ MODEXT=.obj
# operating system class (include/os/<os_class>)
OS_CLASS = RTEMS
#--------------------------------------------------
#print warning
ifeq ($(RTEMS_HAS_POSIX_API),no)
ifeq ($(EPICS_VERSION),7)
$(error Warning: Epics Version $(EPICS_VERSION) must not be used without POSIX enabled on RTEMS !!!)
endif
endif
# operating system API (src/os/<os_class>-<os-api>)
ifeq ($(RTEMS_HAS_POSIX_API),yes)
OS_API = posix
else
OS_API = kernel
endif
#--------------------------------------------------
# Operating system flags
OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm
OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \
#OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm
ifeq ($(RTEMS_API),5)
OP_SYS_CFLAGS += -D__LINUX_ERRNO_EXTENSIONS__
#OP_SYS_LDLIBS += -lrtemsCom -lrtemscpu -lrtemsbsp -ltftpfs -ltelnetd -lbsd -lz -lm
OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -ltftpfs -lbsd -lz -lm
else
OP_SYS_LDLIBS += -lrtemsCom -lrtemscpu -lrtemsbsp
endif
ifeq ($(RTEMS_HAS_NETWORKING),yes)
OP_SYS_CFLAGS += -DRTEMS_LEGACY_STACK
else
OP_SYS_CFLAGS += -DHAVE_SOCKADDR_SA_LEN=1
endif
OP_SYS_LDFLAGS_posix += -u POSIX_Init
OP_SYS_LDFLAGS_kernel += $(CPU_CFLAGS) -u Init \
$(PROJECT_RELEASE)/lib/no-dpmem.rel \
$(PROJECT_RELEASE)/lib/no-mp.rel \
$(PROJECT_RELEASE)/lib/no-part.rel \
$(PROJECT_RELEASE)/lib/no-signal.rel \
$(PROJECT_RELEASE)/lib/no-rtmon.rel
OP_SYS_LDFLAGS += $(CPU_CFLAGS) $(OP_SYS_LDFLAGS_$(OS_API))
MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib
# Do not link against libraries which are part of the Generic Image

View File

@ -0,0 +1,18 @@
#
# CONFIG.Common.RTEMS-beaglebineblack
# Author: Heinz Junkes <junkes@fhi-berlin.mpg.de>
#
# All RTEMS targets use the same Makefile fragment
#
#EXE = .elf
RTEMS_BSP = beagleboneblack
RTEMS_TARGET_CPU = arm
GNU_TARGET = arm-rtems
OP_SYS_LDLIBS += -Wl,--gc-sections
ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/beagleboneblack/lib/
include $(CONFIG)/os/CONFIG.Common.RTEMS

View File

@ -8,14 +8,18 @@ EXE = .elf
RTEMS_BSP = beatnik
RTEMS_TARGET_CPU = powerpc
GNU_TARGET = powerpc-rtems
ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
# optimization trouble in postfix.c
ARCH_DEP_CFLAGS += -DRTEMS_HAS_ALTIVEC
#will use bootp
#ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD
ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048
ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
OP_SYS_LDLIBS += -lbspExt
OP_SYS_LDLIBS += -lbspExt #does not use posix stuff ... want to ignore
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@
endef

View File

@ -6,6 +6,7 @@
#-------------------------------------------------------
# Include definitions from RTEMS-pc386
include $(CONFIG)/os/CONFIG.Common.RTEMS-pc386
# For Tests overwrite it with pc686
include $(CONFIG)/os/CONFIG.Common.RTEMS-pc686
RTEMS_QEMU_FIXUPS = YES

View File

@ -0,0 +1,25 @@
#
# Author: W. Eric Norum
# Canadian Light Source
# eric@cls.usask.ca
#
# All RTEMS targets use the same Makefile fragment
#
RTEMS_BSP = pc686
RTEMS_TARGET_CPU = i386
GNU_TARGET = i386-rtems
MUNCH_SUFFIX = .boot
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@
endef
OP_SYS_LDLIBS += -Wl,--gc-sections
ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/pc686/lib/
include $(CONFIG)/os/CONFIG.Common.RTEMS
#
# Put text segment where it will work with etherboot
#
OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000

View File

@ -0,0 +1,48 @@
#
# CONFIG.Common.RTEMS-qoriq_e500
# Author: Heinz Junkes <junkes@fhi-berlin.mpg.de>
#
# All RTEMS targets use the same Makefile fragment
#
EXE = .elf
RTEMS_BSP = qoriq_e500
RTEMS_TARGET_CPU = powerpc
GNU_TARGET = powerpc-rtems
# optimization trouble in postfix.c
#ARCH_DEP_CFLAGS += -DRTEMS_HAS_ALTIVEC
#will use bootp
#ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048
#ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
#netbsdlib
#ARCH_DEP_CFLAGS += -I$(RTEMS_BASE)/powerpc-rtems5/qoriq_e500/lib/include
#OP_SYS_LDLIBS += -lbspExt #does not use posix stuff ... want to ignore
OP_SYS_LDLIBS += -Wl,--gc-sections
#ARCH_DEP_LDFLAGS = -mcpu=8540 -meabi -msdata=sysv -mstrict-align -mspe -mabi=spe -mfloat-gprs=double
ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/powerpc-rtems5/qoriq_e500/lib
MUNCH_SUFFIX = .img
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@
gzip -9 -f $@
mkimage -A ppc -O linux -T kernel -a 0x4000 -e 0x4000 -n $* -d $@.gz $*.img
endef
include $(CONFIG)/os/CONFIG.Common.RTEMS
RTEMSSYMS=$(PRODNAME:%$(EXE)=%.sym)
RTEMSIMGS=$(PRODNAME:%$(EXE)=%.bin)
INSTALL_RTEMSSYMS=$(RTEMSSYMS:%=$(INSTALL_BIN)/%)
INSTALL_RTEMSIMGS=$(RTEMSIMGS:%=$(INSTALL_BIN)/%)
%.sym: %$(EXE)
$(XSYMS) $^ $@
%.bin: %$(EXE)
$(OBJCOPY) -Obinary $^ $@
#PRODTARGETS+=$(INSTALL_RTEMSSYMS) $(INSTALL_RTEMSIMGS)

View File

@ -0,0 +1,20 @@
#
# CONFIG.Common.RTEMS-xilinx_zynq_a9_qemu
# Author: Heinz Junkes <junkes@fhi-berlin.mpg.de>
#
# All RTEMS targets use the same Makefile fragment
#
#EXE = .elf
RTEMS_BSP = xilinx_zynq_a9_qemu
RTEMS_TARGET_CPU = arm
GNU_TARGET = arm-rtems
#use dhcp/bootp
ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
OP_SYS_LDLIBS += -Wl,--gc-sections
ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/xilinx_zynq_a9_qemu/lib/
include $(CONFIG)/os/CONFIG.Common.RTEMS

View File

@ -0,0 +1,19 @@
#
# CONFIG.Common.RTEMS-xilinx_zynq_zedboard
# Author: Heinz Junkes <junkes@fhi-berlin.mpg.de>
#
# All RTEMS targets use the same Makefile fragment
#
#EXE = .elf
RTEMS_BSP = xilinx_zynq_zedboard
RTEMS_TARGET_CPU = arm
GNU_TARGET = arm-rtems
OP_SYS_LDLIBS += -Wl,--gc-sections
ARCH_DEP_LDFLAGS = -L$(RTEMS_BASE)/$(GNU_TARGET)$(RTEMS_VERSION)/xilinx_zynq_zedboard/lib/
include $(CONFIG)/os/CONFIG.Common.RTEMS

View File

@ -3,6 +3,7 @@
# Definitions for darwin-x86 host builds
# Sites may override these definitions in CONFIG_SITE.darwin-x86.Common
#-------------------------------------------------------
#support for IPv6 etc.
OP_SYS_CFLAGS += -DHAVE_SOCKADDR_SA_LEN=1
#Include definitions common to unix hosts
include $(CONFIG)/os/CONFIG.UnixCommon.Common

View File

@ -5,9 +5,9 @@
# Where to find RTEMS
#
# APS:
RTEMS_VERSION = 4.10.2
RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION)
# FHI:
RTEMS_VERSION = 5
RTEMS_BASE = /home/travis/.rtems
# Cross-compile toolchain in $(RTEMS_TOOLS)/bin
#

View File

@ -71,6 +71,23 @@ This also fixes [lauchpad bug #1714455](https://bugs.launchpad.net/bugs/1714455)
These changes are to more closely follow the JSON5 standard, which doesn't
support octal character escapes or the `\a` (Bel, `\x07`) escape sequence.
### Support for RTEMS 5
The new major release of the RTEMS real-time OS contains many changes including
the ability to support SMP systems. The earlier EPICS support for RTEMS made use
of various RTEMS-specific kernel APIs which cannot be used on an SMP system, so
the changes here required acompletely new port to the Posix real-time APIs that
RTEMS-5 now recommends.
A new RTEMS configuration variable RTEMS_SERIES has been added which should be
set to the first two components of the OS version number, e.g. 4.9. When this
is 4.12 or greater, true for 5.0 as well, the new libCom/osi/os/RTEMS-posix
source files will be used; the older API source files can now be found in
libCom/osi/os/RTEMS-kernel, and those which are common to both installations are
in libCom/osi/os/RTEMS. The compiler options are read from the Makefile.inc of
the corresponding BSP and set in the configuration files. It checks that the BSP
was also built with the --enable-posix option. It also checks if the BSP was built
with the legacy stack or libbsd.
### Filters in database input links
Input database links can now use channel filters, it is not necessary to

View File

@ -11,22 +11,31 @@ TOP = ../../..
include $(TOP)/configure/CONFIG
include $(TOP)/configure/CONFIG_LIBCOM_VERSION
# check check
SRC_DIRS += ../$(OS_API)
PERL_SCRIPTS += epicsMakeMemFs.pl
INC += epicsRtemsInitHooks.h
INC += epicsMemFs.h
INC += epicsNtp.h
ifeq ($(RTEMS_QEMU_FIXUPS),YES)
rtems_init_CPPFLAGS += -DQEMU_FIXUPS
endif
rtemsCom_SRCS += rtems_init.c
rtemsCom_SRCS += rtems_config.c
ifeq ($(RTEMS_HAS_NETWORKING), yes)
rtemsCom_SRCS += rtems_netconfig.c
else
rtemsCom_SRCS += libbsd_netconfig.c
endif
rtemsCom_SRCS += rtems_util.c
rtemsCom_SRCS += setBootConfigFromNVRAM.c
rtemsCom_SRCS += epicsRtemsInitHookPre.c
rtemsCom_SRCS += epicsRtemsInitHookPost.c
rtemsCom_SRCS += epicsMemFs.c
rtemsCom_SRCS += epicsNtp.c
ifeq ($(RTEMS_BSP),pc386)
rtemsCom_SRCS += ne2kpci.c

View File

@ -0,0 +1,85 @@
/*************************************************************************\
* (C) 2014 David Lettier.
* http://www.lettier.com/
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <rtems.h>
#include "epicsNtp.h"
int epicsNtpGetTime(char *ntpIp, struct timespec *now)
{
int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket.
int portno = 123; // NTP UDP port number.
// Create and zero out the packet. All 48 bytes worth.
ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
memset( &packet, 0, sizeof( ntp_packet ) );
// Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero.
*( ( char * ) &packet + 0 ) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.
// Create a UDP socket, convert the host-name to an IP address, set the port number,
// connect to the server, send the packet, and then read in the return packet.
struct sockaddr_in serv_addr; // Server address data structure.
sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // Create a UDP socket.
if ( sockfd < 0 ) {
perror( "epicsNtpGetTime" );
return -1;
}
// Zero out the server address structure.
bzero( ( char* ) &serv_addr, sizeof( serv_addr ) );
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(ntpIp);
serv_addr.sin_port = htons( portno );
// Call up the server using its IP address and port number.
if ( connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 ) {
perror( "epicsNtpGetTime" );
return -1;
}
// Send it the NTP packet it wants. If n == -1, it failed.
n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
if ( n < 0 ) {
perror( "epicsNtpGetTime" );
return -1;
}
// Wait and receive the packet back from the server. If n == -1, it failed.
n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
if ( n < 0 ) {
perror( "epicsNtpGetTime" );
return -1;
}
// These two fields contain the time-stamp seconds as the packet left the NTP server.
// The number of seconds correspond to the seconds passed since 1900.
// ntohl() converts the bit/byte order from the network's to host's "endianness".
packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds.
packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second.
// Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server.
// Subtract 70 years worth of seconds from the seconds since 1900.
// This leaves the seconds since the UNIX epoch of 1970.
// (1900)------------------(1970)**************************************(Time Packet Left the Server)
time_t txTm = ( time_t ) ( packet.txTm_s - NTP_TIMESTAMP_DELTA );
now->tv_sec = txTm;
return 0;
}

View File

@ -0,0 +1,43 @@
/*************************************************************************\
* (C) 2014 David Lettier.
* http://www.lettier.com/
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#ifndef EPICSNTP_H
#define EPICSNTP_H
#define NTP_TIMESTAMP_DELTA 2208988800ull
int epicsNtpGetTime(char *ntpIp, struct timespec *now);
typedef struct
{
uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t stratum; // Eight bits. Stratum level of the local clock.
uint8_t poll; // Eight bits. Maximum interval between successive messages.
uint8_t precision; // Eight bits. Precision of the local clock.
uint32_t rootDelay; // 32 bits. Total round trip delay time.
uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
uint32_t refId; // 32 bits. Reference clock identifier.
uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
uint32_t origTm_s; // 32 bits. Originate time-stamp seconds.
uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second.
uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
} ntp_packet; // Total: 384 bits or 48 bytes.
#endif // EPICSNTP_H

View File

@ -0,0 +1,18 @@
/*************************************************************************\
* Copyright (c) 2006 The University of Chicago, as Operator of Argonne
* National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Dummy version -- use if application does not provide its own version
*/
#include "epicsRtemsInitHooks.h"
int
epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config)
{
return 0;
}

View File

@ -0,0 +1,18 @@
/*************************************************************************\
* Copyright (c) 2006 The University of Chicago, as Operator of Argonne
* National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Dummy version -- use if application does not provide its own version
*/
#include "epicsRtemsInitHooks.h"
int
epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config)
{
return 0;
}

View File

@ -0,0 +1,24 @@
/*************************************************************************\
* Copyright (c) 2006 The University of Chicago, as Operator of Argonne
* National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Hooks into RTEMS startup code
*/
#include <bsp.h>
extern char *env_nfsServer;
extern char *env_nfsPath;
extern char *env_nfsMountPoint;
/*
* Return 0 for success, non-zero for failure (will cause panic)
*/
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);

View File

@ -0,0 +1,116 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* RTEMS network configuration for EPICS
* Author: W. Eric Norum
* eric.norum@usask.ca
* (306) 966-5394
*
* This file can be copied to an application source dirctory
* and modified to override the values shown below.
*/
#include <sys/param.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <unistd.h>
#include <bsp.h>
#include <machine/rtems-bsd-commands.h>
#include <machine/rtems-bsd-rc-conf.h>
#include <machine/rtems-bsd-rc-conf-services.h>
#include "libbsd_netconfig.h"
#include <rtems/console.h>
#include <rtems/shell.h>
#define IFACE_IPV4_DHCP(iface) \
"ifconfig_" # iface "=\"SYNCDHCP\"\n"
#define IFACE_IPV4(iface, addr) \
"ifconfig_" # iface "=\"inet " # addr " netmask 255.255.255.0\"\n"
static const char* rc_conf_text = \
"\n" \
"syslog_priority=\"debug\"\n" \
"\n" \
"#create_args_myvlan=\"vlan 102\"\n" \
"#create_args_yourvlan=\"vlan 202\"\n" \
IFACE_IPV4_DHCP(cgem0) \
"\n" \
"dhcpcd_priority=\"100\"\n" \
"\n" \
"#defaultrouter=\"" NET_CFG_GATEWAY_IP "\"\n" \
"defaultroute_delay=\"5\"\n" \
"\n" \
"#telnetd_enable=\"YES\"\n" \
"#telnetd_options=\"-C 2 -P 100 \"\n" \
"\n" \
"#ftpd_enable=\"YES\"\n" \
"#ftpd_options=\"-v -p 21 -C 2 -P 150 -L -I 10 -R /\"\n" \
"\n" \
"#pf_enable=\"YES\"\n" \
"#pf_rules=\"/etc/mypf.conf\"\n" \
"#pf_flags=\"-q -z\"\n" \
"\n";
static const char* dhcpcd_conf_text = \
"\n" \
"clientid RTEMS test client\n" \
"\n" \
"nodhcp6\n" \
"ipv4only\n" \
"option ntp_servers\n" \
"option rtems_cmdline\n";
int
epicsRtemsPrepareAndRunRCConfFile(void)
{
size_t len;
size_t written;
int fd;
int rv;
struct stat sb;
mkdir("/etc", S_IRWXU | S_IRWXG | S_IRWXO); /* ignore errors, check the dir after. */
assert(stat("/etc", &sb) == 0);
assert(S_ISDIR(sb.st_mode));
printf("--------------- dhcpcd.conf -----------------\n");
printf(dhcpcd_conf_text);
printf("-----------------------------------------\n");
len = strlen(dhcpcd_conf_text);
fd = open("/etc/dhcpcd.conf", O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
assert(fd != -1);
written = write(fd, dhcpcd_conf_text, len);
assert(written == len);
rv = close(fd);
assert(rv == 0);
printf("--------------- rc.conf -----------------\n");
printf(rc_conf_text);
printf("-----------------------------------------\n");
len = strlen(rc_conf_text);
fd = open("/etc/rc.conf", O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
assert(fd != -1);
written = write(fd, rc_conf_text, len);
assert(written == len);
rv = close(fd);
assert(rv == 0);
return (rtems_bsd_run_etc_rc_conf(20, true));
}

View File

@ -0,0 +1,24 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* RTEMS network configuration header for EPICS
*
* This file can be copied to an application source dirctory
* and modified to override the values shown below.
*/
#include <stdio.h>
#include <bsp.h>
#define NET_CFG_INTERFACE_0 "cgem0"
#define DEFAULT_NETWORK_DHCPCD_ENABLE
#define DEFAULT_NETWORK_NO_INTERFACE_0
// Tests
#define NET_CFG_SELF_IP "141.14.128.89"
#define NET_CFG_NETMASK "255.255.240.0"
#define NET_CFG_GATEWAY_IP "141.14.128.128"
int epicsRtemsPrepareAndRunRCConfFile(void);

View File

@ -0,0 +1,153 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* RTEMS configuration for EPICS
* Author: W. Eric Norum
* norume@aps.anl.gov
* (630) 252-4793
*/
#include <rtems.h>
/*
***********************************************************************
* RTEMS CONFIGURATION *
***********************************************************************
*/
extern void *POSIX_Init(void *argument);
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT POSIX_Init
#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (64*1024)
#define CONFIGURE_MAXIMUM_PERIODS 5
#define CONFIGURE_MICROSECONDS_PER_TICK 10000
#define CONFIGURE_MALLOC_STATISTICS 1
/* MINIMUM_STACK_SIZE == 8K */
#define CONFIGURE_EXTRA_TASK_STACKS (4000 * RTEMS_MINIMUM_STACK_SIZE)
#define CONFIGURE_FILESYSTEM_DEVFS
#define CONFIGURE_FILESYSTEM_TFTPFS
#define CONFIGURE_FILESYSTEM_NFS
#define CONFIGURE_FILESYSTEM_IMFS
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
/*
* Configure LibBSD.
*/
#define RTEMS_BSD_CONFIG_NET_PF_UNIX
#define RTEMS_BSD_CONFIG_NET_IF_BRIDGE
#define RTEMS_BSD_CONFIG_NET_IF_LAGG
#define RTEMS_BSD_CONFIG_NET_IF_VLAN
#define RTEMS_BSD_CONFIG_BSP_CONFIG
#define RTEMS_BSD_CONFIG_INIT
#include <machine/rtems-bsd-config.h>
/*
* Configure RTEMS.
*/
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 150
#define CONFIGURE_IMFS_ENABLE_MKFIFO 2
#define CONFIGURE_MAXIMUM_NFS_MOUNTS 3
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 5
#define CONFIGURE_UNLIMITED_ALLOCATION_SIZE 32
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
#define CONFIGURE_STACK_CHECKER_ENABLED
#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
#define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS 4
#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (1 * 1024 * 1024)
/* we are using POSIX_INIT
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
*/
//#define RTEMS_PCI_CONFIG_LIB
//#define CONFIGURE_PCI_LIB PCI_LIB_AUTO
#define CONFIGURE_SHELL_COMMANDS_INIT
#include <bsp/irq-info.h>
#include <rtems/netcmds-config.h>
#define CONFIGURE_SHELL_USER_COMMANDS \
&bsp_interrupt_shell_command, \
&rtems_shell_HOSTNAME_Command, \
&rtems_shell_PING_Command, \
&rtems_shell_ROUTE_Command, \
&rtems_shell_NETSTAT_Command, \
&rtems_shell_IFCONFIG_Command, \
&rtems_shell_TCPDUMP_Command, \
&rtems_shell_PFCTL_Command, \
&rtems_shell_SYSCTL_Command
#define CONFIGURE_SHELL_COMMAND_CPUUSE
#define CONFIGURE_SHELL_COMMAND_PERIODUSE
#define CONFIGURE_SHELL_COMMAND_STACKUSE
#define CONFIGURE_SHELL_COMMAND_PROFREPORT
#define CONFIGURE_SHELL_COMMAND_CP
#define CONFIGURE_SHELL_COMMAND_PWD
#define CONFIGURE_SHELL_COMMAND_LS
#define CONFIGURE_SHELL_COMMAND_LN
#define CONFIGURE_SHELL_COMMAND_LSOF
#define CONFIGURE_SHELL_COMMAND_CHDIR
#define CONFIGURE_SHELL_COMMAND_CD
#define CONFIGURE_SHELL_COMMAND_MKDIR
#define CONFIGURE_SHELL_COMMAND_RMDIR
#define CONFIGURE_SHELL_COMMAND_CAT
#define CONFIGURE_SHELL_COMMAND_MV
#define CONFIGURE_SHELL_COMMAND_RM
#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
#define CONFIGURE_SHELL_COMMAND_SHUTDOWN
#include <rtems/shellconfig.h>
#define RTEMS_BSD_CONFIG_BSP_CONFIG
#define RTEMS_BSD_CONFIG_SERVICE_TELNETD
#define RTEMS_BSD_CONFIG_TELNETD_STACK_SIZE (16 * 1024)
#define RTEMS_BSD_CONFIG_SERVICE_FTPD
#define RTEMS_BSD_CONFIG_FIREWALL_PF
#define CONFIGURE_MAXIMUM_DRIVERS 40
/*
* This should be made BSP dependent, not CPU dependent but I know of no
* appropriate conditionals to use.
* The new general time support makes including the RTC driver less important.
*/
#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && \
!defined(mpc7455) && !defined(__arm__) && !defined(__nios2__)
/* don't have RTC code */
#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
#endif
#if defined(LIBBSP_I386_PC386_BSP_H)
#define RTEMS_BSD_CONFIG_DOMAIN_PAGE_MBUFS_SIZE (64 * 1024 * 1024)
#elif defined(LIBBSP_POWERPC_QORIQ_BSP_H)
#define RTEMS_BSD_CONFIG_DOMAIN_PAGE_MBUFS_SIZE (32 * 1024 * 1024)
#endif
#define CONFIGURE_INIT
#include <rtems/confdefs.h>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,369 @@
/*************************************************************************\
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <bsp.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <epicsStdlib.h>
#include <epicsStdio.h>
#include <epicsString.h>
#include <envDefs.h>
char *env_nfsServer;
char *env_nfsPath;
char *env_nfsMountPoint;
/*
* Split argument string of form nfs_server:nfs_export:<path>
* The nfs_export component will be used as:
* - the path to the directory exported from the NFS server
* - the local mount point
* - a prefix of <path>
* For example, the argument string:
* romeo:/export/users:smith/ioc/iocexample/st.cmd
* would:
* - mount /export/users from NFS server romeo on /export/users
* - chdir to /export/users/smith/ioc/iocexample
* - read commands from st.cmd
*/
static void
splitRtemsBsdnetBootpCmdline(void)
{
char *cp1, *cp2, *cp3;
if ((cp1 = rtems_bsdnet_bootp_cmdline) == NULL)
return;
if (((cp2 = strchr(cp1, ':')) != NULL)
&& (((cp3 = strchr(cp2+1, ' ')) != NULL)
|| ((cp3 = strchr(cp2+1, ':')) != NULL))) {
int l1 = cp2 - cp1;
int l2 = cp3 - cp2 - 1;
int l3 = strlen(cp3) - 1;
if (l1 && l2 && l3) {
*cp2++ = '\0';
*cp3 = '\0';
env_nfsServer = cp1;
env_nfsMountPoint = env_nfsPath = epicsStrDup(cp2);
*cp3 = '/';
rtems_bsdnet_bootp_cmdline = cp2;
}
}
}
/*
* Split NFS mount information of the form nfs_server:host_path:local_path
*/
static void
splitNfsMountPath(char *nfsString)
{
char *cp2, *cp3;
if (nfsString == NULL)
return;
if (((cp2 = strchr(nfsString, ':')) != NULL)
&& (((cp3 = strchr(cp2+1, ' ')) != NULL)
|| ((cp3 = strchr(cp2+1, ':')) != NULL))) {
int l1 = cp2 - nfsString;
int l2 = cp3 - cp2 - 1;
int l3 = strlen(cp3) - 1;
if (l1 && l2 && l3) {
*cp2++ = '\0';
*cp3++ = '\0';
env_nfsServer = nfsString;
env_nfsPath = cp2;
env_nfsMountPoint = cp3;
}
}
}
#if defined(HAVE_MOTLOAD)
/*
* Motorola MOTLOAD NVRAM Access
*/
static char *
gev(const char *parm, volatile char *nvp)
{
const char *val;
const char *name;
char *ret;
char c;
for (;;) {
if (*nvp == '\0')
return NULL;
name = parm;
while ((c = *nvp++) != '\0') {
if ((c == '=') && (*name == '\0')) {
val = (char *)nvp;
while (*nvp++ != '\0')
continue;
ret = malloc(nvp - val);
if (ret == NULL)
return NULL;
strcpy(ret, val);
return ret;
}
if (c != *name++) {
while (*nvp++ != '\0')
continue;
break;
}
}
}
}
static char *
motScriptParm(const char *mot_script_boot, char parm)
{
const char *cp;
char *ret;
int l;
while (*mot_script_boot != '\0') {
if (isspace(*(unsigned char *)mot_script_boot)
&& (*(mot_script_boot+1) == '-')
&& (*(mot_script_boot+2) == parm)) {
mot_script_boot += 3;
cp = mot_script_boot;
while ((*mot_script_boot != '\0') &&
!isspace(*(unsigned char *)mot_script_boot))
mot_script_boot++;
l = mot_script_boot - cp;
ret = malloc(l+1);
if (ret == NULL)
return NULL;
strncpy(ret, cp, l);
*(ret+l) = '\0';
return ret;
}
mot_script_boot++;
}
return NULL;
}
void
setBootConfigFromNVRAM(void)
{
char *cp;
const char *mot_script_boot;
char *nvp;
# if defined(BSP_NVRAM_BASE_ADDR)
nvp = (volatile unsigned char *)(BSP_NVRAM_BASE_ADDR+0x70f8);
# elif defined(BSP_I2C_VPD_EEPROM_DEV_NAME)
char gev_buf[3592];
int fd;
if ((fd = open(BSP_I2C_VPD_EEPROM_DEV_NAME, 0)) < 0) {
printf("Can't open %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno));
return;
}
lseek(fd, 0x10f8, SEEK_SET);
if (read(fd, gev_buf, sizeof gev_buf) != sizeof gev_buf) {
printf("Can't read %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno));
return;
}
close(fd);
nvp = gev_buf;
# else
# error "No way to read GEV!"
# endif
if (rtems_bsdnet_config.bootp != NULL)
return;
mot_script_boot = gev("mot-script-boot", nvp);
if ((rtems_bsdnet_bootp_server_name = gev("mot-/dev/enet0-sipa", nvp)) == NULL)
rtems_bsdnet_bootp_server_name = motScriptParm(mot_script_boot, 's');
if ((rtems_bsdnet_config.gateway = gev("mot-/dev/enet0-gipa", nvp)) == NULL)
rtems_bsdnet_config.gateway = motScriptParm(mot_script_boot, 'g');
if ((rtems_bsdnet_config.ifconfig->ip_netmask = gev("mot-/dev/enet0-snma", nvp)) == NULL)
rtems_bsdnet_config.ifconfig->ip_netmask = motScriptParm(mot_script_boot, 'm');
rtems_bsdnet_config.name_server[0] = gev("rtems-dns-server", nvp);
if (rtems_bsdnet_config.name_server[0] == NULL)
rtems_bsdnet_config.name_server[0] = rtems_bsdnet_bootp_server_name;
cp = gev("rtems-dns-domainname", nvp);
if (cp)
rtems_bsdnet_config.domainname = cp;
if ((rtems_bsdnet_config.ifconfig->ip_address = gev("mot-/dev/enet0-cipa", nvp)) == NULL)
rtems_bsdnet_config.ifconfig->ip_address = motScriptParm(mot_script_boot, 'c');
rtems_bsdnet_config.hostname = gev("rtems-client-name", nvp);
if (rtems_bsdnet_config.hostname == NULL)
rtems_bsdnet_config.hostname = rtems_bsdnet_config.ifconfig->ip_address;
if ((rtems_bsdnet_bootp_boot_file_name = gev("mot-/dev/enet0-file", nvp)) == NULL)
rtems_bsdnet_bootp_boot_file_name = motScriptParm(mot_script_boot, 'f');
rtems_bsdnet_bootp_cmdline = gev("epics-script", nvp);
splitRtemsBsdnetBootpCmdline();
splitNfsMountPath(gev("epics-nfsmount", nvp));
rtems_bsdnet_config.ntp_server[0] = gev("epics-ntpserver", nvp);
if (rtems_bsdnet_config.ntp_server[0] == NULL)
rtems_bsdnet_config.ntp_server[0] = rtems_bsdnet_bootp_server_name;
if ((cp = gev("epics-tz", nvp)) != NULL)
epicsEnvSet("TZ", cp);
}
#elif defined(HAVE_PPCBUG)
/*
* Motorola PPCBUG NVRAM Access
*/
struct ppcbug_nvram {
uint32_t PacketVersionIdentifier;
uint32_t NodeControlMemoryAddress;
uint32_t BootFileLoadAddress;
uint32_t BootFileExecutionAddress;
uint32_t BootFileExecutionDelay;
uint32_t BootFileLength;
uint32_t BootFileByteOffset;
uint32_t TraceBufferAddress;
uint32_t ClientIPAddress;
uint32_t ServerIPAddress;
uint32_t SubnetIPAddressMask;
uint32_t BroadcastIPAddressMask;
uint32_t GatewayIPAddress;
uint8_t BootpRarpRetry;
uint8_t TftpRarpRetry;
uint8_t BootpRarpControl;
uint8_t UpdateControl;
char BootFilenameString[64];
char ArgumentFilenameString[64];
};
static char *addr(char *cbuf, uint32_t addr)
{
struct in_addr a;
if ((a.s_addr = addr) == 0)
return NULL;
return (char *)inet_ntop(AF_INET, &a, cbuf, INET_ADDRSTRLEN);
}
void
setBootConfigFromNVRAM(void)
{
static struct ppcbug_nvram nvram;
static char ip_address[INET_ADDRSTRLEN];
static char ip_netmask[INET_ADDRSTRLEN];
static char server[INET_ADDRSTRLEN];
static char gateway[INET_ADDRSTRLEN];
if (rtems_bsdnet_config.bootp != NULL)
return;
/*
* Get network configuation from PPCBUG.
* The 'correct' way to do this would be to issue a .NETCFIG PPCBUG
* system call. Unfortunately it is very difficult to issue such a
* call once RTEMS is up and running so we just copy from the 'known'
* location of the network configuration parameters.
* Care must be taken to access the NVRAM a byte at a time.
*/
#if defined(NVRAM_INDIRECT)
{
volatile char *addrLo = (volatile char *)0x80000074;
volatile char *addrHi = (volatile char *)0x80000075;
volatile char *data = (volatile char *)0x80000077;
int addr = 0x1000;
char *d = (char *)&nvram;
while (d < ((char *)&nvram + sizeof nvram)) {
*addrLo = addr & 0xFF;
*addrHi = (addr >> 8) & 0xFF;
*d++ = *data;
addr++;
}
}
#else
{
volatile char *s = (volatile char *)0xFFE81000;
char *d = (char *)&nvram;
while (d < ((char *)&nvram + sizeof nvram))
*d++ = *s++;
}
#endif
/*
* Assume that the boot server is also the name, log and ntp server!
*/
rtems_bsdnet_config.name_server[0] =
rtems_bsdnet_config.ntp_server[0] =
rtems_bsdnet_bootp_server_name = addr(server, nvram.ServerIPAddress);
rtems_bsdnet_bootp_server_address.s_addr = nvram.ServerIPAddress;
/*
* Nothing better to use as host name!
*/
rtems_bsdnet_config.ifconfig->ip_address =
rtems_bsdnet_config.hostname = addr(ip_address, nvram.ClientIPAddress);
rtems_bsdnet_config.gateway = addr(gateway, nvram.GatewayIPAddress);
rtems_bsdnet_config.ifconfig->ip_netmask = addr(ip_netmask, nvram.SubnetIPAddressMask);
rtems_bsdnet_bootp_boot_file_name = nvram.BootFilenameString;
rtems_bsdnet_bootp_cmdline = nvram.ArgumentFilenameString;
splitRtemsBsdnetBootpCmdline();
}
#elif defined(__mcf528x__)
static char *
env(const char *parm, const char *defaultValue)
{
const char *cp = bsp_getbenv(parm);
if (!cp) {
if (!defaultValue)
return NULL;
cp = defaultValue;
printf ("%s environment variable missing -- using %s.\n", parm, cp);
}
return epicsStrDup(cp);
}
void
setBootConfigFromNVRAM(void)
{
const char *cp1;
if (rtems_bsdnet_config.bootp != NULL)
return;
rtems_bsdnet_config.gateway = env("GATEWAY", NULL);
rtems_bsdnet_config.ifconfig->ip_netmask = env("NETMASK", "255.255.252.0");
rtems_bsdnet_bootp_server_name = env("SERVER", "192.168.0.1");
rtems_bsdnet_config.name_server[0] = env("NAMESERVER", rtems_bsdnet_bootp_server_name);
rtems_bsdnet_config.ntp_server[0] = env("NTPSERVER", rtems_bsdnet_bootp_server_name);
cp1 = env("DOMAIN", NULL);
if (cp1 != NULL)
rtems_bsdnet_config.domainname = cp1;
rtems_bsdnet_config.hostname = env("HOSTNAME", "iocNobody");
rtems_bsdnet_config.ifconfig->ip_address = env("IPADDR0", "192.168.0.2");
rtems_bsdnet_bootp_boot_file_name = env("BOOTFILE", "uC5282App.boot");
rtems_bsdnet_bootp_cmdline = env("CMDLINE", "epics/iocBoot/iocNobody/st.cmd");
splitNfsMountPath(env("NFSMOUNT", NULL));
if ((cp1 = env("TZ", NULL)) != NULL)
epicsEnvSet("TZ", cp1);
}
#else
/*
* Placeholder for systems without NVRAM
*/
void
setBootConfigFromNVRAM(void)
{
printf("SYSTEM HAS NO NON-VOLATILE RAM!\n");
printf("YOU MUST USE SOME OTHER METHOD TO OBTAIN NETWORK CONFIGURATION\n");
}
#endif

View File

@ -0,0 +1,251 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume@aps.anl.gov
* 630 252 4793
*/
/*
* We want to access information which is
* normally hidden from application programs.
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
#define epicsExportSharedSymbols
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsMessageQueue.h"
#include "errlog.h"
LIBCOM_API epicsMessageQueueId epicsStdCall
epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
{
rtems_status_code sc;
epicsMessageQueueId id = calloc(1, sizeof(*id));
rtems_interrupt_level level;
static char c1 = 'a';
static char c2 = 'a';
static char c3 = 'a';
if(!id)
return NULL;
sc = rtems_message_queue_create (rtems_build_name ('Q', c3, c2, c1),
capacity,
maximumMessageSize,
RTEMS_FIFO|RTEMS_LOCAL,
&id->id);
if (sc != RTEMS_SUCCESSFUL) {
free(id);
errlogPrintf ("Can't create message queue: %s\n", rtems_status_text (sc));
return NULL;
}
id->maxSize = maximumMessageSize;
id->localBuf = NULL;
rtems_interrupt_disable (level);
if (c1 == 'z') {
if (c2 == 'z') {
if (c3 == 'z') {
c3 = 'a';
}
else {
c3++;
}
c2 = 'a';
}
else {
c2++;
}
c1 = 'a';
}
else {
c1++;
}
rtems_interrupt_enable (level);
return id;
}
static rtems_status_code rtems_message_queue_send_timeout(
rtems_id id,
void *buffer,
uint32_t size,
rtems_interval timeout)
{
Message_queue_Control *the_message_queue;
Objects_Locations location;
CORE_message_queue_Status msg_status;
the_message_queue = _Message_queue_Get( id, &location );
switch ( location )
{
case OBJECTS_ERROR:
return RTEMS_INVALID_ID;
case OBJECTS_LOCAL:
msg_status = _CORE_message_queue_Send(
&the_message_queue->message_queue,
buffer,
size,
id,
NULL,
1,
timeout
);
_Thread_Enable_dispatch();
/*
* If we had to block, then this is where the task returns
* after it wakes up. The returned status is correct for
* non-blocking operations but if we blocked, then we need
* to look at the status in our TCB.
*/
if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT )
msg_status = _Thread_Executing->Wait.return_code;
return _Message_queue_Translate_core_message_queue_return_code( msg_status );
}
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
}
LIBCOM_API int epicsStdCall epicsMessageQueueSend(
epicsMessageQueueId id,
void *message,
unsigned int messageSize)
{
if (rtems_message_queue_send_timeout(id->id, message, messageSize, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)
return 0;
else
return -1;
}
LIBCOM_API int epicsStdCall epicsMessageQueueSendWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int messageSize,
double timeout)
{
rtems_interval delay;
extern double rtemsTicksPerSecond_double;
/*
* Convert time to ticks
*/
if (timeout <= 0.0)
return epicsMessageQueueTrySend(id, message, messageSize);
delay = (int)(timeout * rtemsTicksPerSecond_double);
if (delay == 0)
delay++;
if (rtems_message_queue_send_timeout(id->id, message, messageSize, delay) == RTEMS_SUCCESSFUL)
return 0;
else
return -1;
}
static int receiveMessage(
epicsMessageQueueId id,
void *buffer,
uint32_t size,
uint32_t wait,
rtems_interval delay)
{
size_t rsize;
rtems_status_code sc;
if (size < id->maxSize) {
if (id->localBuf == NULL) {
id->localBuf = malloc(id->maxSize);
if (id->localBuf == NULL)
return -1;
}
rsize = receiveMessage(id, id->localBuf, id->maxSize, wait, delay);
if (rsize > size)
return -1;
memcpy(buffer, id->localBuf, rsize);
}
else {
sc = rtems_message_queue_receive(id->id, buffer, &rsize, wait, delay);
if (sc != RTEMS_SUCCESSFUL)
return -1;
}
return rsize;
}
LIBCOM_API int epicsStdCall epicsMessageQueueTryReceive(
epicsMessageQueueId id,
void *message,
unsigned int size)
{
return receiveMessage(id, message, size, RTEMS_NO_WAIT, 0);
}
LIBCOM_API int epicsStdCall epicsMessageQueueReceive(
epicsMessageQueueId id,
void *message,
unsigned int size)
{
return receiveMessage(id, message, size, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
}
LIBCOM_API int epicsStdCall epicsMessageQueueReceiveWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int size,
double timeout)
{
rtems_interval delay;
uint32_t wait;
extern double rtemsTicksPerSecond_double;
/*
* Convert time to ticks
*/
if (timeout <= 0.0) {
wait = RTEMS_NO_WAIT;
delay = 0;
}
else {
wait = RTEMS_WAIT;
delay = (int)(timeout * rtemsTicksPerSecond_double);
if (delay == 0)
delay++;
}
return receiveMessage(id, message, size, wait, delay);
}
LIBCOM_API int epicsStdCall epicsMessageQueuePending(
epicsMessageQueueId id)
{
uint32_t count;
rtems_status_code sc;
sc = rtems_message_queue_get_number_pending(id->id, &count);
if (sc != RTEMS_SUCCESSFUL) {
errlogPrintf("Message queue %x get number pending failed: %s\n",
(unsigned int)id,
rtems_status_text(sc));
return -1;
}
return count;
}
LIBCOM_API void epicsStdCall epicsMessageQueueShow(
epicsMessageQueueId id,
int level)
{
int pending = epicsMessageQueuePending(id);
if (pending >= 0)
printf ("Message queue %lx -- Pending: %d\n", (unsigned long)id, pending);
}

View File

@ -0,0 +1,29 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume@aps.anl.gov
* 630 252 4793
*/
/*
* Very thin shims around RTEMS routines
*/
#include <rtems.h>
struct epicsMessageQueueOSD {
rtems_id id;
unsigned int maxSize;
void *localBuf;
};
#define epicsMessageQueueDestroy(q) (rtems_message_queue_delete((q)->id))
#define epicsMessageQueueTrySend(q,m,l) (rtems_message_queue_send((q)->id, (m), (l)) == RTEMS_SUCCESSFUL ? 0 : -1)

View File

@ -0,0 +1,160 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume@aps.anl.gov
* 630 252 4793
*/
/*
* We want to access information which is
* normally hidden from application programs.
*/
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
#define epicsExportSharedSymbols
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems.h>
#include <rtems/error.h>
#include "epicsMessageQueue.h"
#include "errlog.h"
#include <epicsAtomic.h>
#include <errno.h>
#include <mqueue.h>
#include <fcntl.h>
LIBCOM_API epicsMessageQueueId epicsStdCall
epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
{
struct mq_attr the_attr;
epicsMessageQueueId id = (epicsMessageQueueId)calloc(1, sizeof(*id));
epicsAtomicIncrIntT(&id->idCnt);
sprintf(id->name, "MQ_%01d", epicsAtomicGetIntT(&id->idCnt));
the_attr.mq_maxmsg = capacity;
the_attr.mq_msgsize = maximumMessageSize;
id->id = mq_open(id->name, O_RDWR | O_CREAT | O_EXCL, 0644, &the_attr);
if (id->id <0) {
fprintf (stderr, "Can't create message queue: %s\n", strerror (errno));
return NULL;
}
return id;
}
LIBCOM_API void epicsStdCall epicsMessageQueueDestroy(
epicsMessageQueueId id)
{
int rv;
rv = mq_close(id->id);
if( rv ) {
fprintf(stderr, "epicsMessageQueueDestroy mq_close failed: %s\n",
strerror(rv));
}
rv = mq_unlink(id->name);
if( rv ) {
fprintf(stderr,"epicsMessageQueueDestroy mq_unlink %s failed: %s\n",
id->name, strerror(rv));
}
free(id);
}
LIBCOM_API int epicsStdCall epicsMessageQueueTrySend(
epicsMessageQueueId id,
void *message,
unsigned int messageSize)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return mq_timedsend(id->id, (char const *)message, messageSize, 0, &ts);
}
LIBCOM_API int epicsStdCall epicsMessageQueueSendWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int messageSize,
double timeout)
{
struct timespec ts;
unsigned long micros;
// assume timeout in sec
micros = (unsigned long)(timeout * 1000000.0);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += micros / 1000000L;
ts.tv_nsec += (micros % 1000000L) * 1000L;
return mq_timedsend (id->id, (const char *)message, messageSize, 0, &ts);
}
LIBCOM_API int epicsStdCall epicsMessageQueueTryReceive(
epicsMessageQueueId id,
void *message,
unsigned int size)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
}
LIBCOM_API int epicsStdCall epicsMessageQueueReceiveWithTimeout(
epicsMessageQueueId id,
void *message,
unsigned int size,
double timeout)
{
unsigned long micros;
struct timespec ts;
micros = (unsigned long)(timeout * 1000000.0);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += micros / 1000000L;
ts.tv_nsec += (micros % 1000000L) * 1000L;
return mq_timedreceive(id->id, (char *)message, size, NULL, &ts);
}
LIBCOM_API int epicsStdCall epicsMessageQueuePending(
epicsMessageQueueId id)
{
int rv;
struct mq_attr the_attr;
rv = mq_getattr(id->id, &the_attr);
if (rv) {
fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n",
(unsigned int)id->id, id->name, strerror(rv));
return -1;
}
return the_attr.mq_curmsgs;
}
LIBCOM_API void epicsStdCall epicsMessageQueueShow(
epicsMessageQueueId id,
int level)
{
int rv;
struct mq_attr the_attr;
rv = mq_getattr(id->id, &the_attr);
if (rv) {
fprintf(stderr, "Epics Message queue %x (%s) get attr failed: %s\n",
(unsigned int)id->id, id->name, strerror(rv));
}
printf("Message Queue Used:%ld Max Msg:%lu", the_attr.mq_curmsgs, the_attr.mq_maxmsg);
if (level >= 1)
printf(" Maximum size:%lu", the_attr.mq_msgsize);
printf("\n");
}

View File

@ -0,0 +1,29 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author W. Eric Norum
* norume@aps.anl.gov
* 630 252 4793
*/
/*
* Very thin shims around RTEMS routines
*/
#include <rtems.h>
#include <mqueue.h>
struct epicsMessageQueueOSD {
mqd_t id;
char name[24];
int idCnt;
};
#define epicsMessageQueueSend(q,m,l) (mq_send((q)->id, (const char*)(m), (l), 0))
#define epicsMessageQueueReceive(q,m,s) (mq_receive((q)->id, (char*)(m), (s), NULL))

View File

@ -0,0 +1,6 @@
#include <rtems.h>
#include <rtems/error.h>
#include <rtems/rtems/tasks.h>
#include <rtems/score/threadimpl.h>
#include "../posix/osdMutex.c"

View File

@ -0,0 +1,27 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <rtems.h>
#include <rtems/malloc.h>
#include <rtems/score/heap.h>
#define epicsExportSharedSymbols
#include "osiPoolStatus.h"
/*
* osiSufficentSpaceInPool ()
*/
LIBCOM_API int epicsStdCall osiSufficentSpaceInPool ( size_t contiguousBlockSize )
{
unsigned long n;
Heap_Information_block info;
malloc_info( &info );
n = info.Stats.size - (unsigned long)(info.Stats.lifetime_allocated - info.Stats.lifetime_freed);
return (n > (50000 + contiguousBlockSize));
}

View File

@ -0,0 +1,81 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Linux specific socket include
*/
#ifndef osdSockH
#define osdSockH
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h> /* for MAXHOSTNAMELEN */
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#include <unistd.h> /* close() and others */
typedef int SOCKET;
#define INVALID_SOCKET (-1)
#define SOCKERRNO errno
#define socket_ioctl(A,B,C) ioctl(A,B,C)
typedef int osiSockIoctl_t;
typedef socklen_t osiSocklen_t;
typedef int osiSockOptMcastLoop_t;
typedef int osiSockOptMcastTTL_t;
#define FD_IN_FDSET(FD) ((FD)<FD_SETSIZE)
#define SOCK_EWOULDBLOCK EWOULDBLOCK
#define SOCK_ENOBUFS ENOBUFS
#define SOCK_ECONNRESET ECONNRESET
#define SOCK_ETIMEDOUT ETIMEDOUT
#define SOCK_EACCES EACCES
#define SOCK_EADDRINUSE EADDRINUSE
#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL
#define SOCK_ECONNREFUSED ECONNREFUSED
#define SOCK_ECONNABORTED ECONNABORTED
#define SOCK_EINPROGRESS EINPROGRESS
#define SOCK_EISCONN EISCONN
#define SOCK_EALREADY EALREADY
#define SOCK_EINVAL EINVAL
#define SOCK_EINTR EINTR
#define SOCK_EPIPE EPIPE
#define SOCK_EMFILE EMFILE
#define SOCK_SHUTDOWN ESHUTDOWN
#define SOCK_ENOTSOCK ENOTSOCK
#define SOCK_EBADF EBADF
#ifndef SHUT_RD
# define SHUT_RD 0
#endif
#ifndef SHUT_WR
# define SHUT_WR 1
#endif
#ifndef SHUT_RDWR
# define SHUT_RDWR 2
#endif
#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name))
#ifndef IPPORT_USERRESERVED
#define IPPORT_USERRESERVED 5000
#endif
#endif /*osdSockH*/