Skip to content
0.5.0 – 2017-09-14
- Support for whole STM32L0 chip family.
- Support and test configuration for NUCLEO-L073RZ board with STM32L0 chip.
- Support and test configuration for 32F769IDISCOVERY board with STM32F7 chip.
- Test of
ENOSPC when the amount of target thread’s free stack is too small to request signal delivery.
- GDB pretty-printers for
estd containers (
internal::ThreadList and all variants of FIFO and message queues (
StaticRawMessageQueue). This greatly simplifies system debugging by allowing easy debugger access to thread lists (inside scheduler or synchronization objects), software timer lists (inside scheduler) and by allowing live examination of queue contents.
ThisThread::setSchedulingPolicy() – counterparts of
- Parser of devicetree
*.dts files written in Python with ply –
pydts.py. The script can parse a
*.dts file into a Python dictionary. As this is a proof-of-concept for now, only limited set of devicetree syntax is supported. Following features are currently not handled: path references, bytestrings, any integer arithmetic other than addition and multiplication, labels for anything else than a node, multiple labels for single node, memory reservations, any non-standard extensions,
/include/ statements (
#include statements should be used exclusively), C or C++ comments (should be handled by C preprocessor). The features which are currently handled are enough to parse all STM32
*.dts files from Linux or from Zephyr. The script relies on C preprocessor to resolve
#define macros, handle
#include statements and remove C/C++ comments. Before you feed the file into this script, you should first do something like
cpp -nostdinc -undef -E -x assembler-with-cpp in.dts -o out.dts. Linemarkers generated by current cpp versions are supported.
- Support for cores which don’t support bit-banding (ARM Cortex-M0(+), ARM Cortex-M1, ARM Cortex-M7) or don’t have
BASEPRI register (ARMv6-M) to STM32’s SPIv1 low-level driver.
- Devicetree fragments (
*.dtsi files) for architectures.
*.csv files which describe memory and selected peripherals of all supported chips.
generateChipDtsi.py Python script (using Jinja2 template engine) which can generate chip’s devicetree fragments (
*.dtsi files) from
*.csv input file.
- Basic devicetree
*.dts files for all supported boards.
- Board generator Python script using
.dts files as input (parsed with
pydts.py module) and Jinja2template engine for rendering output. This new feature can be used with
make board CONFIG_FILE=path/to/config.dts command.
- “Enable support for signals” option in Kconfig menus. When this option is enabled, all namespaces, functions and classes required for signals are available. Otherwise they are completely disabled, which reduces the size of compiled application. This affects
- Experimental “Enable link-time optimization” option in Kconfig menus.
- “Enable static destructors” and “Register static destructors in run time” options in Kconfig menus. These can be used to completely disable destructors for objects with static storage duration, which reduces ROM usage of application. By default both options are disabled, as this is the most common choice for an embedded application which never exits.
- Support for newlib’s ratargetable locking, which makes all newlib functions with shared state – like the ones from
<stdio.h>, functions which manipulate time zone, modify environment variables and so on – thread-safe. “Retargetable locking” has to be enabled during toolchain compilation – toolchains compiled in March 2017 or later should support that feature.
architecture::requestFunctionExecution() no longer handles the case of current thread sending the request to itself.
- Size of stack passed as argument to
DynamicThread or as template argument to
StaticThread is adjusted to alignment requirements of architecture. This way “usable” size of stack will never be less than the requested value.
distortosConfiguration.h file no longer “undefines” Kconfig symbols which are not set.
- All boolean Kconfig symbols are now converted to
#define CONFIG_... 1 in generated
distortosConfiguration.h file. Previously they were converted to a macro without value (
#define CONFIG_...), which made building complex conditions harder than necessary.
- All supported boards were regenerated from
- All folders in
source/board/STM32/STM32*/ and in
configurations/ were renamed to be in sync with filenames of their generated contents.
chip::configureOutputPin() for STM32’s GPIOv1 now have default values for all the arguments which are less important.
chip::configureOutputPin() for STM32’s GPIOv2 now have default values for all the arguments which are less important.
- Generated linker scripts (either from
.dts file by
make board or during compilation when using custom board) are more similar to GNU’s default linker script.
- Type of
TickClock counter –
TickClock::rep was changed from
int64_t. This way
TickClock::duration can be negative and
TickClock::time_point may represent time points before bootup.
- Update CMSIS to version 5.1.0.
- Update CMSIS-STM32F0 to version 1.8.0.
- Update CMSIS-STM32F1 to version 1.6.0.
- Update CMSIS-STM32F4 to version 1.16.0.
StaticRawMessageQueue<T, QueueSize> and
StaticRawMessageQueueFromSize<ElementSize, QueueSize> were marked as deprecated and are scheduled to be removed after v0.5.0. The classes are deprecated because they don’t match their “dynamic” counterparts (which use size in bytes, not type) and because
StaticRaw...QueueFromSize<ElementSize, QueueSize> aliases work only for
ElementSize which is a positive power of 2. New versions of these classes which were added –
StaticRawFifoQueue2<ElementSize, QueueSize> and
StaticRawMessageQueue2<ElementSize, QueueSize> – don’t have these flaws. To upgrade your code replace
StaticRaw...Queue<T, QueueSize> with
StaticRaw...Queue2<sizeof(T), QueueSize> and
StaticRaw...QueueFromSize<ElementSize, QueueSize> with
chip::configureAlternateFunctionPin(chip::Pin, bool, chip::PinOutputSpeed, chip::PinPull, chip::PinAlternateFunction) for STM32’s GPIOv2 was marked as deprecated and is scheduled to be removed after v0.5.0. This function is deprecated because one of the most important arguments –
chip::PinAlternateFunction – is the last one, which makes it impossible to have default values for the less important arguments. New overload
chip::configureAlternateFunctionPin(chip::Pin, chip::PinAlternateFunction, bool, chip::PinOutputSpeed, chip::PinPull) has
chip::PinAlternateFunction passed on the second position, not the last one, thus allowing to have a default value for all the arguments that follow.
ThisThread::Signals::setSignalMask() may never return
ENOSPC, as it delivers signals directly, not via
- Failure during generation or queuing of signal – for example due to free stack size being insufficient, which is reported with
ENOSPC error code – won’t leave the generated/queued signal pending.
- Signals are never delived from within critical section.
- Fixed compilation of USARTv2 low-level driver for some STM32F0 chips, for which
USART_CR1_M0is not defined.
- Minor fixes necessary for compilation and proper behaviour in GCC 7.
- Fixes required for compilation and proper execution when link-time optimization is enabled.
- Fix tup-based build when
Tupfile.lua from folder A is used to compile files from folder B. Previously proper folder hierarchy would not be created in the output directory.
- Fix stack overflow in idle thread for ARMv6-M when
Thread::detach() is enabled, “Optimize for size (-Os)” is selected and GCC 7 is used. In that case idle thread needs 264 bytes of stack, so increase its size to 320 bytes.
- All support for GCC 4.x was removed, GCC 5.1 is the minimum supported version. GCC 5.1 – released more than 2 years ago – is the first version to fully support
constexpr constructors. Dropping support for earlier versions finally allows global objects’ initialization to be greatly simplified. This project aims to support 3 most recent “major” versions of GCC, which – currently – means GCC 5, GCC 6 and GCC 7.
0.4.0 – 2017-03-11
- Support for all 78 STM32F7 chips.
- Support and test configuration for 32F746GDISCOVERY board with STM32F7 chip.
STKALIGN bit in
SCB->CCR for ARM Cortex-M3 r1p1 (like STM32F1). Thanks to that, stack will be automatically aligned to 8-bytes on exception entry, which is required by AAPCS. This bit is set by default on all other ARM Cortex-M cores.
FATAL_ERROR() macro with weak
- “Check context of functions” option in Kconfig menus. When this option is selected, the context of functions which must not be used from interrupt context (all blocking functions, all
Mutex functions and all functions from
ThisThread namespace) is checked during run-time. If a violation is detected,
FATAL_ERROR() is called with appropriate message. See help of the new option for more info.
- “Check stack pointer range during context switch” option in Kconfig menus. Selecting this option enables simple range checking of preempted thread’s stack pointer during context switches. Such check is relatively fast, but cannot detect all stack overflows.
FATAL_ERROR() is called with appropriate message when an overflow is detected. Check new option’s help for more info.
- “Check stack guard contents during context switch” option in Kconfig menus. When enabled, this option extends stacks for all threads (including
main() thread) with a “stack guard” at the overflow end. This “stack guard” – just as the whole stack – is filled with a sentinel value during thread initialization. During each context switch contents of preempted thread’s “stack guard” are checked – if any byte has changed, FATAL_ERROR() will be called with appropriate message. This method is able to detect stack overflows much more reliably than simple stack pointer range checking and is still sufficiently fast, assuming that the size of “stack guard” is reasonable. For more info, check new option’s help.
- “Check stack pointer range during system tick” and “Check stack guard contents during system tick” options in Kconfig menus, which are similar to “Check stack pointer range during context switch” and “Check stack guard contents during context switch” respectively, but executed during every system tick.
ThisThread::getStackSize() which can be used to get thread’s stack size.
ThisThread::getStackHighWaterMark() which can be used to get “high water mark” (max usage) of thread’s stack.
- Test of thread’s
ENOSPC when stack is too small.
STM32-bit-banding.h header with
STM32_BITBAND() macros, which are more suited for STM32’s CMSIS headers – it’s enough to write
STM32_BITBAND(RCC, CR, PLLON) instead of
BITBAND(&RCC->CR, RCC_CR_PLLON_bit). Note that these new macros must not be used with
FLASH registers – use
STM32_BITBAND_FLASH_ADDRESS() for that peripheral.
- Options to enable STM32’s GPIO to Kconfig menu.
- New chips: 10 STM32F413 chips and 5 STM32F423 chips.
README.md files for all supported boards.
- Changed placement of fixed stacks for ARMv6-M and ARMv7-M in generated linker script. Stack for interrupts (“main” stack) is located at the beginning of RAM, so any stack overflow during interrupt handling will cause a HardFault exception. Stack for
main() thread (“process” stack) is placed at the end or RAM, after heap, which introduces a potential safety margin for any stack overflows in this thread – as long as heap’s last block is not allocated, the memory below this stack is not used.
- Stacks are filled with 0xed419f25 instead of 0. Using 0 is not a reliable method to detect stack usage/overflow, as 0 is very likely to be used in the application (for example to zero-initialize variables).
- Reduced default size of stack for interrupts to 1kB.
- Reduced size of stack for interrupts to 1kB in all test configurations.
- Reduced size of stack for idle thread to 256 bytes when support for thread detachment is enabled.
architecture::requestFunctionExecution() checks for amount of free stack before doing any stack modifications. If there’s not enough free stack available, it returns an
ENOSPC error code. Modify all callers of this function (which includes functions to generate/queue signals and set signal mask) to handle this error code.
- Changed number of threads, software timers, queued signals and signal actions used by test application to 8 (was 10) to reduce its RAM requirements. This fixes a crash of test application for NUCLEO-F103RB board caused by insufficient memory available for
_sbrk_r() and crashes of other configurations at lower optimization levels due to stack overflow.
callOnce() with a mutex. This increases the size of
OnceFlag object (32 bytes vs 8 bytes), but at the same time reduces stack requirements of any thread using
callOnce() function. Removed
ThreadState::blockedOnOnceFlag enum value.
- Cleaned up
architecture namespace, leaving only architecture-specific elements. Moved
internal namespace. Moved
- Removed virtual
Thread::start() and convert overrides available via
StaticThread to non-virtual functions.
architecture::initializeStack() checks for buffer overflow before actually doing any memory operations. If stack is too small for stack frame,
ENOSPC error code is returned. Modify all call paths – starting at
StaticThread::start() – to handle this error.
lowLevelInitialization0() to the very beginning of reset handler.
BITBAND_PERIPH() macro to
- Moved remaining ARMv6-M and ARMv7-M assembly functions (
SVC_Handler) to C++ source files.
ARMv6-M-ARMv7-M-Reset_Handler.cpp no longer requires
__USES_TWO_STACKS to be defined in compilation flags.
- Moved enabling of RCC clocks for STM32’s GPIO from
- Buttons and LEDs for boards depend on enabling the GPIO port to which they are connected. “Enable buttons” and “Enable LEDs” options in Kconfig menu are available only if at least one GPIO port of buttons / LEDs is enabled. Preprocessor macros with total number of buttons and LEDs which were previously provided by Kconfig –
CONFIG_BOARD_TOTAL_LEDS – were renamed to
DISTORTOS_BOARD_TOTAL_LEDS. These macros are now generated automatically by
- Update CMSIS-STM32F0 to version 1.7.0.
- Update CMSIS-STM32F4 to version 1.14.0.
ChipUartLowLevel classes to “devices” group in API reference generated by doxygen.
- Compiler’s built-in defines are passed automatically to doxygen, which fixes some missing documentation entries (for example bit-banding macros).
- Fixed failures in several test cases (
CallOnceOperationsTestCase) that occured only with low core frequency due to very strict timing requirements.
- Fixed stack overflow in
CallOnceOperationsTestCase which occured only on ARM Cortex-M0 cores with
-Og optimization level.
- Maximum values of APB1 and APB2 frequencies for STM32F4 take into account whether over-drive is enabled or not.
lowLevelInitialization1() – which was executed right before calling
main() – from reset handler.
...-bits.h headers files, which are superseded by recent versions of CMSIS headers.
- Configuration of chip package from Kconfig menu.
0.3.0 – 2016-11-24
- Support for periodic execution of software timers. All overloads of
SoftwareTimer::start() were extended with optional second argument with period. If the period is 0 (which is the default value), software timer’s function is executed only once. Otherwise it will be executed periodically until the software timer is stopped.
devices::UartBase interface class, which can be used as a private base for devices using UART interface.
devices::UartLowLevel interface class, which is a low-level interface to hardware-dependent UART driver.
chip::ChipUartLowLevel class – interrupt-driven implementation of
devices::UartLowLevel interface for STM32F0, STM32F1 and STM32F4.
devices::SpiMasterBase interface class, which can be used as a private base for devices using SPI as bus master.
devices::SpiMasterLowLevel interface class, which is a low-level interface to hardware-dependent SPI bus master driver.
chip::ChipSpiMasterLowLevel class – interrupt-driven implementation of
devices::SpiMasterLowLevel interface for STM32F0, STM32F1 and STM32F4.
- “Peripherals configuration” Kconfig menu, where low-level drivers for SPI bus master and U[S]ART can be selected.
uarts.hpp header for STM32F0, STM32F1 and STM32F4 with declarations of all enabled low-level U[S]ART drivers.
spis.hpp header for STM32F0, STM32F1 and STM32F4 with declarations of all enabled low-level SPI master drivers.
devices::SerialPort class – universal serial port device with an interface similar to standard files (
write() member functions of this class support both blocking (with or without timeout) and non-blocking behaviour. Convenient wrappers for reading/writing with timeout are also provided:
estd::ScopeGuard template class, which can be used to execute bound function on scope exit using RAII pattern.
devices::Rs485 class – RS-485 device with all features of
devices::SerialPort and with automatic management of “driver enable” output pin.
devices::SpiDevice classes, which enable easy communication with multiple SPI slave devices connected to the same SPI bus master.
devices::SpiEeprom class which is a driver for common SPI EEPROM chips: Atmel AT25xxx, ON Semiconductor CAT25xxx, ST M95xxx, Microchip 25xxxxx or similar.
- Support for
assert() – override of newlib’s
assertHook() for application and option to enable/disable assertions in Kconfig menus.
estd::ContiguousRange with support for
std::array, constructor for non-const -> const conversions and various useful functions:
- Option in Kconfig menus for manual configuration of ROM’s offset and size in generated linker script. This can be useful when the device has a bootloader at the beginning of flash, when the application is a bootloader and/or when the application uses a few last ROM pages for its own purposes (e.g. emulated EEPROM, storing configuration, logging, …).
architecture::isInInterruptContext() which checks whether thread or interrupt context is currently active. An example use is when the application needs to decide between blocking or non-blocking behaviour, as blocking is not possible in interrupt context.
ChipOutputPin::setInvertedMode() functions, which – if needed – can be made
public by deriving from these classes.
- Missing tests of timers: basic operations of periodic timers, synchronous and asynchronous stops and restarts, reading of state in timer’s function.
- New chips: STM32F071C8, STM32F101C4, 8 STM32F412 chips, 3 STM32F469Vx chips, 3 STM32F469Zx chips, 2 STM32F479Vx chips and 2 STM32F479Zx chips.
- New package types: UFQFPN48 for STM32F101C8, LQFP48 for STM32F410CB, UFBGA64 for STM32F410RB, LQFP176 for STM32F469IG.
- Replace generator of
distortosConfiguration.h that uses AWK (
makeDistortosConfiguration.awk) with the one using shell, cat and sed (
makeDistortosConfiguration.sh). With this change AWK is no longer needed to configure & build this project.
- Merge GPIO drivers for STM32.
- Update CMSIS-STM32F0 to version 1.6.0.
- Update CMSIS-STM32F1 to version 1.4.0.
- Update CMSIS-STM32F4 to version 1.13.0.
- Fix generated linker scripts for older versions of ld (like 18.104.22.16841128), where hidden symbols cannot be used in expressions.
- Fix failure of test application for new versions of “official” ARM toolchain (5.x).
- Fixes necessary for compilation and proper behaviour in GCC 6.2.0 – mainly related to
reinterpret_cast<>() in constant expressions.
- ST’s website no longer lists WLCSP49 as package type for STM32F401CB.
0.2.0 – 2016-05-03
- Support for ARMv6-M (ARM Cortex-M0, ARM Cortex-M0+ and ARM Cortex-M1) architecture.
- Support for all 72 STM32F0 chips.
- Support for all 94 STM32F1 chips.
- Support and test configurations for NUCLEO-F091RC board with STM32F0 chip, NUCLEO-F103RB board with STM32F1 chip and NUCLEO-F429ZI board with STM32F4 chip.
make oldconfig target, which can be used to update currently selected configuration asking about new options.
make olddefconfig target, which can be used to update currently selected configuration with default values of new options.
forAllConfigurations.sh script, which can be used to run any command – passed in first argument – for all configurations found in provided (optional) search path – passed in second argument, default – current path (“.”). One use case is updating all configurations –
./scripts/forAllConfigurations.sh "make oldconfig" or
./scripts/forAllConfigurations.sh "make olddefconfig".
- Ability to delete some folders – if you don’t use their contents – without breaking make/tup build and Kconfig menus. You can obviously delete anything from
configurations/, including the entire folder. The same is true for
documentation/ directory if you don’t plan to generate API reference with doxygen. In case of
source/chip/ you can delete any number of complete components or group of components – e.g. you can delete
source/board/STM32/STM32F4/STM32F4DISCOVERY/ (port for single board) and/or
source/board/STM32/STM32F4/ (group of ports for boards), but you shouldn’t delete just
source/board/STM32/STM32F4/STM32F4DISCOVERY/include/ (part of port for single board). Additionally you can delete entire
- Ability to add configurations of custom applications to Kconfig menus. User can add any number of files named
Kconfig-applicationOptions anywhere in the project, and they will all be automatically included in the “Applications configuration” menu. The same is possible for custom boards, chips and architectures, but these are slightly more complicated, as multiple files are needed.
- Configuration of SRAM1, SRAM2 and SRAM3 regions’ unification for STM32F4 chips.
- Support for additional memory regions of STM32F4 chips (BKPSRAM, CCM, SRAM2, SRAM3) in generated linker scripts.
- Ability to use ARMv7-M‘s PRIMASK to disable all interrupts during critical sections when “Interrupt priority disabled in critical sections” (ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI) options is set to 0. This is the new default setting, as this is a more conservative (and thus safer for a beginner) approach, which doesn’t require any special configuration of interrupt priorities (default value is 0).
- Support for optional inversion to all implementations of
buttons.hpp header with board buttons for all supported boards.
clocks.hpp header with definition of clocks for selected chip.
- New package type for STM32F411C chips – the website lists WLCSP49 variant now.
- Change names of elements of all
enum class from
camelCase for consistency with their use as constants and with other enums.
- Replace individual linker script generators for STM32F1 and STM32F4 families with generic script for ARMv7-M-based chips. The new generator also supports arbitrary number of additional memories (like BKPSRAM, CCM, …), which can be defined with command line arguments.
- Reorganize and simplify Kconfig menus for STM32F1 and STM32F4.
- Improve configuration and initialization of chip clocks for STM32F1 and STM32F4.
- Move configuration of SysTick timer from
architecture::startScheduling() for all ARMv6-M and ARMv7-M targets.
- Change allowed range of PLLN for STM32F446 chips from [192; 432] (first revision of the reference manual) to [50; 432] (second revision of the reference manual).
- API reference generated by doxygen no longer includes code from disabled folders. This way documentation for particular configuration has entries only for single selected chip & architecture, single selected board (if any) and only for enabled applications – sources that are excluded from compilation are not parsed by doxygen.
- Fix insufficient dependencies for “PLLR” option in system clock source configuration for STM32F4. Main PLL’s “/R” output cannot be used as system clock if PLL is disabled.
- Fix invalid definition of templated variants of
- Added missing STM32F429NG chip to Kconfig configuration menus.
- Fix make build for constructs like
CXXFLAGS_$(d)someFileName.cpp := ... not working correctly in top-level folder of the project (where
0.1.0 – 2016-02-26
- Build infrastructure for make and tup.
- Fully preemptive scheduling with 256 priority levels. FIFO and round-robin scheduling policies. Completely static implementation.
- Static and dynamic threads. Thread can execute any function type (regular function, member function, stateless functor, lambda) with any number of arguments of any type. Both thread types can be joined, while dynamic threads can also be detached.
- Semaphores which can also be configured to work as binary semaphores during construction. Completely static implementation.
constexpr constructor. Non-blocking functions can be used in interrupt handlers.
- Mutexes which support various types (normal, error-checking, recursive) and protocols (normal, priority inheritance, priority protection). Priority inheritance protocol works with no limitations: through any number of inheritance “levels” and with any number of mutexes locked by threads in any order. Completely static implementation.
- Condition variables which can work with mutexes. Completely static implementation.
OnceFlag – equivalents of
std::once_flag from C++11 or
pthread_once_t from POSIX. Completely static implementation.
- Message and FIFO queues, both in two flavors: with proper support for C++ objects and for binary serializable types (like POD types). 256 priority levels in message queues. Available in static and dynamic versions. Non-blocking functions can be used in interrupt handlers.
- Support for POSIX-style signals with synchronous (waits) and asynchronous (signal handlers) API. Signals can be “generated” and “queued” with value. Completely static implementation. Non-blocking functions can be used in interrupt handlers.
- One-shot static software timers which can execute any function type (regular function, member function, stateless functor, lambda) with any number of arguments of any type.
- Basic device drivers for input and output pin.
- Support for ARMv7-M (ARM Cortex-M3 and ARM Cortex-M4(F)) architecture. FPU can be used in any number of threads and interrupt handlers at the same time.
- Support for STM32F4 chips.
- Support and test configurations for 3 boards with STM32F4 chips: 32F429IDISCOVERY, NUCLEO-F401RE and STM32F4DISCOVERY.
- Extensive functional tests for all implemented functionalities.
- Configuration with mconf tool from kconfig-frontends.
README.md file with introduction and information about configuration & building.
- Integration with Travis CI service.