Experimental Physics and Industrial Control System
At the Canada-France-Hawaii Telescope we have ported the EPICS IOC code to the
Force Sparc 5 VME-based processor and have been running this version
for the past three months.
These notes are being posted to tech-talk due to their potential relevance for
the porting of EPICS IOC core to other RISC processors.
The version of EPICS we worked with is R3.12.0Beta13 1995/04/28 11:01:32.
Some of the changes mentioned here _may_ have been incorporated into the
current release. [I haven't checked yet].
The major porting issues have been in the alignment of several buffers used in
Channel Access. The general approach taken was to force the buffer whose access
was generating a 'Memory Address Not Aligned' error to be aligned as a double.
This is usually accomplished by making use of the CA_MESSAGE_ALIGN() macro
defined in $EPICS/base/src/ca/iocmsg.h during the allocation of the buffer.
Four buffers in the $EPICS/base/src/ directories had to be aligned. They
are:
File Routine Buffer
---- ------- ------
[IOC CA Server Code]
rsrv/server.h N/A message_buffer.buf
[IOC CA Client Code]
ca/access.c ca_search_and_connect() chix->id.paddr
ca/access.c ca_array_put() user supplied argument 'pvalue'
ca/access.c ca_array_put_callback() ppn->dbPutNotify.pbuffer
The rest of this posting provides additional details of each case.
File: rsrv/server.h
Buffer: message_buffer.buf
Notes: This is a case in which we had to change the definition of a data
structure. Quoting from Jeff Hill:
I see one possible cause of problems. If the message buffer starts
at a proper boundary then all protocol items will be properly
aligned because each item's length is an integer multiple of the
largest data item passed - a double. The structure below has 3 long's
before the protocol buffer (which is an array of characters).
Long's are 4 bytes on the SPARC so we end up with the protocol buffer
potentially on a 4 byte boundary. This is a problem.
struct message_buffer{
unsigned long stk;
unsigned long maxstk;
long cnt;
char buf[MAX_MSG_SIZE];
};
Try making the following change to the structure:
/*
* !! align and buf must be next to each other !!
*
* The dbr_double_t pad guarantees buf will have
* proper alignment because dbr_double_t is currently
* the largest atomic data type passed in the CA protocol
* (I really should malloc the buffer)
*/
struct message_buffer{
const dbr_double_t align;
char buf[MAX_MSG_SIZE];
unsigned long stk;
unsigned long maxstk;
long cnt;
};
With a double immediately preceding the buffer the compiler
will force proper alignment. Of course this is ugly and I
should malloc the buffer however I am looking for a simple
reliable fix that will not require extensive changes on your part.
File: ca/access.c ca_search_and_connect()
Buffer: chix->id.paddr
Notes: (struct db_addr *)chix->id.paddr is not properly aligned as
a result of the calloc() that creates (chid) chix. A memory alignment error
is generated when (struct db_addr) tmp_paddr is copied to *chix->id.paddr.
Here's the source code listing to illustrate the technique used to align:
int APIENTRY ca_search_and_connect
(
char *name_str,
chid *chixptr,
void (*conn_func) (struct connection_handler_args),
void *puser
)
{
<stuff deleted>
/*
* only for IOCs
*/
#ifdef vxWorks
{
struct db_addr tmp_paddr;
int size;
/* Find out quickly if channel is on this node */
status = db_name_to_addr(name_str, &tmp_paddr);
if (status == OK) {
/*
* allocate CHIU (channel in use) block
*
* also allocate enough for the channel name & paddr
* block
*/
size = sizeof(*chix) + strcnt + sizeof(struct db_addr);
/* Adjust size to include proper alignment of id.paddr field */
size = CA_MESSAGE_ALIGN(size);
*chixptr = chix = (chid) calloc(1,size);
if (!chix){
return ECA_ALLOCMEM;
}
/*******************************************
* Force chix->id.paddr to be 8-byte aligned
********************************************/
chix->id.paddr = (struct db_addr *)
CA_MESSAGE_ALIGN((strcnt + (char *) (chix + 1)));
*chix->id.paddr = tmp_paddr;
<rest of routine deleted>
File: ca/access.c ca_array_put()
Buffer: user supplied argument 'pvalue'
Notes: This is sensistive to the alignment of the user supplied
argument 'pvalue'. I'm currently forcing alignment in the client
programs.
File: ca/access.c ca_array_put_callback()
Buffer: ppn->dbPutNotify.pbuffer
Notes:
if(!ppn){
int fill;
/*
ppn = (CACLIENTPUTNOTIFY *)
calloc(1, sizeof(*ppn)+size);
*/
fill = CA_MESSAGE_ALIGN(sizeof(*ppn)) -
sizeof(*ppn);
ppn = (CACLIENTPUTNOTIFY *)
calloc(1, sizeof(*ppn)+fill+size);
if(!ppn){
UNLOCK;
return ECA_ALLOCMEM;
}
chix->ppn = ppn;
ppn->pcas = ca_static;
ppn->dbPutNotify.userCallback =
ca_put_notify_action;
ppn->dbPutNotify.usrPvt = chix;
ppn->dbPutNotify.paddr = chix->id.paddr;
/* ppn->dbPutNotify.pbuffer = (ppn+1);
*/
ppn->dbPutNotify.pbuffer = (char *)((int)ppn + fill);
}
Aloha,
Peregrine
-------------------------------------------------------------------------------
Peregrine M. McGehee http://www.cfht.hawaii.edu/~mcgehee
Telescope Control Systems Group Canada-France-Hawaii Telescope
(808) 885-3178 P.O. Box 1597, Kamuela, Hawaii 96743
- Navigate by Date:
- Prev:
Re: Policy on C++ compilers Jeff Hill
- Next:
[Q] X-window's Graphics context Noboru Yamamoto
- Index:
1994
1995
<1996>
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
description for archive record Matthias Clausen DESY -MKV2/KRYK-
- Next:
[Q] X-window's Graphics context Noboru Yamamoto
- Index:
1994
1995
<1996>
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024