CYGPKG_HAL_M68K_MCF521x — eCos Support for Freescale MCF521x Processors


The Freescale MCF521x group of processors is part of the larger family of Coldfire processors. The MCF521x group has several members including the MCF5211, MCF5212 and MCF5213. They differ from other Coldfire processors in that there is no external memory bus, instead all memory is on-chip. For example the MCF5213 has 256KB on-chip flash and 32K of on-chip SRAM. All MCF521x processors have basically the same set of peripherals (CAN is not available on the MCF5211 or MCF5212) but differ in the amount of on-chip memory.

The processor HAL package CYGPKG_HAL_M68K_MCF521x provides support for all MCF521x processors, although at the time of writing it has only been tested on an MCF5213. It complements the M68K architectural HAL package CYGPKG_HAL_M68K and the variant HAL package CYGPKG_HAL_M68K_MCFxxxx. An eCos configuration should also include a platform HAL package, for example CYGPKG_HAL_M68K_M5213EVB to support board-level details like how the on-chip peripherals are connected to the outside world. It should be noted that compared with other eCos Coldfire ports rather more work is done by the MCF521x processor HAL and rather less by the platform HAL. This is possible because of the lack of an external memory bus.


The MCF521x processor HAL package should be loaded automatically when eCos is configured for appropriate target hardware. It should never be necessary to load this package explicitly. Unloading the package should only happen as a side effect of switching target hardware.

The configuration option CYGHWR_HAL_M68K_MCF521x_PROCESSOR defines the exact processor type, for example MCF5213. Usually it will be set by the platform HAL and should not be manipulated by the user.

The option CYG_HAL_STARTUP determines whether the application will reside in RAM or in ROM (flash). With just 32K of RAM on the MCF5213 only fairly simple applications will fit into RAM so the default is ROM startup. This can make debugging significantly more difficult because it requires the use of hardware breakpoints, and the processor only supports a small number of these. Debugging RAM startup applications can be rather easier because the debugger can insert breakpoints by modifying the code. Hence it may sometimes be convenient to debug a cut-down version of an application linked against a RAM startup eCos configuration. Alternatively with ROM startup individual functions can be placed in a “.2ram” section which means they will be copied from flash to RAM during initialization and execute from RAM. Again this may make debugging rather easier, assuming sufficient RAM is available.

For ROM startup the table of M68K exception vectors can reside either in ROM or in RAM. This table occupies 512 bytes (a full M68K exception vector table is 1K but on an MCF521x running eCos only half of this is needed). Keeping it in ROM saves a significant portion of the scarce RAM, but means that some eCos functionality (such as the HAL_VSR_SET macros) is not available. Few applications require that functionality so by default the vectors are kept in ROM.

The processor HAL gives application developers full control over how the GPIO pins should be initialized, using configuration options such as CYGHWR_HAL_M68K_MCF521x_GPIO_PORTQS_QS0. That pin is normally used for QSPI but can also be used for CAN, UART0, or as a general-purpose input or output. For a GPIO output it is also possible to specify whether the pins should be initialized high or low. The default settings for each pin are determined by the platform HAL. However there may be various jumpers or an expansion connector on the board, in which case the platform HAL may not know exactly how the various pins should be set up. Hence the processor HAL allows application developers to override the default settings for every pin. There are also configuration options for controlling the pin slew rates and drive strengths.

The GPIO pin settings are used to determine default values for a variety of other hardware-related configuration options. For example CYGHWR_HAL_M68K_MCFxxxx_UART0 will be enabled if either the TX or RX lines are connected, and that option is used elsewhere in the system when deciding which UARTs are potentially usable for HAL diagnostics or should have serial device driver support. The user may be able to override some of these settings, to handle scenarios where a pin should come up as a GPIO output but may later get switched to e.g. a UART tx line. The platform HAL may impose some restrictions.

If the SPI bus should be enabled then there is a configuration option CYGNUM_HAL_M68K_MCF521x_QSPI_ISRPRI to control the interrupt priority of the QSPI bus device. MCF521x processors use the same interrupt controller as the MCF5282, and this has a limitation that all interrupt priorities should be unique. The processor HAL provides non-conflicting defaults for the various on-chip devices but when changing interrupt priorities it is the application developer's responsibility to maintain unique priorities.

If the I²C bus should be enabled then again there is a configuration option CYGNUM_HAL_M68K_MCF521x_I2C_ISRPRI to control the interrupt priority of the I²C device. There is also a configuration option CYGNUM_HAL_M68K_MCF521x_I2C_FDR to set the FDR register which controls the I²C bus speed. The default speed is the I²C standard 100KHz, or as close to that as the hardware allows, but if all attached I²C devices can operate at a faster speed then this option may be adjusted accordingly.

The processor HAL provides a configuration option CYGNUM_HAL_RTC_PERIOD to control the system clock speed. The default setting is 10 milliseconds between clock interrupts or as close to that as the hardware allows, giving a 100Hz system clock.

In kernel configurations the behaviour of the idle thread can be controlled using CYGIMP_HAL_M68K_MCF521x_IDLE. The default behaviour is wait where the cpu, flash and SRAM enter a low power mode but all peripherals continue operating normally. Any interrupt will bring the processor out of low power mode.

The processor HAL defines 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. There are three flags specific to the MCF521x port:

The m68k-elf-gcc compiler supports many variants of the M68K architecture, from the original 68000 onwards. A -m option should be used to select the specific variant in use, and as far as the compiler is concerned the MCF521x has the same cpu core as the MCF5282.
This option forces m68k-elf-gcc to align integer and floating point data to a 32-bit boundary rather than a 16-bit boundary. It should improve performance. However the resulting code is incompatible with most published application binary interface specifications for M68K processors, so it is possible that this option causes problems with existing third-party object code.
Traditionally the %A6 register was used as a dedicated frame pointer, and the compiler was expected to generate link and unlink instructions on procedure entry and exit. These days the compiler is perfectly capable of generating working code without a frame pointer, so omitting the frame pointer often saves some work during procedure entry and exit and makes another register available for optimization. However without a frame pointer register the m68k-elf-gdb debugger is not always able to interpret a thread stack, so it cannot reliably give a backtrace. Removing -fomit-frame-pointer from the default flags will make debugging easier, but the generated code may be worse.

The HAL Port

This section describes how the MCF521x processor HAL package implements parts of the eCos HAL specification. It should be read in conjunction with similar sections from the architectural and variant HAL documentation.

Memory Map and Linker Script

On most platforms the memory map is determined by the platform HAL. However, on an MCF521x processor, all memory is on-chip and the memory map can be determined by the processor HAL, so less work has to be done to port to different MCF521x platforms. For ROM startup, the memory map is as follows:


The base of on-chip flash, and the table of exception vectors. Usually the first 512 bytes are used for exception vectors, but if CYGIMP_HAL_STARTUP_VECTORS_IN_RAM is enabled then only 8 bytes of flash are needed and the exception vectors are relocated to RAM at 0x20000000.

The M68K architecture reserves 1K for the table of exception vectors but on an MCF521x only half of this is needed. Memory between the end of the flash exception vectors and 0x00000400 is used for certain eCos functions such as startup and the interrupt VSR.

The MCF521x on-chip flash requires a 24-byte hal_mcfxxxx_cfm_security_settings data structure at this location. This structure controls the initial locked status of flash blocks and related security settings. eCos provides default settings which leave everything disabled, but the relevant structure hal_68k_mcf5213_security_settings is declared weak so applications can override this if desired.
0x00000418 onwards
Code and constant data are placed in on-chip flash immediately after the CFM security settings. If the application does not fill the whole of flash then any remaining flash blocks may be used for storing persistent data using the standard eCos flash API functions such as cyg_flash_program.
This is the base address for the on-chip SRAM. If the run-time exception vectors are placed in RAM via the configuration option CYGIMP_HAL_STARTUP_VECTORS_IN_RAM then the first 512 bytes are used for the table of exception vectors. Otherwise this SRAM is available for application data.
0x20000000 onwards or 0x20000200 onwards

On-chip SRAM is used for holding application data, both initialized data held in the .data region and uninitialized data in the .bss region. Any SRAM left over at the end can be used for a standard C heap accessed via malloc and free.

The on-chip SRAM can also be used to hold code placed in .2ram section. This mechanism is used by the CFM flash driver for certain low-level functions which cannot normally execute from flash. It can also be used for application functions. For code held in flash the debugger must use hardware breakpoints and the processor supports only a limited number of these. For code held in RAM the debugger can use software breakpoints, modifying the instructions at run-time, so there is no limit on the number of breakpoints. Hence placing certain functions in .2ram sections and hence in RAM may facilitate debugging. Obviously on-chip RAM is a scarce resource so this technique will not always be applicable.

0x40000000 onwards
The on-chip peripherals are mapped into memory starting at this addres.

For RAM startup the on-chip flash is ignored (although the CFM security settings will still affect the flash device driver). Instead all code and data gets placed into RAM and must somehow fit into the limited amount of available on-chip RAM. This can be useful for specialized applications and for debugging certain problems.

Since all MCF521x memory is on-chip the processor does not have a cache and the default empty cache macros provided by the architectural HAL will be used.

The processor HAL provides the .ldi file which, in conjunction with the architectural m68k.ld file, is used to generate the linker script.


The header file cyg/hal/proc_io.h provides definitions of MCF521x-specific on-chip peripherals. Many of the on-chip peripherals are compatible with those on the MCF5282, and for those peripherals it is the var_io.h header provided by the MCFxxxx variant HAL which provides the appropriate definitions. Both headers are automatically included by the architectural header cyg/hal/hal_io.h, so typically application code and other packages will just include the latter.

Interrupt Handling

MCF521x processors implement standard Coldfire interrupt and exception handling, and comes with a single MCF5282-compatible interrupt controller and edge port module. Therefore all interrupt and exception handling is left to the architectural and MCFxxxx variant HAL. The processor's cyg/hal/proc_intr.h serves mainly to define symbols such as CYGNUM_HAL_ISR_UART0, mapping the MCF521x on-chip interrupt sources to the interrupt vectors.

In the default configuration, an MCF521x boots from flash and the exception vectors are held in flash. Hence the HAL_VSR_SET macro and associated functionality are not available. This behaviour can be changed via the configuration option CYGIMP_HAL_STARTUP_VECTORS_IN_RAM.

Clock Support

MCF521x processors come with two MCF5282-compatible programmable interrupt timers. PIT1 is used for the system clock using functionality provided by the variant HAL. PIT0 is available for use by the application. Timer-based profiling is not available since there is not enough RAM available for the arrays needed to hold profiling information.

The MCF521x processor HAL depends on the platform HAL to provide a configuration option CYGHWR_HAL_SYSTEM_CLOCK_HZ, corresponding to the default processor clock speed. The input clock can be provided in various ways and it is only the platform HAL which knows how the clock has been implemented on a given board.

Other Issues

The MCF521x processor HAL does not affect the implementation of data types, stack size definitions, SMP support, system startup, or debug support. The MCFxxxx variant HAL versions of HAL_LSBIT_INDEX and HAL_MSBIT_INDEX are used since the processor supports the ff1.l and bitrev.l instructions.

Other Functionality

The MCF521x processor HAL can instantiate a single flash device structure using the functionality provided by the CYGPKG_DEVS_FLASH_M68K_MCFxxxx_CFM device driver. This will only happen if the generic flash support CYGPKG_IO_FLASH is part of the configuration. Not all applications require flash driver support so to avoid unnecessary code and data overheads the generic flash support is not included in the standard eCos templates. Instead it will have to be added explicitly to the configuration.

The processor HAL will instantiate a cyg_i2c_bus structure hal_mcf521x_i2c_bus when the configuration option CYGHWR_HAL_M68K_MCF521x_I2C is enabled. That option is enabled by default if various GPIO pins are configured appropriately. The implementation is provided by the CYGPKG_DEVS_I2C_MCFxxxx device driver. The processor HAL does not know what I²C devices may be attached to the bus so that is left to the platform HAL.

The processor HAL will instantiate a cyg_spi_bus structure hal_mcf521x_qspi_bus when the configuration option CYGHWR_HAL_M68K_MCF521x_SPI is enabled. That option is enabled by default if various GPIO pins are configured appropriately. The implementation is provided by the CYGPKG_DEVS_SPI_MCFxxxx_QSPI device driver. The processor HAL does not know what SPI devices may be attached to the bus so that is left to the platform HAL. All SPI device structures should be placed in the table mcf521x_qspi.