The ST STM32 parts include on-chip SRAM, and on-chip FLASH. The RAM can vary in size from as little as 4KiB to 128KiB. The FLASH can be up to 1024KiB in size depending on model. There is also support in some models for external SRAM and Flash, which eCos may use where available.
Typically, an eCos platform HAL port will expect a GDB stub ROM monitor or RedBoot image to be programmed into the STM32 on-chip ROM memory for development, and the board would boot this image from reset. The stub ROM/RedBoot provides GDB stub functionality so it is then possible to download and debug stand-alone and eCos applications via the gdb debugger using serial interfaces or other debug channels. The JTAG interface may also be used for development if a suitable JTAG device is available. If RedBoot is present it may also be used to manage the on-chip and external flash memory. For production purposes, applications are programmed into external or on-chip FLASH and will be self-booting.
The package CYGPKG_DEVS_FLASH_STM32 ("STM32
Flash memory support") provides a driver for the on-chip
flash. This driver conforms to the Version 2 flash driver API,
and is automatically enabled if the generic "Flash device
CYGPKG_IO_FLASH) package is included
in the eCos configuration. The driver will configure itself
automatically for the size and parameters of the specific STM32
variant which has been selected in the eCos configuration.
The STM32 does not contain any caches, however, the variant HAL supplies the cyg/hal/hal_cache.h header to satisfy generic code. This header describes zero sized caches and provides null macros for the required functions.
The STM32 variant HAL supports basic polled HAL diagnostic I/O
over any of the on-chip serial devices. There is also a fully
interrupt-driven serial device driver suitable for eCos
applications for all on-chip serial devices, and where
appropriate for the target platform, DMA can be used to reduce
the CPU load. The serial driver consists of an eCos package:
CYGPKG_IO_SERIAL_CORTEXM_STM32 which provides
all support for the STM32 on-chip serial devices. Using the HAL
diagnostic I/O support, any of these devices can be used by the
ROM monitor or RedBoot for communication with GDB. If a device is
needed by the application, either directly or via the serial
driver, then it cannot also be used for GDB
communication using the HAL I/O support. An alternative serial port
should be used instead.
Depending on the STM32Fx series processor configured, the HAL defines CDL interfaces from CYGINT_HAL_STM32_UART0 up to CYGINT_HAL_STM32_UART7 for each of the available UARTs. For F1 series devices the range is 0..4. For F2 and F4 family members the range is 0..5 (4 USARTs and 2 UARTs). For F4 and F7 devices the range is 0..7 (4 USARTs and 4 UARTs). The platform HAL CDL should contain an implements directive for each such UART that is available for use on the board. This will enable use of the UART for diagnostic and application use.
eCos uses a numbering scheme for UARTs which starts at 0, whereas STM32 documentation uses a numbering scheme which starts at 1. Be sure to check which numbering scheme is relevant when interpreting UART numbers in CDL options or eCos interfaces (eCos numbering) or hardware-specific definitions (ST numbering).
The STM32 USARTs provide TX and RX data lines plus hardware flow control using RTS/CTS for those UARTs that have them connected.
CYGPKG_IO_SERIAL_CORTEXM_STM32 package provides
a number of CDL options that allow the size and location of buffers to be
configured. These settings, in conjunction with platform specific
manifests for DMA stream/channel configuration, are used to control
how data is buffered by the STM32 UART driver. For the options listed
below, the relevant UART controller is specified by
x with the
logical eCos interface number.
This option specifies the size of both the input and output buffers for the common serial I/O driver layer, which sits above the low-level STM32 specific driver. When using high baud rates, to avoid overrun, the buffer size may need to be increased to cope with the application serial handler thread switching latency. If the device should only be used in polled mode then this option can be disabled by setting the value to 0. Typically the device driver will run in interrupt or DMA mode (as configured by the platform), such that it will perform some buffering of both incoming and outgoing data.
By default the common serial I/O buffers of the size specified by the
CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIALx_BUFSIZEoption are held in the main application data memory as defined by the active
CYG_HAL_STARTUPconfiguration. For the majority of standard serial uses this will be sufficient, and this option can remain disabled. However, this option can be enabled to force the buffers to be placed into on-chip SRAM, which may be required when using very high communication rates with applications that use off-chip data memory. This option is ignored if the
CYG_HAL_STARTUPconfiguration already selects the on-chip SRAM for application data.
This option controls the size of the low-level UART driver RX buffer.
When interrupt transfers are being used then this option specifies the size of the RX buffer used to provide FIFO-alike operation to minimise the possibility for dropped characters when waiting for the UART DSR to be processed. A minimal buffer size is enforced since if the processor is using off-chip RAM then it may be too slow to handle higher baud rates.
For DMA enabled RX this buffer is used to reduce the overall STM32 serial driver ISR and DSR system overhead. For DMA an interrupt will only be generated when 50% of the buffer size has been received, or when the receiver has been idle for some time. This reduces overall system load at the expense of making the driver slightly less “responsive” for non-continuous transfers. The DMA suport actually splits the buffer into two equal sized buffers and uses the hardware double-buffer support to automatically switch between buffers.
Serial overrun mitigation
Ideally it is prudent for UART connections to use hardware flow control where possible, since it provides a mechanism for both ends of a connection to throttle the data flow to avoid buffer overrun. This is especially true when using very high baud rates, since many characters could be received within the ISR, DSR and scheduling latencies of a running application.
If H/W flow control is not available then,
especially when using higher baud rates, it is critical that the
application developer understands the serial transfer requirements, and
that the STM32 UART driver processing method and configured buffering
is tuned to avoid (or at least minimise the possibility of)
overrun. When H/W flow control is not being used then it may not be
possible to avoid overrun completely, since the remote end can always
transmit more data than the receiver has buffer space for. The
possibility of overrun can be mitigated by ensuring a suitable
software “throttling” handshake mechanism between the
transmitted and receiver, or by ensuring that the receiver has
sufficient buffer space at both the low-level driver reception layer
and the higher-level common serial/application layer
to cope with the worst-case scheduling latency of the application.
When DMA usage is configured by the specific STM32 platform support (implemented by provision of a suitably named manifest describing the stream/channel configuration), the UART DSR MUST have copied data out of the RX buffer into the common serial buffers BEFORE the second DMA buffer has been filled. For example, at 10.5MHz over 1000 8N1 characters can be received in 1-millisecond. The buffer depth should be tuned accordingly to cope with the worst-case UART driver DSR latency to ensure that the automatic hardware switch on DMA buffer fill does not cause data which has not yet been copied to the higher serial layer to be overwritten.
Further, when using DMA, the RX IDLE support is used to force data to
be passed to the common serial layer in a timely fashion. This avoids
the eCos receiver application having to wait for a complete DMA buffer
fill for pending data, which is useful for “character”
based serial protocols. The downside is that due to the IDLE
implementation having to disable the DMA stream temporarily, if the
remote end transmits multiple characters shortly after IDLE is
detected by the STM32 receiver then the DMA ISR latency may affect
whether RX overrun occurs before the handler can re-enable the DMA
The STM32 HAL relies on the architectural HAL to provide support for the interrupts directly routed to the NVIC. The cyg/hal/var_intr.h header defines the vector mapping for these.
In addition support is present for interrupts
EXTI5 to EXTI15 that share
NVIC vectors. These are decoded by a springboard ISR routine that
decodes the interrupt from the EXTI_PR register and calls
hal_deliver_interrupt in the architectural
HAL to deliver it to the real ISR. Variant specific macros are
also defined to permit the masking and configuration of these
The variant HAL provides support for packaging the configuration of a GPIO line into a single 32-bit descriptor that can then be used with macros to configure the pin and set and read its value. Details are supplied later.
The variant HAL provides support for MultiMediaCard (MMC) and
Secure Digital (SD) media cards via the
MMC/SD driver"). This makes use of the STM32 SDIO on-chip
interface. NOTE: No support is yet in place for Secure Digital
Input Output (I/O) cards.
If enabled this driver allows use of MultiMedia Cards (MMC cards) and Secure Digital (SD) flash storage cards within eCos, exported as block devices. This makes them suitable for use as the underlying devices for filesystems such as FAT.
This driver provides the necessary support for the generic MMC
bus layer within the
package to export a disk block device. The disk block device is
only available if the generic disk I/O layer found in the package
CYGPKG_IO_DISK is included in the
The block device may then be used as the device layer for a filesystem such as FAT. Example devices are "/dev/mmcsd0/1" to refer to the first partition on the card, or "/dev/mmcsd0/0" to address the whole device including potentially the partition table at the start.
If the driver is enabled, the following options are available to configure it:
This indicates that the driver should operate in interrupt-driven mode if possible. This is enabled by default if the eCos kernel is enabled. Note though that if the driver finds that global interrupts are off when running, then it will fall back to polled mode even if this option is enabled. This allows for use of the MMC/SD driver in an initialisation context.
This option enables the power-saving feature that will disable the SD clock when the device is idle. This feature can normally be safely enabled on all STM32 platforms.
USB OTG Controllers
The STM32 series supports two different USB OTG controller implementations: OTG1 FS and OTG2 HS. If a specific STM32 microcontroller contains both controllers then configuration support is provided to enable you to select specific operation modes for each.
CYGPKG_IO_USB_HOST host support is enabled then
both controllers will operate in host mode. Similarly, if only
CYGPKG_IO_USB_TARGET is enabled then both controllers
will operate in peripheral mode.
If both options are enabled then the controllers will default to host mode.
To force a specific controller into peripheral mode then
CYGHWR_DEVS_USB_STM32_OTG_HS should be set
If only one controller is in target mode, then
CYGHWR_IO_USB_TARGET_PCDI, will be set to that
controller. If both controllers are in target mode then the FS controller
will be used as the default. If you want to select the other controller
then this will need to be set explicitly.
Note: The STM32 HS OTG2 controller support is currently limited to use in FS speed mode only. In addition, dynamically changing controller mode between host and target is not supported at this time.
eCos includes RTC (known in eCos as a wallclock) device drivers
for the on-chip RTC in the STM32 family. For the F1 processor
family this is located in the package
CYGPKG_DEVS_WALLCLOCK_STM32 ("STM32 RTC
wallclock support"), and for the F2 and F4 processor families this is
located in the
("STM32F2 RTC wallclock support").
On the F1 processor family, the wallclock driver can be
configured with three different clock sources using the CDL
clock source"): LSE for the low-speed
32.768KHz external clock, LSI for the
low-speed internal clock, or HSE_128 for the
high-speed external clock with a fixed divider of 128. The
decision of which source to use depends on the desired clock
stability and hardware configuration, and power
requirements. Consult the STM32 documentation for more details.
The F2 and F4 processor families are similar, except that the
LSE and LSI clocks are at
32KHz clock, and the CDL option name is
The STM32 HAL contains support for gprof-base profiling using a sampling timer. The default timer used is Timer 6, which is one of the basic timers, leaving the more complex timers for application code. The timer used is selected by a set of #defines in src/stm32_misc.c which can be changed to refer to a different timer if required. This timer is only enabled when the gprof profiling package (CYGPKG_PROFILE_GPROF) is included and enabled in the eCos configuration, otherwise it remains available for application use.
The platform HAL must provide the input clock frequency
CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK) in its
CDL file. This is then combined with the following options defined
in this package to define the default system clocks:
This defines the source of the input to the PLL that generates the main system clock. There are two possible sources: the HSE selects the high speed external oscillator, and the HSI selects the high speed internal oscillator. This option defaults to the HSE.
This indicates whether the HSE clock should be started at all. If the system clock is running solely from the HSI clock, there may be no need for an HSE clock, and no crystal connected to it. In that scenario, this option can be disabled. This is usually set by the platform HAL.
This option specifies how much the clock from the input source defined by
CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_SOURCEis divided down by, before being used as an input for the PLL. On non-connectivity parts, you can only divide by 2 or 1. On other F1 parts, if using HSI as the clock source, then that is automatically divided by 2. If using HSE as the clock source, then this value corresponds to the PREDIV1 field of register RCC_CFGR2. On F2 and F4 parts, this value corresponds to the PLLM field of RCC_PLLCFGR.
This defines the factor by which the PLL will multiply the selected input clock, after being divided by
CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_PREDIV. It ranges from 2 to 16 on F1 parts, and 2 to 432 on F2 and F4 parts, and defaults to 9, which is intended to give a 72MHz system clock on those boards with an 8MHz input. On the F1 it corresponds to the PLLMUL field of RCC_CFGR. On the F2/F4 it corresponds to the PLLN field of RCC_PLLCFGR.
This setting is only applicable to the F2 and F4 family of processors. This defines the divider applied to the PLL output for use as the SYSCLK. It can only have values 2, 4, 6 or 8 and defaults to 4. This setting corresponds to the PLLP field of RCC_PLLCFGR.
This defines the divider applied to the prescaler for all peripheral clocks. The HCLK fed to the AHB bus and other peripherals is taken directly from this output. Other peripheral clocks are derived by dividing it further. This can take values between 1 and 512 in powers of 2, the default value is 1.
This defines the prescaler divider for the peripheral clock passed to peripherals on the APB1 bus. It can take values between 1 and 16 in powers of 2, the default value is 2.
This defines the prescaler divider for the peripheral clock passed to peripherals on the APB2 bus. It can take values between 1 and 16 in powers of 2, the default value is 1.
This setting only applies to the F2 and F4 family of processors. It defines the divider used to divide down the PLL output clock (VCO clock) for use by the USB OTG FS, SDIO and RNG peripherals. USB OTG FS requires a 48MHz clock and other peripherals require a clock no greater than 48MHz. The allowable values range from 4 to 15 and the default is 10.
The actual values of these clocks, in Hz, is stored in global
hal_stm32_pclk2 and for the F2/F4/F7 processor families only,
hal_stm32_qclk. The clock supplied to the
SysTick timer, HCLK/8, is also assigned to
hal_cortexm_systick_clock. These variables are
used, rather than configuration options, in anticipation of future
support for power management by varying the system clock rate.
Note that when changing or configuring any of these clock settings, you should consult the relevant processor datasheet as there may be both upper and lower constraints on the frequencies of some clock signals, including intermediate clocks. There are also some clocks where, while there is no strict constraint, clock stability is improved if values are chosen wisely. Finally, be aware that increasing clock speeds using this package may have an effect on platform specific properties, such as memory timings which may have to be adjusted accordingly.