From f377202f20f09231b08c98503a22f71e15ca762e Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Thu, 18 Nov 1999 21:45:11 +0000 Subject: [PATCH] for iocCore port --- RELEASE_NOTES.html | 27 +- iocCorePort.html | 705 +++++++++++++++++++++++++++++++++++++++++++++ iocPortStatus.html | 250 ++++++++++++++++ 3 files changed, 981 insertions(+), 1 deletion(-) create mode 100644 iocCorePort.html create mode 100644 iocPortStatus.html diff --git a/RELEASE_NOTES.html b/RELEASE_NOTES.html index fa53f2c38..694ec8cb9 100644 --- a/RELEASE_NOTES.html +++ b/RELEASE_NOTES.html @@ -2,7 +2,7 @@ - + EPICS Release baseR3.13.0.beta12 @@ -11,6 +11,31 @@

EPICS Release baseR3.13.1

+

+November 20, 1998

+ +

+Changes since 3.13.1

+dbStaticLib +

The DTYP field is always written. The NoRun version now keeps record +instances keeps all records of each type in alphabetical order. +

breakpoint tables +

Tables names were previously forced to be alphanumeric. This restriction +is removed. +

dbNotify +

If  dbPutNotify called dbProcess and dbProcess returned an error +the notify completion callback was called twice. This bug is fixed. +

drvBB232 +

This support was defining storage twice. A bug in the current gcc compiler +supplied with tornado does not properl;y compile such code. The extra definitions +are removed. +

aiRecord and aoRecord +

eoff was not being reinitialized when conversion related fields were +dynamically modified. +

mbbiDirectRecord +

When just the record's severity changed, only monitors on the VAL fields +were posted, no monitors on the single bit fields. +
 

Changes between beta12 and 3.13.1

iocLogClient diff --git a/iocCorePort.html b/iocCorePort.html new file mode 100644 index 000000000..261e17ee6 --- /dev/null +++ b/iocCorePort.html @@ -0,0 +1,705 @@ + + + + + + + + +
+
+
+
+
+

+Porting iocCore

+ +
+

+Nov 17, 1999

+
+
+
+
+
+
+iocCore includes the following components of epics base: + + +


The port is based on the following assumptions: +

+ +
+
+

+Overview of Changes

+
+
+ +

+Replacements for existing vxWorks and epics components

+The following Operating System Independent libraries replace vxWorks specific +libraries. + +In addition the following new base components are provided + + +

+Registry

+It is not possible to expect every environment to supply an environment +that makes it easy to implement  vxWorks symFindByName. Instead a +facility to register and find pointers to functions and structures is provided. +This leaves the problem of registering everything currently located via +calls to symFindByName. The following solves the problem: + + +

+Build Environment (Everyone's favorite subject :-)

+The build environment is different. The principal features are: + + +

+task_params.h

+This will go away. + + +

+module_types.h

+This goes away. +

+vxWorks shell

+If the target is not for vxWorks, the vxWorks target shell is not available. +IocInit, dbLoadRecords, etc  must be  called directly by main +or the equivalent. The "nice" vxWorks debugging environment is not available +although a nicer one using xgdb may be available. +

How do we run dbpr, dbgf, etc? +

+Interrupt Level

+The vxWorks intLock/intUnlock routines are an essential part of base. For +example any code, including interrupt routines, can call callbackRequest. +osiInterrupt is provided to solve this problem. For operating systems like +vxWorks, in which everything runs in a shared memory, multithreaded kernel +environment, an osi specific version must be provided. For other operating +systems, e.g. winxx, Unix, Linux, a generic version is provided. The only +restriction is that kernel code MUST not call any of the osi routines. +
+
+
+
+
+

+Status Of Port

+
+
+
+
+
+The following has been done: + +This section contains prototype definitions of what needs to be implemented +for each port of iocCore. +

A particular implementation may implement each function as desired BUT +the final result must appear to user code like the definitions in this +section. For example  functions can be implemented via macros defined +in a header file that replace the generic header file. +
  +

+osiClock

+ +
unsigned long clockGetCurrentTick();
+int clockGetRate();
+int clockGetEventTime(int event_number,TS_STAMP *ts);
+int clockGetCurrentTime(TS_STAMP* ts);
+A vxWorks specific version is provided that provides exactly the same semantics +as 3.13. +

A generic version is provided that should work on most platforms. +

Perhaps it should be implemented via libCom/osiTime. +

+osiFindGlobalSymbol

+ +
void * osiFindGlobalSymbol(const char *name);
+A vxWorks version is provided that calls symFindByName. It is called by +the registry if a name is not found in the registry itself. +

A generic version is provided that always returns failure. If the generic +version is used then all external symbols must be registered, See the registry +for details. +

+osiInterrupt

+ +
int interruptLock();
+void interruptUnlock(int key);
+int interruptIsInterruptContext();
+void interruptContextMessage(const char *message);
+To lock the following must be done: +
+
int key;
+...
+key = interruptLock();
+...
+interruptUnlock(key);
+
+A vxWorks specific version is provided. It maps directly to intLib calls. +

A generic version is provided that uses a global semaphore to lock. +This version is intended for operating systems in which iocCore will run +as a multithreaded process. The global semaphore is thus only global within +the process. +

+osiRing

+ +
ringId  ringCreate(int nbytes);
+void    ringDelete(ringId id);
+int     ringGet(ringId id, char *value,int nbytes);
+int     ringPut(ringId id, char *value,int nbytes);
+void    ringFlush(ringId id);
+int     ringFreeBytes(ringId id);
+int     ringUsedBytes(ringId id);
+int     ringSize(ringId id);
+int     ringIsEmpty(ringId id);
+int     ringIsFull(ringId id);
+A vxWorks specific version is provided that maps directly to rngLib calls. +

A generic version is provided that works on all platforms.  This +version is currently 1.5 times slower than the vxWorks specific version. +Perhaps some clever thought can make it as fast as rngLib. +

osiRing has the following properties. +

+ +

+osiSem.h

+ +
typedef void *semId;
+typedef enum {semTakeOK,semTakeTimeout,semTakeError} semTakeStatus;
+typedef enum {semEmpty,semFull} semInitialState;
+
+semId semBinaryCreate(int initialState);
+void semBinaryDestroy(semId id);
+void semBinaryGive(semId id);
+semTakeStatus semBinaryTake(semId id);
+void semBinaryTakeAssert(semId id);
+semTakeStatus semBinaryTakeTimeout(semId id, double timeOut);
+semTakeStatus semBinaryTakeNoWait(semId id);
+void semBinaryFlush(semId id);
+void semBinaryShow(semId id);
+
+semId semMutexCreate(void);
+void semMutexDestroy(semId id);
+void semMutexGive(semId id);
+semTakeStatus semMutexTake(semId id);
+void semMutexTakeAssert(semId id);
+semTakeStatus semMutexTakeTimeout(semId id, double timeOut);
+semTakeStatus semMutexTakeNoWait(semId id);
+void semMutexShow(semId id);
+
+
+ +


Mutual exclusion semaphores +

+For POSIX + +For vxWorks + + +


On a single threaded environment +

+ +

+osiThread

+ +
#define threadPriorityMax 99
+#define threadPriorityMin  0
+
+/*some generic values */
+#define threadPriorityLow 10
+#define threadPriorityMedium 50
+#define threadPriorityHigh 90
+
+
+/*some iocCore specific values */
+#define threadPriorityChannelAccessClient 10
+#define threadPriorityChannelAccessServer 20
+#define threadPriorityScanLow 60
+#define threadPriorityScanHigh 70
+
+/*
+ *The following functions convert to/from osi (operating system independent)
+ * and oss (operating system specific) priority values
+ * NOTE THAT ALL OTHER CALLS USE osi priority values
+*/
+
+int threadGetOsiPriorityValue(int ossPriority);
+int threadGetOssPriorityValue(int osiPriority);
+
+/* stack sizes for each stackSizeClass are implementation and CPU dependent */
+typedef enum {
+    threadStackSmall, threadStackMedium, threadStackBig
+} threadStackSizeClass;
+
+unsigned int threadGetStackSize(threadStackSizeClass size);
+
+typedef void *threadId;
+threadId threadCreate(const char *name,
+    unsigned int priority, unsigned int stackSize,
+    THREADFUNC funptr,void *parm);
+void threadDestroy(threadId id);
+void threadSuspend(threadId id);
+void threadResume(threadId id);
+int threadGetPriority(threadId id);
+void threadSetPriority(threadId id,int priority);
+void threadSetDestroySafe(threadId id);
+void threadSetDestroyUnsafe(threadId id);
+const char *threadGetName(threadId id);
+int threadIsEqual(threadId id1, threadId id2);
+int threadIsReady(threadId id);
+int threadIsSuspended(threadId id);
+void threadSleep(double seconds);
+threadId threadGetIdSelf(void);
+void threadLockContextSwitch(void);
+void threadUnlockContextSwitch(void);
+threadId threadNameToId(const char *name);
+Thread priorities are assigned a value from 0 to 99. A higher value means +higher priority +

Thread stack values are handled as follows: +

+For vxWorks osiThread is implement via calls to taskLib +

For posix it should be possible (I hope)  to implement thread via +a combination of: +

+Thread is not implemented for a single threaded environment. +

+osiWatchdog

+ +
typedef void *watchdogId;
+typedef void (*WATCHDOGFUNC)(void *parm);
+
+watchdogId watchdogCreate ();
+void watchdogDestroy (watchdogId id);
+void watchdogStart(watchdogId id, int delaySeconds,WATCHDOGFUNC funptr,*parm);
+void watchdogCancel(watchdogId id);
+A vxWorks version is provided that maps directly into wdLib calls. A generic +version is provided. +

+c++ osi classes created by Jeff Hill

+ + + +
+
+
+

+New base supplied component

+
+
+
+ +

+cantProceed

+ +
void cantProceed(const char *errorMessage);
+void *callocMustSucceed(size_t count, size_t size, const char *errorMessage);
+void *mallocMustSucceed(size_t size, const char *errorMessage);
+cantProceed prints error message and then + +callocMustSucceed is like calloc except that it does not return if storage +is not available. A lot of iocCore is initialized by iocInit. If memory +allocation fails during iocInit it is not possible to recover. mallocMustSucceed +is like malloc except that it does not return if storage is not available. +
+
+
+
+

+REGISTRY

+
+
+
+
+iocCore currently uses symFindByName to dynamically bind the following: + +This only the first two items need a solution. The existing implementation +solves the first problem. No solution has been provided for the subroutine +records but it will not be hard implement. +

+Overview

+The basic idea is to provide a registration facility. Any storage meant +to be "globally" accessable must be registered before it can be accessed +by other code. +

A perl script is provided that reads the xxxApp.dbd file and produces +a c file containing a routine registerRecordDeviceDriver, which registers +all record/device/driver support defined in the xxxApp.dbd file. +

+registry

+ +
+
int registryAdd(void *registryID,const char *name,void *data);
+void *registryFind(void *registryID,const char *name);
+ +
int registrySetTableSize(int size);
+void registryFree();
+int registryDump(void);
+
+This is the code which does the work. Each different set of things to register +must have it's own unique ID. Everything to be registered is stored in +the same gpHash table. +

Routine registrySetTableSize is provided in case the default hash table +size (1024 entries)  is not sufficient. +

+registryRecordType.h

+ +
+
typedef int (*computeSizeOffset)(dbRecordType *pdbRecordType);
+
+typedef struct recordTypeLocation {
+    struct rset *prset;
+    computeSizeOffset sizeOffset;
+}recordTypeLocation;
+
+
+int registryRecordTypeAdd(const char *name,recordTypeLocation *prtl);
+recordTypeLocation *registryRecordTypeFind(const char *name);
+
+Some features: + + +

+registryDeviceSupport

+ +
+
int registryDeviceSupportAdd(const char *name,struct dset *pdset)
+struct dset *registryDeviceSupportFind(const char *name);
+
+This provides access to the device support entry table. +

+registryDriverSupport

+ +
+
int registryDriverSupportAdd(const char *name,struct drvet *pdrvet);
+struct drvet *registryDriverSupportFind(const char *name);
+
+/* The following function is generated by registerRecordDeviceDriver/pl */
+int registerRecordDeviceDriver(DBBASE *pdbbase);
+
+This provides access to the driver support entry table. +
  +

+registerRecordDeviceDriver.pl

+This is the perl script which creates a c source file that registers record/device/driver +support. Make rules are provided that + + +

+registerRecordDeviceDriver.c

+A version of this is provided for vxWorks. This version makes it unnecessary +to use registerRecordDeviceDriver.pl or register other external names. +Thus for vxWorks everything can work almost exactly like it did in release +3.13.x + + diff --git a/iocPortStatus.html b/iocPortStatus.html new file mode 100644 index 000000000..44e97d378 --- /dev/null +++ b/iocPortStatus.html @@ -0,0 +1,250 @@ + + + + + + + + +
+

+Status of iocCore port

+ +
Marty Kraimer +
Nov 18, 1999
+ +

This is a brief status of the iocCore port, what has changed since my +last commit, and what needs to be done before we can run iocCore on something +besides vxWorks. +

In the following I state things as though the only remaining thing to +do is implement osiSem and osiThread for other posixIOC. I realize that +a bunck of problems will arise elsewhere when this is done but I really +hope any such problems are minor. +

Note also that I have only built for solaris and vxWorks. +

+makeBaseApp

+The example does not work with the configure rules. We are working on this +problem. +

+Make

+Trying to build everything via a single Makefile in each source directory +became too complicated. Janet has redone the build using Makefile.Host +and Makefile.Ioc +

We still are not handling single vs multithreaded properly. For now +Makefile.Host is single threaded, Makefile.Ioc is multithreaded. +

+libCom

+The osiXXX routines are very similar to what was previously checked in. +Janet has implemented a generic version of osiWatchDog using Jeff's osiTimer. +Thus for ports to other operating systems only osiSem and osiThread need +to be implemented. +

osiSem has changed since the last commit: +

+Some comments for Jeff + +ToDo before demonstration of iocCore of something besides vxWorks + + +

+Channel Access

+In ca/os/posixIOC I have created files caOsDependent.h and caOsDependent..c. +I hope that these are close to what is needed for a pthreads version of +iocCore. Until osiSem and osiThread are implemented for posix this code +can not be tested. See details about channel access below. +
  +

+CASR

+I deleted caswatchdog.c. It was not being built. +

+src/vxWorks

+All vxWorks specific code is moved to src/vxWorks. If you are building +for something besides vxWorks just comment out the build for vxWorks in +src/Makefile. +

+Sequencer

+The old sequencer has been moved to src/vxWorks. This is for compatibilty +for existing vxWorks applications. +

This version of the sequencer will not work on IOCS using the posixIOC +version of Channel Access. The reason is the calls to ca_import and ca_import_cancel. +The technique used for vxWorks will not work (at least easily) for pthreads +since pthreads does not have task variables like vxWorks. Thus this needs +to be rethought. Perhaps William already has solved this problem in his +unbundled version of the sequencer. +

+RTMS

+The following needs  to be done. + + +

+Details of CA conversion

+This is mainly of interest to Jeff. I will guess that Jeff will want to +restructure the code so these are notes about what I did. +

As we knew up frount, the biggest problem was the use of the vxWorks +task variable facility. This is used because ca clients do not have to +call ca_initialize or pass a ca private pointer to each ca_xxx library +routine.  I looked at what pthreads supports and came up with the +following solution. +

iocinf.h previously had the statements +

+
GLBLTYPE struct CA_STATIC *ca_static;
+
+This is replaced by the statements +
+
#include "caOsDependent.h"
+CA_OSD_CA_STATIC
+
+caOsDependent.h is created in each ca/os/xxx directory. For posix (single +threaded), vms, vxWorks, and win32 it just nhas the definitions: +
+
#define CA_OSD_CA_STATIC \
+ GLBLTYPE CA_STATIC *ca_static;
+#define CA_OSD_GET_CA_STATIC
+
+For posixIOC it is defined as: +
+
#include <pthread.h>
+#define CA_OSD_CA_STATIC \
+        extern pthread_key_t *pca_key;
+#define CA_OSD_GET_CA_STATIC \
+  CA_STATIC *ca_static=(CA_STATIC *)pthread_getspecific(*pca_key);
+
+Then each ca public routine (those defined in cadef.h) that use ca_static +have +
+
CA_OSD_GET_CA_STATIC
+
+as the last definition at the start of the routine. A look at ca_task_initialize +in ca/os/posixIOC/caOsDependent.c shows how things are initialized for +a pthread implementation. +

Most of the private ca routines (defined internally or in iocinf.h) +that use ca_static were modified to have ca_static as their first argument. +

Now for some details +

V5_vxWorks_patch.c seemed to be obsolete code. It is gone. +

The following are no longer part of the os specific code. +

+The following should not be part of the os specific code. Can we put them +somewhere else? Maybe ca/bsd_depen.c ? + + +


vxWorks_depen.c is now ca/os/vxWorks/caOsDependent.c. In addition +

+posix_depen.c is now ca/os/posix/caOsDependent.c. +
  +

ca/os/posixIOC/caOsDependent is the os specific code for a pthread implementation. +Since osiSem and osiThread are not implemented for pthread I can not test +this code. I hope it is close to ,what is needed. +

vms_depen.c is now /home/phoebus/MRK/epics/base/src/ca/os/vms/caOsDependent.c. +I removed the routines no longer needed. I can not test this. +

windows_depen.c is now ca/os/win32/caOsDependent.c. I removed the routines +no longer needed. I can not test this. Note that you will also want an +IOC version. +
  +
  +

 
+ + +