all doc now in AppDevGuide
This commit is contained in:
705
iocCorePort.html
705
iocCorePort.html
@@ -1,705 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h1>
|
||||
Porting iocCore</h1>
|
||||
|
||||
<blockquote>
|
||||
<h3>
|
||||
Nov 17, 1999</h3>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
iocCore includes the following components of epics base:
|
||||
<ul>
|
||||
<li>
|
||||
Database locking, scanning, and processing</li>
|
||||
|
||||
<li>
|
||||
Channel access client and server support</li>
|
||||
|
||||
<li>
|
||||
Standard record types and soft device support</li>
|
||||
|
||||
<li>
|
||||
Access security</li>
|
||||
|
||||
<li>
|
||||
Other non-hardware support presently packaged with base</li>
|
||||
</ul>
|
||||
|
||||
<p><br>The port is based on the following assumptions:
|
||||
<ul>
|
||||
<li>
|
||||
All hardware support is unbundled from base and thus does not need
|
||||
to be ported.</li>
|
||||
|
||||
<li>
|
||||
For iocCore a multithreaded environment is necessary.</li>
|
||||
|
||||
<li>
|
||||
osi components are defined such that</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
vxWorks implementation has minimal overhead compared to vxWorks specific
|
||||
calls</li>
|
||||
|
||||
<li>
|
||||
The components can be implemented via a combination of POSIX, POSIX.4 (posix
|
||||
real time), and POSIX threads (pthreads).</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
For components that require different implementation for different environments</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The implementation may be via header and/or source files as long as user
|
||||
code can use the "prototype" header files.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h2>
|
||||
Overview of Changes</h2>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h2>
|
||||
Replacements for existing vxWorks and epics components</h2>
|
||||
The following Operating System Independent libraries replace vxWorks specific
|
||||
libraries.
|
||||
<ul>
|
||||
<li>
|
||||
osiClock</li>
|
||||
|
||||
<br>replaces tickGet, sysClockRateGet, TSgetTimeStamp and TSgetCurrentTime.
|
||||
<br>A generic and a vxWorks version is available
|
||||
<li>
|
||||
osiFindGlobalSymbol</li>
|
||||
|
||||
<br>A generic version is provided that always returns failure.
|
||||
<br>a vxWorks version is provided that calls symFindByName.
|
||||
<li>
|
||||
osiInterrupt</li>
|
||||
|
||||
<br>Replaces intLib
|
||||
<br>A generic version is provided that uses a global semaphore. It can
|
||||
be used for winXX, Unix, Linux, etc.
|
||||
<br>A vxWorks specific version is provided.
|
||||
<li>
|
||||
osiRing</li>
|
||||
|
||||
<br>Replaces rngLib.
|
||||
<br>A generic version usable on all platforms is provided.
|
||||
<br>A vxWorks specific version is provided.
|
||||
<li>
|
||||
osiSem</li>
|
||||
|
||||
<br>replaces semLib.h
|
||||
<br>A vxWorks version is provided.
|
||||
<br>No version has been written for other platforms.
|
||||
<li>
|
||||
osiThread</li>
|
||||
|
||||
<br>replaces taskLib.h
|
||||
<br>A vxWorks version is provided.
|
||||
<br>No version exists for other platforms.
|
||||
<li>
|
||||
osiWatchdog</li>
|
||||
|
||||
<br>replaces wdLib.h
|
||||
<br>A vxWorks version is provided.
|
||||
<br>No version exists for other platforms.</ul>
|
||||
In addition the following new base components are provided
|
||||
<ul>
|
||||
<li>
|
||||
cantProceed</li>
|
||||
|
||||
<br>This is called by code that doesnt know what to do when an error occurs.
|
||||
<li>
|
||||
registry</li>
|
||||
|
||||
<br>replaces symFindByName</ul>
|
||||
|
||||
<h2>
|
||||
Registry</h2>
|
||||
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:
|
||||
<ul>
|
||||
<li>
|
||||
Each "ioc" loads a single dbd file defining the complete set of record
|
||||
types, device support, and drivers for that "ioc". A utility is provided
|
||||
that reads this dbd file and generates a C routine registerRecordDeviceDriver,
|
||||
which registers the record, device, and driver support.</li>
|
||||
|
||||
<li>
|
||||
dbLoadDatabase calls registerRecordDeviceDriver after loading the database.</li>
|
||||
|
||||
<li>
|
||||
A version of registerRecordDeviceSupport is also provided which calls osiFindGlobalSymbol.
|
||||
If the underlying operating system properly implements osiFindGlobalSymbol,
|
||||
this version can be used without running the utility that generates the
|
||||
special version. For example this version works on vxWorks</li>
|
||||
|
||||
<li>
|
||||
Nothing has been done to support things like subroutine records. It should
|
||||
not be hard.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
Build Environment (Everyone's favorite subject :-)</h2>
|
||||
The build environment is different. The principal features are:
|
||||
<ul>
|
||||
<li>
|
||||
In source directories Makefile.Ioc replaces Makefile.Vx</li>
|
||||
|
||||
<li>
|
||||
The new configuration files are located in base/configure</li>
|
||||
|
||||
<li>
|
||||
At least for awhile base/config is still present so that old applications
|
||||
still build without major changes</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
task_params.h</h2>
|
||||
This will go away.
|
||||
<ul>
|
||||
<li>
|
||||
Thread names are determined by code that calls threadCreate</li>
|
||||
|
||||
<li>
|
||||
Priorites and stack sizes are handled as described below in the description
|
||||
of thread</li>
|
||||
|
||||
<li>
|
||||
Task creation options are determined by each platform specific version
|
||||
of thread.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
module_types.h</h2>
|
||||
This goes away.
|
||||
<h2>
|
||||
vxWorks shell</h2>
|
||||
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.
|
||||
<p>How do we run dbpr, dbgf, etc?
|
||||
<h2>
|
||||
Interrupt Level</h2>
|
||||
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.
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h2>
|
||||
Status Of Port</h2>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
The following has been done:
|
||||
<ul>
|
||||
<li>
|
||||
All code except the Sequencer and vxWorks dependent device and driver support
|
||||
has been converted to use the new libraries</li>
|
||||
|
||||
<li>
|
||||
The registry has been implemented</li>
|
||||
|
||||
<li>
|
||||
The example generated by makeBaseApp has been successfully tested on vxWorks.</li>
|
||||
|
||||
<li>
|
||||
A separate subdirectory base/src/vxWorks has been created and all vxWorks
|
||||
specific code moved to this subdirectory. This makes it possible for existing
|
||||
vxWorks ioc applications to use the new system with only minor changes
|
||||
to the applications. The sequencer has also been moved to src/vxWorks.
|
||||
The version supplied will only run on vxWorks</li>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h2>
|
||||
Work Remaining</h2>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<li>
|
||||
Implement osiSem and osiThread for other platforms. If the implementation
|
||||
is done via posix (including posix real time and posix threads) then many
|
||||
platforms should be supported.</li>
|
||||
|
||||
<li>
|
||||
Convert the sequencer to use osi calls. William Lupton has already implemented
|
||||
an alpha version. Also the sequencer will be unbundled from base.</li>
|
||||
|
||||
<li>
|
||||
Finish the config and Makefile Changes.</li>
|
||||
|
||||
<li>
|
||||
Modify makeBaseApp so that it uses the new method of building</li>
|
||||
|
||||
<li>
|
||||
TEST TEST TEST</li>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h2>
|
||||
Prototype Definitions</h2>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</ul>
|
||||
This section contains prototype definitions of what needs to be implemented
|
||||
for each port of iocCore.
|
||||
<p>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.
|
||||
<br>
|
||||
<h2>
|
||||
osiClock</h2>
|
||||
|
||||
<pre>unsigned long clockGetCurrentTick();
|
||||
int clockGetRate();
|
||||
int clockGetEventTime(int event_number,TS_STAMP *ts);
|
||||
int clockGetCurrentTime(TS_STAMP* ts);</pre>
|
||||
A vxWorks specific version is provided that provides exactly the same semantics
|
||||
as 3.13.
|
||||
<p>A generic version is provided that should work on most platforms.
|
||||
<p>Perhaps it should be implemented via libCom/osiTime.
|
||||
<h2>
|
||||
osiFindGlobalSymbol</h2>
|
||||
|
||||
<pre>void * osiFindGlobalSymbol(const char *name);</pre>
|
||||
A vxWorks version is provided that calls symFindByName. It is called by
|
||||
the registry if a name is not found in the registry itself.
|
||||
<p>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.
|
||||
<h2>
|
||||
osiInterrupt</h2>
|
||||
|
||||
<pre>int interruptLock();
|
||||
void interruptUnlock(int key);
|
||||
int interruptIsInterruptContext();
|
||||
void interruptContextMessage(const char *message);</pre>
|
||||
To lock the following must be done:
|
||||
<blockquote>
|
||||
<pre>int key;
|
||||
...
|
||||
key = interruptLock();
|
||||
...
|
||||
interruptUnlock(key);</pre>
|
||||
</blockquote>
|
||||
A vxWorks specific version is provided. It maps directly to intLib calls.
|
||||
<p>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.
|
||||
<h2>
|
||||
osiRing</h2>
|
||||
|
||||
<pre>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);</pre>
|
||||
A vxWorks specific version is provided that maps directly to rngLib calls.
|
||||
<p>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.
|
||||
<p>osiRing has the following properties.
|
||||
<ul>
|
||||
<li>
|
||||
For a single writer it is not necessary to lock puts</li>
|
||||
|
||||
<li>
|
||||
For a single reader it is not necessary to lock gets</li>
|
||||
|
||||
<br>ringFlush should only be used if both gets and puts are locked.</ul>
|
||||
|
||||
<h2>
|
||||
osiSem.h</h2>
|
||||
|
||||
<pre>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);
|
||||
|
||||
</pre>
|
||||
|
||||
<p><br>Mutual exclusion semaphores
|
||||
<ul>
|
||||
<li>
|
||||
MUST implement recursive locking</li>
|
||||
|
||||
<li>
|
||||
SHOULD implement priority inheritance and be deletion safe</li>
|
||||
</ul>
|
||||
For POSIX
|
||||
<ul>
|
||||
<li>
|
||||
Binary can be implemented easily as a condition variable</li>
|
||||
|
||||
<li>
|
||||
Mutex can be implemented via various POSIX facilities. Takes careful thought.
|
||||
A pthread mutex is not sufficient.</li>
|
||||
</ul>
|
||||
For vxWorks
|
||||
<ul>
|
||||
<li>
|
||||
the entire implementation of Binary and Mutex is via macros in a
|
||||
vxWorks specific header file.</li>
|
||||
</ul>
|
||||
|
||||
<p><br>On a single threaded environment
|
||||
<ul>
|
||||
<li>
|
||||
Mutex and context are implemented as though the caller always has access
|
||||
to the resource.</li>
|
||||
|
||||
<li>
|
||||
Binary issues an error message and terminates if an attempt is made to
|
||||
create an instance.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
osiThread</h2>
|
||||
|
||||
<pre>#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);</pre>
|
||||
Thread priorities are assigned a value from 0 to 99. A higher value means
|
||||
higher priority
|
||||
<p>Thread stack values are handled as follows:
|
||||
<ul>
|
||||
<li>
|
||||
threadGetStackSize cal be called to get one of three default sizes. Thus
|
||||
should be done whenever possible.</li>
|
||||
|
||||
<li>
|
||||
Code can just set any size it desires. Such code is not portable.</li>
|
||||
</ul>
|
||||
For vxWorks osiThread is implement via calls to taskLib
|
||||
<p>For posix it should be possible (I hope) to implement thread via
|
||||
a combination of:
|
||||
<ul>
|
||||
<li>
|
||||
osiSem</li>
|
||||
|
||||
<li>
|
||||
pthread and POSIX.4</li>
|
||||
|
||||
<li>
|
||||
Special code</li>
|
||||
</ul>
|
||||
Thread is not implemented for a single threaded environment.
|
||||
<h2>
|
||||
osiWatchdog</h2>
|
||||
|
||||
<pre>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);</pre>
|
||||
A vxWorks version is provided that maps directly into wdLib calls. A generic
|
||||
version is provided.
|
||||
<h2>
|
||||
c++ osi classes created by Jeff Hill</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>osiTime</b></li>
|
||||
|
||||
<li>
|
||||
<b>osiPoolStatus</b></li>
|
||||
|
||||
<li>
|
||||
<b>osiSleep</b></li>
|
||||
|
||||
<li>
|
||||
<b>osiTimer</b></li>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h2>
|
||||
New base supplied component</h2>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h2>
|
||||
cantProceed</h2>
|
||||
|
||||
<pre>void cantProceed(const char *errorMessage);
|
||||
void *callocMustSucceed(size_t count, size_t size, const char *errorMessage);
|
||||
void *mallocMustSucceed(size_t size, const char *errorMessage);</pre>
|
||||
cantProceed prints error message and then
|
||||
<ul>
|
||||
<li>
|
||||
For a threaded environment suspends. This is for debugging purposes.</li>
|
||||
|
||||
<li>
|
||||
For a non-threaded environment exits.</li>
|
||||
</ul>
|
||||
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.
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<h1>
|
||||
REGISTRY</h1>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
iocCore currently uses symFindByName to dynamically bind the following:
|
||||
<ul>
|
||||
<li>
|
||||
record/device/driver support.</li>
|
||||
|
||||
<br>The registration facility provides a safe and easy to use alternative
|
||||
to symFindByName
|
||||
<li>
|
||||
subroutine record subroutines.</li>
|
||||
|
||||
<br>An easy to use solution must be developed.
|
||||
<li>
|
||||
initHooks</li>
|
||||
|
||||
<br>A new implementation of initHooks is now provided. It provides a routine
|
||||
initHookRegister. This MUST be called by any routine that wants to be called
|
||||
during initialization.
|
||||
<li>
|
||||
devLib</li>
|
||||
|
||||
<br>This has been moved to base/src/vxWorks. Thus for now it is only supported
|
||||
on vxWorks
|
||||
<li>
|
||||
drvTS.c</li>
|
||||
|
||||
<br>This has been moved to base/src/vxWorks. Thus for now it is only supported
|
||||
on vxWorks
|
||||
<li>
|
||||
errSymLib.c</li>
|
||||
|
||||
<br>This was rewritten to be independent of vxWorks.
|
||||
<li>
|
||||
epicsDynLink - obsolete. Gone.</li>
|
||||
|
||||
<li>
|
||||
dev/symbDev</li>
|
||||
|
||||
<br>Moved to base/src/vxWorks. Thus for now it is only supported on vxWorks.
|
||||
<li>
|
||||
any hardware related component</li>
|
||||
|
||||
<br>Either moved to base/src/vxWorks. or unbundled from base.</ul>
|
||||
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.
|
||||
<h3>
|
||||
Overview</h3>
|
||||
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.
|
||||
<p>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.
|
||||
<h3>
|
||||
registry</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>int registryAdd(void *registryID,const char *name,void *data);
|
||||
void *registryFind(void *registryID,const char *name);</pre>
|
||||
|
||||
<pre>int registrySetTableSize(int size);
|
||||
void registryFree();
|
||||
int registryDump(void);</pre>
|
||||
</blockquote>
|
||||
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.
|
||||
<p>Routine registrySetTableSize is provided in case the default hash table
|
||||
size (1024 entries) is not sufficient.
|
||||
<h2>
|
||||
registryRecordType.h</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>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);</pre>
|
||||
</blockquote>
|
||||
Some features:
|
||||
<ul>
|
||||
<li>
|
||||
Access to both the record support entry table and to the routine which
|
||||
computes the size and offset of each field are provided</li>
|
||||
|
||||
<li>
|
||||
Type safe access is provided.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
registryDeviceSupport</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>int registryDeviceSupportAdd(const char *name,struct dset *pdset)
|
||||
struct dset *registryDeviceSupportFind(const char *name);</pre>
|
||||
</blockquote>
|
||||
This provides access to the device support entry table.
|
||||
<h3>
|
||||
registryDriverSupport</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>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);</pre>
|
||||
</blockquote>
|
||||
This provides access to the driver support entry table.
|
||||
<br>
|
||||
<h3>
|
||||
registerRecordDeviceDriver.pl</h3>
|
||||
This is the perl script which creates a c source file that registers record/device/driver
|
||||
support. Make rules are provided that
|
||||
<ul>
|
||||
<li>
|
||||
execute this script using the dbd file created by dbExpand</li>
|
||||
|
||||
<li>
|
||||
compile the resulting C file</li>
|
||||
|
||||
<li>
|
||||
Make the object file part of the xxxLib file</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
registerRecordDeviceDriver.c</h2>
|
||||
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
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,250 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
Status of iocCore port</h1></center>
|
||||
|
||||
<center>Marty Kraimer
|
||||
<br>Nov 18, 1999</center>
|
||||
|
||||
<p>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.
|
||||
<p>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.
|
||||
<p>Note also that I have only built for solaris and vxWorks.
|
||||
<h2>
|
||||
makeBaseApp</h2>
|
||||
The example does not work with the configure rules. We are working on this
|
||||
problem.
|
||||
<h2>
|
||||
Make</h2>
|
||||
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
|
||||
<p>We still are not handling single vs multithreaded properly. For now
|
||||
Makefile.Host is single threaded, Makefile.Ioc is multithreaded.
|
||||
<h2>
|
||||
libCom</h2>
|
||||
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.
|
||||
<p>osiSem has changed since the last commit:
|
||||
<ul>
|
||||
<li>
|
||||
semXXXShow functions were added. It is permissible to make these
|
||||
empty functions.</li>
|
||||
|
||||
<li>
|
||||
semMutexFlush no longer exists.</li>
|
||||
</ul>
|
||||
Some comments for Jeff
|
||||
<ul>
|
||||
<li>
|
||||
What is osiPoolStatus.c ? Look at libCom/os/vxworks/osiPoolStatus.c Is
|
||||
this a problem?</li>
|
||||
|
||||
<li>
|
||||
Are any of you msi routine going to cause a problem for other operating
|
||||
systems? My guess is that a posix or generic version of most will suffice.
|
||||
This includes osiTime, osiTimer, osiSleep, osiSock, osiFilename.</li>
|
||||
|
||||
<li>
|
||||
I will let you decide how to move osiXXX things from libCom/misc/...
|
||||
to libCom/osi/...</li>
|
||||
|
||||
<li>
|
||||
osiMutex - This caused a problem building the new way. For now we are not
|
||||
referencing it in the Makefiles. It looks like only cas uses it. Can we
|
||||
just move it to cas?</li>
|
||||
</ul>
|
||||
ToDo before demonstration of iocCore of something besides vxWorks
|
||||
<ul>
|
||||
<li>
|
||||
osiSem.c and osiThread.c must be created in libCom/osi/os/posixIOC</li>
|
||||
|
||||
<li>
|
||||
Make up application that properly runs. The key is a main program that
|
||||
does what is currenlt done in the st.cmd file.</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
Channel Access</h2>
|
||||
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.
|
||||
<br>
|
||||
<h2>
|
||||
CASR</h2>
|
||||
I deleted caswatchdog.c. It was not being built.
|
||||
<h2>
|
||||
src/vxWorks</h2>
|
||||
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.
|
||||
<h2>
|
||||
Sequencer</h2>
|
||||
The old sequencer has been moved to src/vxWorks. This is for compatibilty
|
||||
for existing vxWorks applications.
|
||||
<p>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.
|
||||
<h2>
|
||||
RTMS</h2>
|
||||
The following needs to be done.
|
||||
<ul>
|
||||
<li>
|
||||
Definitions added to configure</li>
|
||||
|
||||
<li>
|
||||
If pthreads are supported then that is all; otherwise</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
osiSem and osiThread must be created in libCom/osi/os/rtms</li>
|
||||
|
||||
<li>
|
||||
caOsDependent.h and caOsDependent.c must be created in ca/os/rtms. Start
|
||||
with the version in ca/os/posixIOC</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
Details of CA conversion</h2>
|
||||
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.
|
||||
<p>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.
|
||||
<p>iocinf.h previously had the statements
|
||||
<blockquote>
|
||||
<pre>GLBLTYPE struct CA_STATIC *ca_static;</pre>
|
||||
</blockquote>
|
||||
This is replaced by the statements
|
||||
<blockquote>
|
||||
<pre>#include "caOsDependent.h"
|
||||
CA_OSD_CA_STATIC</pre>
|
||||
</blockquote>
|
||||
caOsDependent.h is created in each ca/os/xxx directory. For posix (single
|
||||
threaded), vms, vxWorks, and win32 it just nhas the definitions:
|
||||
<blockquote>
|
||||
<pre>#define CA_OSD_CA_STATIC \
|
||||
GLBLTYPE CA_STATIC *ca_static;
|
||||
#define CA_OSD_GET_CA_STATIC</pre>
|
||||
</blockquote>
|
||||
For posixIOC it is defined as:
|
||||
<blockquote>
|
||||
<pre>#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);</pre>
|
||||
</blockquote>
|
||||
Then each ca public routine (those defined in cadef.h) that use ca_static
|
||||
have
|
||||
<blockquote>
|
||||
<pre>CA_OSD_GET_CA_STATIC</pre>
|
||||
</blockquote>
|
||||
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.
|
||||
<p>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.
|
||||
<p>Now for some details
|
||||
<p>V5_vxWorks_patch.c seemed to be obsolete code. It is gone.
|
||||
<p>The following are no longer part of the os specific code.
|
||||
<ul>
|
||||
<li>
|
||||
cac_gettimeval is now implemented in access.c</li>
|
||||
|
||||
<li>
|
||||
cac_block_for_io_completion is now implemented in iocinf.c</li>
|
||||
|
||||
<li>
|
||||
cac_block_for_sg_completion is no longer needed.</li>
|
||||
|
||||
<li>
|
||||
os_specific_sg_io_complete is no longer needed</li>
|
||||
|
||||
<li>
|
||||
os_specific_sg_create is no longer needed</li>
|
||||
|
||||
<li>
|
||||
os_specific_sg_delete is no longer needed</li>
|
||||
|
||||
<li>
|
||||
cac_add_task_variable is no longer supported. See vxWorks below.</li>
|
||||
</ul>
|
||||
The following should not be part of the os specific code. Can we put them
|
||||
somewhere else? Maybe ca/bsd_depen.c ?
|
||||
<ul>
|
||||
<li>
|
||||
max_unix_fd</li>
|
||||
|
||||
<li>
|
||||
caSetDefaultPrintfHandler</li>
|
||||
</ul>
|
||||
|
||||
<p><br>vxWorks_depen.c is now ca/os/vxWorks/caOsDependent.c. In addition
|
||||
<ul>
|
||||
<li>
|
||||
It's functionality should be the same as previously. I moved the LOCAL
|
||||
routines to the end so that it was easier to understand what was needed.</li>
|
||||
|
||||
<li>
|
||||
Some suggestions</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Can ca_channel_status be made a non os specific routine? The argument will
|
||||
not easily work for posixIOC. For now I am ignoring this problem.
|
||||
It is just not implemented for posixIOC</li>
|
||||
|
||||
<li>
|
||||
Can the ca/os/posixIOC routines localUseName and caSetDefaultPrintfHandler
|
||||
be put in bsd_depen.c</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
Problems</li>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
ca_import and ca_import_cancel are a problem. These can NOT be easily implemented
|
||||
for posixIOC. Since it appears that they exist mainly for the sequencer,
|
||||
perhaps this is not a problem. I dont know what William is doing in the
|
||||
new sequencer. Note that definitions for ca_import and ca_import_cancel
|
||||
were removed from cadef.h</li>
|
||||
</ul>
|
||||
</ul>
|
||||
posix_depen.c is now ca/os/posix/caOsDependent.c.
|
||||
<br>
|
||||
<p>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.
|
||||
<p>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.
|
||||
<p>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.
|
||||
<br>
|
||||
<br>
|
||||
<blockquote> </blockquote>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user