Here are some brief notes providing the meaning and use for defines that
are commonly seen under uClinux and it's tools. If you are porting an
application or driver and need to make changes based on the library or
version of linux, this is a good starting point for which defines to use.
- __uClinux__
- Use this pre-define to work out if you are building for uClinux. For
example:
#ifdef __uClinux__
pid = vfork();
#else
pid = fork();
#endif
It is only available to applications. For drivers CONFIG_UCLINUX is
more appropriate (also NO_MM for 2.0 and 2.4 kernels and CONFIG_NO_MMU
for 2.5 kernels).
- __UCLIBC__
- Use the pre-define to work out if you are building against uClibc. This
is defined for both the old uC-libc and the new uClibc libraries. Both
libraries try to look like Glibc in many ways so do not rely on
any of the __GLIBC__ family of defines.
- __UC_LIBC__
- This one distinguishes uC-libc from uClibc and is only defined when
building against uC-libc.
- EMBED
- This one is often used to distinguish code that is not required in
a typical embedded system. Generally its use can be avoided by using
defines that are more descriptive like CONFIG_NO_SWAP. It is provided
here so that when encountered it's purpose will be known.
- mc68000
- This define is provided by the m68k-elf compiler for all m68k compiled
code. If you need to know that you are on an m68k, this is the define
to use.
-
__mcf5200__, __mcf5200,
__mcf5307__, __mcf5307,
__mc68332__, __mcpu32__, ...
- The m68k-elf compiler provides defines based on the CPU type. You can use
these when whatever you are doing is processor dependent. These are
particularly useful in assembler when a particular model doesn't
support the same set of instructions as another (ie., coldfire/m68000)
and you need to make some slight changes.
- arm
- This define is provided by the arm-elf compiler for all ARM compiled code.
If you need to know that you are on an ARM, this is the define to
use. arm_elf is also defined by the arm-elf compiler.
-
__ARM_ARCH_4T__, __ARM_ARCH_2__, ...
- The arm-elf compiler provides defines based on the CPU type. You can use
these when whatever you are doing is processor dependent. These are
particularly useful in assembler when a particular model doesn't
support the same set of instructions as another (ie., arm2/arm7tdmi)
and you need to make some slight changes.
- LINUX_VERSION_CODE
- You can use the define from the linux kernel to make changes based on
kernel revisions. Applications generally do not need to do this as
they can use other defines related to the functionality they rely on
to make the decision.
In a device driver you may need to use a different API for a newer
kernel. In general it is better to choose the latest API and for the
old kernel where the new API doesn't exist, implement it uses macros
at the top of the file. For example, we maintain 2.0 compatibility
in one of our drivers with the following code bits:
#include
...
#if LINUX_VERSION_CODE < 0x020100
#define get_user(x, y) ((x) = get_fs_long(y))
#define put_user(x, y) put_fs_long(x, y)
#define set_current_state(x) (current->state = (x))
#define signal_pending(x) ((x)->signal & ~(x)->blocked)
#define schedule_timeout(x) ({current->timeout=jiffies+(x);schedule();})
#define copy_from_user(a, b, c) memcpy_fromfs(a, b, c)
#else
#include
#endif
For user code you may be better off with something like the following
to help make your code more portable. Using the kernel version in the
following example would be bad practice, even though it would work,
the following is much cleaner.
...
#ifdef SO_RCVTIMEO
setsockopt (connfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
#endif
...
If your compiler is not listed here then you may want to examine the output
of "XXX-gcc -dumpspecs". It will list the compiler specs in a fairly
readable output that shows all the built-in compiler defines and the options
that enable them.
|