nano RTOS can be integrated in Arduino to provide tasks, synchronisation primitives, enhanced drivers, printf, etc. Some Arduino libraries utilise Arduino timing functions, that might not function optimally when an operating system is in control of the SysTick timer. The following compatibility macros affect the behaviour of Arduino timing functions.
☂︎ Default configuration
The default configuration uses a dynamic (tickless) scheduler, where
the SysTick period is adjusted to reduce unnecessary interrupts, while
also providing very precise wake-up events with microsecond accuracy.
In this mode, forwarding events to an external handler, e.g. Arduino
is still possible, but is disabled to reduce overhead, since the updates
may take up to one second. This can be resolved by patching the Arduino
board libraries to utilise the nano RTOS timing functions, see below.
NANO_TICKLESS= 1 NANO_SYSTICK_EXT= 0
☂︎ Compatibility mode
In compatibility mode, the SysTick period is fixed. Timer events can be
forwarded to Arduino, which makes the Arduino timing functions fully
functional. In this mode however, the precision of wake-up events is
reduced to a millisecond. For optimal performance, please use the dynamic
scheduler, which is enabled in the default configuration.
NANO_TICKLESS= 0 NANO_SYSTICK_EXT= 1
☂︎ Download and extract in ~/Documents/Arduino/libraries
☂︎ Navigate to nanoRTOS/src/cortex-m3
and create a symlink to nanoRTOS.a
☂︎ macOS
cd~/ Documents/ Arduino/ libraries/ nanoRTOS/ src/ cortex- m3 ln- s~/ nano/ lib/ nanoRTOS. a nanoRTOS. a
☂︎ Windows
cd% USERPROFILE%\ Documents\ Arduino\ libraries\ nanoRTOS\ src\ cortex- m3 set NANO_RTOS= c:\ nano mklink nanoRTOS. a% NANO_RTOS%\ lib\ nanoRTOS. a
☂︎ macOS: install from brew and create a link
brew install cask gcc- arm- embedded cd~/ Library/ Arduino15/ packages/ arduino/ tools/ arm- none- eabi- gcc ln- s/ Applications/ ArmGNUToolchain/*/ arm- none- eabi ARMrm - rf4 . 8. 3- 2014q1
☂︎ Or download the Arm GNU Toolchain and extract to
☂︎ macOS
~/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc
☂︎ Windows
%LOCALAPPDATA%\Arduino15\packages\arduino\tools\arm-none-eabi-gcc
spiRec
The return type of spiRec
is uint8_t
, which is incompatible with the
declaration of byte
in new versions of arm-none-eabi-gcc
☂︎ macOS
/Applications/Arduino.app/Contents/Java/libraries/SD/src/utility/Sd2Card.cpp
☂︎ Windows
%ProgramFiles% (x86)\Arduino\Java\libraries\SD\src\utility\Sd2Card.cpp
--- Sd2Card. cpp+++ Sd2Card. cpp@@ - 770, 7+ 770, 7@@ */ uint8_t Sd2Card:: isBusy( void) { chipSelectLow(); - byte b= spiRec(); + uint8_t b= spiRec(); chipSelectHigh(); return( b != 0 XFF);
☂︎ When bare metal is selected, the original behaviour is preserved
☂︎ When nano RTOS is selected, the Arduino timing functions are replaced
☂︎ macOS
~/Library/Arduino15/packages/STMicroelectronics/hardware/stm32/2.6.0/cores/boards.txt
☂︎ Windows
%LOCALAPPDATA%\Arduino15\packages\STMicroelectronics\hardware\stm32\2.6.0\cores\boards.txt
--- boards. txt+++ boards. txt@@ - 8, 6+ 8, 7@@ menu. virtio= Virtual serial support menu. opt= Optimize+ menu. rtos= RTOS menu. dbg= Debug symbols and core logs menu. rtlib= C Runtime Library menu. upload_method= Upload method@@ - 2159, 6+ 2160, 9@@ GenF1. menu. pnum. BLUEPILL_F103C8. build. product_line= STM32F103xB GenF1. menu. pnum. BLUEPILL_F103C8. build. variant= STM32F1xx/ F103C8T_F103CB( T- U) GenF1. menu. pnum. BLUEPILL_F103C8. build. variant_h= variant_PILL_F103Cx. h+ GenF1. menu. pnum. BLUEPILL_F103C8. rtos. nano= nano RTOS+ GenF1. menu. pnum. BLUEPILL_F103C8. rtos. nano. build. flags. rtos=- DUSE_NANO_RTOS= 1+ GenF1. menu. pnum. BLUEPILL_F103C8. rtos. bare_metal= bare metal GenF1. menu. pnum. BLUEPILL_F103CB= BluePill F103CB( or C8 with128 k) GenF1. menu. pnum. BLUEPILL_F103CB. upload. maximum_size= 131072@@ - 2167, 6+ 2171, 9@@ GenF1. menu. pnum. BLUEPILL_F103CB. build. product_line= STM32F103xB GenF1. menu. pnum. BLUEPILL_F103CB. build. variant_h= variant_PILL_F103Cx. h GenF1. menu. pnum. BLUEPILL_F103CB. build. variant= STM32F1xx/ F103C8T_F103CB( T- U) + GenF1. menu. pnum. BLUEPILL_F103CB. rtos. nano= nano RTOS+ GenF1. menu. pnum. BLUEPILL_F103CB. rtos. nano. build. flags. rtos=- DUSE_NANO_RTOS= 1+ GenF1. menu. pnum. BLUEPILL_F103CB. rtos. bare_metal= bare metal# BLACKPILL_F103C8 board GenF1. menu. pnum. BLACKPILL_F103C8= BlackPill F103C8
build.flags.rtos
to the build process
☂︎ macOS
~/Library/Arduino15/packages/STMicroelectronics/hardware/stm32/2.6.0/cores/platform.txt
☂︎ Windows
%LOCALAPPDATA%\Arduino15\packages\STMicroelectronics\hardware\stm32\2.6.0\cores\platform.txt
--- platform. txt+++ platform. txt@@ - 30, 11+ 30, 11@@ compiler. extra_flags=- mcpu={ build. mcu} { build. fpu} { build. float- abi} - DVECT_TAB_OFFSET={ build. flash_offset} - DUSE_FULL_LL_DRIVER- mthumb"@{build.opt.path}" - compiler. S. flags={ compiler. extra_flags} - c- x assembler- with- cpp{ compiler. stm. extra_include} + compiler. S. flags={ compiler. extra_flags} - c- x assembler- with- cpp{ compiler. stm. extra_include} { build. flags. rtos} - compiler. c. flags={ compiler. extra_flags} - c{ build. flags. optimize} { build. flags. debug} { compiler. warning_flags} - std={ compiler. c. std} - ffunction- sections- fdata- sections-- param max- inline- insns- single= 500- MMD{ compiler. stm. extra_include} + compiler. c. flags={ compiler. extra_flags} - c{ build. flags. optimize} { build. flags. debug} { compiler. warning_flags} - std={ compiler. c. std} - ffunction- sections- fdata- sections-- param max- inline- insns- single= 500- MMD{ compiler. stm. extra_include} { build. flags. rtos} - compiler. cpp. flags={ compiler. extra_flags} - c{ build. flags. optimize} { build. flags. debug} { compiler. warning_flags} - std={ compiler. cpp. std} - ffunction- sections- fdata- sections- fno- threadsafe- statics-- param max- inline- insns- single= 500- fno- rtti- fno- exceptions- fno- use- cxa- atexit- MMD{ compiler. stm. extra_include} + compiler. cpp. flags={ compiler. extra_flags} - c{ build. flags. optimize} { build. flags. debug} { compiler. warning_flags} - std={ compiler. cpp. std} - ffunction- sections- fdata- sections- fno- threadsafe- statics-- param max- inline- insns- single= 500- fno- rtti- fno- exceptions- fno- use- cxa- atexit- MMD{ compiler. stm. extra_include} { build. flags. rtos} compiler. ar. flags= rcs@@ - 105, 6+ 105, 7@@ build. startup_file= build. fpu= build. float- abi= + build. flags. rtos= build. flags. optimize=- Os build. flags. debug=- DNDEBUG build. flags. ldspecs=-- specs= nano. specs
☂︎ When bare metal is selected, the original behaviour is preserved
☂︎ When nano RTOS is selected, the Arduino timing functions are replaced
☂︎ macOS
~/Library/Arduino15/packages/STMicroelectronics/hardware/stm32/2.6.0/cores/arduino/wiring_time.c
☂︎ Windows
%LOCALAPPDATA%\Arduino15\packages\STMicroelectronics\hardware\stm32\2.6.0\cores\arduino\wiring_time.c
--- wiring_time. c+++ wiring_time. c@@ - 22, 6+ 22, 28@@ extern "C" { #endif + #if USE_NANO_RTOS + externuint64_t get_timestamp_ms( void); + externuint64_t get_timestamp_us( void); + externuint64_t task_sleep( uint64_t us); + + uint32_t millis( void) +{ + // ToDo: ensure no interrupts + return( uint32_t) get_timestamp_ms(); +} + +// Interrupt- compatible version of micros+ uint32_t micros( void) +{ + return( uint32_t) get_timestamp_us(); +} + + void delay( uint32_t ms) +{ + task_sleep( ms* 1000 ); +} + #else uint32_t millis( void) { // ToDo: ensure no interrupts @@ - 43, 6+ 65, 7@@ } while ( getCurrentMillis() - start< ms); } } + #endif #ifdef __cplusplus }