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.
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.
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.
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.
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:
This option selects the FPU context switching scheme.
Table 200-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.
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.
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.
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.
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.
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.
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.
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.