Name

Options — Configuring the ARM Architectural HAL Package

Description

The ARM architectural HAL is included in all ecos.db entries for ARM targets, so the package will be loaded automatically when creating a configuration. It should never be necessary to load the package explicitly or to unload it.

The ARM architectural HAL contains a number of configuration points. Few of these should be altered by the user, they are mainly present for the variant and platform HALs to select different architectural features. For example, the CPU family being used, whether the Thumb or Thumb2 instruction sets are supported, if the ARM EABI (Embedded Application Binary Interface) is being used, etc.

CYGINT_HAL_ARM_BIGENDIAN
This interface controls whether the CPU is capable of being run in big endian mode. It should be implemented by either the variant or platform HAL to reflect the setting of the hardware.
CYGHWR_HAL_ARM_BIGENDIAN
On targets which are capable of big-endian operation, this option is used to select whether big- or little-endian operation is desired. It provides the main test point for HAL, eCos and application code to test for a big-endian target. It is inactive if CYGINT_HAL_ARM_BIGENDIAN is not implemented.
CYGINT_HAL_ARM_FPU

This interface controls whether the CPU is capable of supporting a hardware FPU (Floating Point Unit). It is the “common” FPU marker and is implemented when either the variant or platform HAL in turn implements a supported FPU type.

For example, a Cortex-A5 target may define CYGINT_HAL_VFPV4_D16 when it provides the ARMv7 VFPv4-D16 architecture floating point unit.

CYGHWR_HAL_ARM_FPU

On targets which are capable of hardware FPU operation, this option is used to select whether soft or hard floating point operation is desired. It provides the main test point for HAL, eCos and application code to test for a hard-FP target. It is inactive if CYGINT_HAL_ARM_FPU is not implemented.

Even though an architecture may provide a hardware FPU, it is not always suitable for all applications. For example, there is the associated scheduler and RAM cost in preserving FPU context for multi-threaded applications. If CYGHWR_HAL_ARM_FPU is enabled then some further configuration options are made available:

CYGHWR_HAL_ARM_FPU_SWITCH

This option selects the FPU context switching scheme.

Table 234.1. Context Switch

SWITCH Description
ALL

This mode is the most straightforward, and means that on every context switch, all FPU registers are saved and restored between threads.

This mode makes the most sense if you need determinism and/or most or all of your threads will use FP. However if few threads use FP, it can result in a lot of overhead due to saves and restores of unchanged registers.

LAZY

In this mode, if a thread has not used the FPU, the FPU context will not be saved or restored for it. The HAL installs a handler in the ARM undefined instruction exception vector in order to detect the first time the FPU is accessed by that thread. Once the FPU is accessed, the fault handler enables the FPU for that thread, and from then on, the FPU context will be saved and restored when switching from or to that thread.

In a system where some or many threads do not use the FPU, this can greatly improve context switch time. However if the system spends most of its time swapping between two or more threads which do both use the FPU, then there may be additional overhead compared to the ALL mode (due to the need to check if the FPU was enabled for a particular thread on switch). This means the worst case context switch time is longer than with ALL mode. It also reduces determinism as there is an unavoidable latency at the point the thread first accesses the FPU, so that the fault handler can execute to enable the FPU; and determinism is further affected as context switch time depends on whether threads use the FPU.

The LAZY mode does not save on stack usage, as the number of registers which might need to be saved remains the same.

NONE

In this mode, the FPU is enabled, but no floating point context is stored at any point, which naturally means there is no overhead on context switch. However this means that only one thread or context may use the FPU at a time.

If using this mode, either all FP operations must be constrained to a single thread. Or there must be locking to ensure that multiple threads do not access the FPU registers simultaneously. But if you rely on locking, great care must be taken as the compiler has the potential to reorder floating point accesses outside of the critical region if it is still in the same function. The use of the HAL_REORDER_BARRIER() call from the <cyg/hal/hal_arch.h> HAL header can be useful to prevent reordering across a particular point in the code.


CYGIMP_HAL_ARM_FPU_EXC_SAVE

This option allows the FPU context to be saved over exceptions, including interrupts. Normally this option will be disabled by default, since the hardware FPU instructions will only ever be used from application thread level code.

Disabling this option avoids the unnecessary cost associated with saving the hardware FPU context for interrupt or exception handlers. When disabled this does impose the restriction that the developer should ensure that no attached ISR, DSR or exception handler routine can make use of hardware FPU instructions. For the vast majority of eCos configurations this is not an issue.

When this option is enabled the code will preserve the FPU context over exception handlers (including interrupt calls). This option may become a “requirement” if the compiler is configured to make use of hardware FPU registers as temporary storage. However, such use is not recommended since the extra performance cost in saving and restoring the FPU context across (for example) every interrupt probably far outweighs the gain from being able to use the hardware FPU within such handlers. NOTE: If an interrupt or exception handler does make use of the FPU hardware there is NO FPU state preserved across successive handler calls, since each call is a unique instance.

CYGINT_HAL_ARM_NEON

This interface controls whether the CPU contains support for the ARM Advanced SIMD architecture, commonly referred to as NEON. It is usually implemented by the variant or platform HAL to enable NEON support. Since NEON shares registers with the FPU, it is also usually necessary to implement the appropriate FPU option.

For example, a Cortex-A53 target may implement CYGINT_HAL_VFPV4_D32 when it provides the ARMv7 VFPv4-D32 architecture floating point unit and in addition implement CYGINT_HAL_ARM_NEON to indicate that the FPU also implements the NEON architecture.

CYGHWR_HAL_ARM_NEON

On targets which are capable of NEON operation, this option is used to select whether NEON support is enabled. It provides the main test point for HAL, eCos and application code to test for a NEON capable target. It is inactive if either CYGINT_HAL_ARM_FPU or CYGINT_HAL_ARM_NEON are not implemented. If this option is enabled, then CYGHWR_HAL_ARM_FPU will also be enabled automatically. When NEON is enabled, the compiler may generate NEON instructions for data manipulation in any function, including those that may be called from an ISR or DSR. Consequently, CYGIMP_HAL_ARM_FPU_EXC_SAVE is also enabled automatically.

Even though an architecture may provide NEON support, it is not always suitable for all applications. NEON shares the FPU registers and the same context save and restore issues apply. Consequently, the FPU options described above for managing the FPU context are active and also apply to NEON applications.

CYGINT_HAL_ARM_SYSTEM_DEBUG_DCC
This interface controls whether the CPU supports the ARM Debug Communications Channel (DCC) feature. It is normally implemented by the variant HAL to reflect the availability of the hardware.
CYGHWR_HAL_ARM_DIAGNOSTICS_INTERFACE

By default the architectural HAL does not implement diagnostic support, with the default Serial support being left to the variant or platform HAL implementation.

However, if the CPU variant implements the on-chip Debug Communications Channel feature then selecting DCC for this option will configure the system to use the generic architectural HAL DCC diagnostic output support. Accessing DCC diagnostic output will require corresponding support from the hardware debugger host tools being used to connect to the target system.

The discard option configures the system so that all diagnostic output is discarded. This can be selected and used when no I/O channel is available for diagnostics.

When DCC is being used for HAL diagnostics the option CYGDBG_HAL_ARM_DIAGNOSTICS_INTERFACE_DCC_TYPE should match the attached host debugger interface used to capture the diagnostic output. The Character interface simply transfers single characters through the DCC interface, and is compatible with the Linux ICEDCC support and with either of the Lauterbach DCC and DCC3 formats. The LIBDCC format (as used by OpenOCD for example) uses a specific single character encoding that inter-operates with features not currently supported by eCos.

Compiler Flags

It is normally the responsibility of the platform HAL to define the default compiler and linker flags for all packages, although it is possible to override these on a per-package basis. Most of the flags used are the same as for other architectures supported by eCos.

Linker Scripts

The architecture HAL does not provide the main linker script. Instead this must be supplied by the variant HAL, and the makefile rules to generate the final target.ld must be included in the variant's CDL file.