Need help with <asm/io.h> include file

Need help with <asm/io.h> include file

Post by Jon Elso » Wed, 20 Jun 2001 14:31:25



Hello, all,

I am working on improving performance on a parallel port motion
control interface I have working for servo motors.  There is a file,
/usr/src/linux-2.0.36/include/asm-i386/io.h (at least on my system)
which defines 80x86 I/O instructions so they can be placed inline
in the C code.  This makes a HUGE difference in performance, when
the subroutine overhead can be eliminated.

The problem I'm having is that this include file can only be included
in one C source file of a group that are linked together.  If it is
included in more than one of the source files, you get  the following
blast of errors from the linker.  I did compile with the -O2 option.
This is a Red Hat 5.2 system with the realtime 0.9J patch, if that
matters.

g++ -g  -DLINUX -Dlinux_2_0_36 -DPLATNAME=\"linux_2_0_36\" -D__RT__
-Dlinux -Dlinux_2_0_36 /usr/local/emc/plat/linux_2_0_36/lib/extppmcmot.o

/usr/local/emc/plat/linux_2
_0_36/lib/ppmc_encoder.o /usr/local/emc/plat/linux_2_0_36/lib/ppmc_dac.o

/usr/local/emc/plat/linux_2_0_36/lib/ppmc_aio.o
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o
 /usr/local/emc/plat/linux_2_0_36/lib/ppmc_internal.o
/usr/local/emc/plat/linux_2_0_36/lib/emcmot.o
/usr/local/emc/plat/linux_2_0_36/lib/emcmotglb.o /usr/local/emc/plat
/linux_2_0_36/lib/trivkins.o /usr/local/emc/plat/linux_2_0_36/lib/pid.o
/usr/local/emc/plat/linux_2_0_36/lib/cubic.o
/usr/local/emc/plat/linux_2_0_36/lib/tp.o /usr/loca
l/emc/plat/linux_2_0_36/lib/tc.o
/usr/local/emc/plat/linux_2_0_36/lib/mmxavg.o
/usr/local/emc/plat/linux_2_0_36/lib/emcmotlog.o
/usr/local/emc/plat/linux_2_0_36/lib/emc
motutil.o \
/usr/local/rcslib/plat/linux_2_0_36/lib/libpm.a \
/usr/local/rcslib/plat/linux_2_0_36/lib/librcs.a \
 -lm \
-o /usr/local/emc/plat/linux_2_0_36/bin/ppmcmot )
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function
`virt_to_phys':
/usr/include/asm/io.h:47: multiple definition of `virt_to_phys'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:47:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function
`phys_to_virt':
/usr/include/asm/io.h:52: multiple definition of `phys_to_virt'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:52:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function `__inb':
/usr/include/asm/io.h:126: multiple definition of `__inb'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:126:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function `__inbc':
/usr/include/asm/io.h:126: multiple definition of `__inbc'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:126:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function `__inb_p':
/usr/include/asm/io.h:126: multiple definition of `__inb_p'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:126:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function `__inbc_p':

/usr/include/asm/io.h:126: multiple definition of `__inbc_p'
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_encoder.o:/usr/include/asm/io.h:126:

first defined here
/usr/local/emc/plat/linux_2_0_36/lib/ppmc_dio.o: In function `__inw':

and on and on, ad infinitum!

I can see why virt-to-phys and phys-to-virt are causing a multiple
definition, as these ARE
callable routines.  But, I don't see why this is causing mutliple
definitions of __inb, etc. as these
appear to only be preprocessor defines, and anyway, aren't callable but
inline, so the linker
shouldn't have to know or worry about them.

Does anyone understand this particularly obscure bit of code enough to
help me with this?

Thanks much in advance!

Jon Elson