diff --git a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_32K/NRF51822.ld b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_32K/NRF51822.ld index 0b9c664fc41..913b2108474 100644 --- a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_32K/NRF51822.ld +++ b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NORDIC_32K/NRF51822.ld @@ -124,18 +124,20 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; + __HeapBase = .; *(.heap*) + . = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size; __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > RAM diff --git a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S110/NRF51822.ld b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S110/NRF51822.ld index cb472e56404..d0ed81d84e7 100644 --- a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S110/NRF51822.ld +++ b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S110/NRF51822.ld @@ -124,18 +124,20 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; + __HeapBase = .; *(.heap*) + . = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size; __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > RAM diff --git a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S130/NRF51822.ld b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S130/NRF51822.ld index c334dbb3cd8..237ab159854 100644 --- a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S130/NRF51822.ld +++ b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/TARGET_MCU_NRF51_16K_S130/NRF51822.ld @@ -124,18 +124,20 @@ SECTIONS __bss_end__ = .; } > RAM - .heap (COPY): + .heap (NOLOAD): { __end__ = .; end = __end__; + __HeapBase = .; *(.heap*) + . = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size; __HeapLimit = .; } > RAM /* .stack_dummy section doesn't contains any symbols. It is only * used for linker to calculate size of stack sections, and assign * values to stack symbols later */ - .stack_dummy (COPY): + .stack_dummy (NOLOAD): { *(.stack*) } > RAM diff --git a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S index e5de3f95fb1..7fb929dd26b 100644 --- a/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S +++ b/hal/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, Nordic Semiconductor ASA All rights reserved. @@ -28,8 +28,8 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -NOTE: Template files (including this one) are application specific and therefore +/* +NOTE: Template files (including this one) are application specific and therefore expected to be copied into the application project folder prior to its use! */ @@ -43,6 +43,7 @@ expected to be copied into the application project folder prior to its use! #else .equ Stack_Size, 2048 #endif + .globl Stack_Size .globl __StackTop .globl __StackLimit __StackLimit: @@ -53,21 +54,9 @@ __StackTop: .section .heap .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE -#else - .equ Heap_Size, 2048 -#endif .globl __HeapBase .globl __HeapLimit -__HeapBase: - .if Heap_Size - .space Heap_Size - .endif - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - + .section .Vectors .align 2 .globl __Vectors @@ -129,7 +118,7 @@ __Vectors: /* Reset Handler */ .equ NRF_POWER_RAMON_ADDRESS, 0x40000524 - .equ NRF_POWER_RAMON_RAMxON_ONMODE_Msk, 0x3 + .equ NRF_POWER_RAMON_RAMxON_ONMODE_Msk, 0x3 .text .thumb @@ -148,7 +137,7 @@ Reset_Handler: STR R2, [R0] /* Loop to copy data from read only memory to RAM. The ranges - * of copy from/to are specified by following symbols evaluated in + * of copy from/to are specified by following symbols evaluated in * linker script. * __etext: End of code section, i.e., begin of data sections to copy from. * __data_start__/__data_end__: RAM address range that data should be @@ -167,7 +156,7 @@ Reset_Handler: str r0, [r2,r3] bgt .LC1 .LC0: - + LDR R0, =SystemInit BLX R0 LDR R0, =_start @@ -259,4 +248,3 @@ Default_Handler: .end - diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c b/hal/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c index 78f966ab7f9..11aebbe1483 100644 --- a/hal/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c +++ b/hal/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c @@ -19,6 +19,7 @@ #include "cmsis.h" #include "PeripheralNames.h" #include "nrf_delay.h" +#include "toolchain.h" /* * Note: The micro-second timer API on the nRF51 platform is implemented using @@ -55,6 +56,25 @@ static bool us_ticker_inited = false; static volatile uint32_t overflowCount; /**< The number of times the 24-bit RTC counter has overflowed. */ static volatile bool us_ticker_callbackPending = false; static uint32_t us_ticker_callbackTimestamp; +static bool os_tick_started = false; /**< flag indicating if the os_tick has started */ +/** + * The value previously set in the capture compare register of channel 1 + */ +static uint32_t previous_tick_cc_value = 0; + +/* + RTX provide the following definitions which are used by the tick code: + * os_trv: The number (minus 1) of clock cycle between two tick. + * os_clockrate: Time duration between two ticks (in us). + * OS_Tick_Handler: The function which handle a tick event. + This function is special because it never returns. + Those definitions are used by the code which handle the os tick. + To allow compilation of us_ticker programs without RTOS, those symbols are + exported from this module as weak ones. + */ +MBED_WEAK uint32_t const os_trv; +MBED_WEAK uint32_t const os_clockrate; +MBED_WEAK void OS_Tick_Handler() { } static inline void rtc1_enableCompareInterrupt(void) { @@ -110,15 +130,22 @@ static void rtc1_start() */ void rtc1_stop(void) { - NVIC_DisableIRQ(RTC1_IRQn); - rtc1_disableCompareInterrupt(); - rtc1_disableOverflowInterrupt(); + // If the os tick has been started, RTC1 shouldn't be stopped + // In that case, us ticker and overflow interrupt are disabled. + if (os_tick_started) { + rtc1_disableCompareInterrupt(); + rtc1_disableOverflowInterrupt(); + } else { + NVIC_DisableIRQ(RTC1_IRQn); + rtc1_disableCompareInterrupt(); + rtc1_disableOverflowInterrupt(); - NRF_RTC1->TASKS_STOP = 1; - nrf_delay_us(MAX_RTC_TASKS_DELAY); + NRF_RTC1->TASKS_STOP = 1; + nrf_delay_us(MAX_RTC_TASKS_DELAY); - NRF_RTC1->TASKS_CLEAR = 1; - nrf_delay_us(MAX_RTC_TASKS_DELAY); + NRF_RTC1->TASKS_CLEAR = 1; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + } } /** @@ -148,11 +175,11 @@ static inline uint32_t rtc1_getCounter(void) } /** - * @brief Function for handling the RTC1 interrupt. + * @brief Function for handling the RTC1 interrupt for us ticker (capture compare channel 0 and overflow). * * @details Checks for timeouts, and executes timeout handlers for expired timers. */ -void RTC1_IRQHandler(void) +void us_ticker_handler(void) { if (NRF_RTC1->EVENTS_OVRFLW) { overflowCount++; @@ -271,3 +298,305 @@ void us_ticker_clear_interrupt(void) NRF_RTC1->EVENTS_OVRFLW = 0; NRF_RTC1->EVENTS_COMPARE[0] = 0; } + + +#if defined (__CC_ARM) /* ARMCC Compiler */ + +__asm void RTC1_IRQHandler(void) +{ + IMPORT OS_Tick_Handler + IMPORT us_ticker_handler + + /** + * Chanel 1 of RTC1 is used by RTX as a systick. + * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. + * Otherwise, just execute us_ticker_handler. + * This function has to be written in assembly and tagged as naked because OS_Tick_Handler + * will never return. + * A c function would put lr on the stack before calling OS_Tick_Handler and this value + * would never been dequeued. + * + * \code + * void RTC1_IRQHandler(void) { + if(NRF_RTC1->EVENTS_COMPARE[1]) { + // never return... + OS_Tick_Handler(); + } else { + us_ticker_handler(); + } + } + * \endcode + */ + ldr r0,=0x40011144 + ldr r1, [r0, #0] + cmp r1, #0 + beq US_TICKER_HANDLER + bl OS_Tick_Handler +US_TICKER_HANDLER + push {r3, lr} + bl us_ticker_handler + pop {r3, pc} + nop /* padding */ +} + +#elif defined (__GNUC__) /* GNU Compiler */ + +__attribute__((naked)) void RTC1_IRQHandler(void) +{ + /** + * Chanel 1 of RTC1 is used by RTX as a systick. + * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. + * Otherwise, just execute us_ticker_handler. + * This function has to be written in assembly and tagged as naked because OS_Tick_Handler + * will never return. + * A c function would put lr on the stack before calling OS_Tick_Handler and this value + * would never been dequeued. + * + * \code + * void RTC1_IRQHandler(void) { + if(NRF_RTC1->EVENTS_COMPARE[1]) { + // never return... + OS_Tick_Handler(); + } else { + us_ticker_handler(); + } + } + * \endcode + */ + __asm__ ( + "ldr r0,=0x40011144\n" + "ldr r1, [r0, #0]\n" + "cmp r1, #0\n" + "beq US_TICKER_HANDLER\n" + "bl OS_Tick_Handler\n" + "US_TICKER_HANDLER:\n" + "push {r3, lr}\n" + "bl us_ticker_handler\n" + "pop {r3, pc}\n" + "nop" + ); +} + +#else + +#error Compiler not supported. +#error Provide a definition of RTC1_IRQHandler. + +/* + * Chanel 1 of RTC1 is used by RTX as a systick. + * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. + * Otherwise, just execute us_ticker_handler. + * This function has to be written in assembly and tagged as naked because OS_Tick_Handler + * will never return. + * A c function would put lr on the stack before calling OS_Tick_Handler and this value + * will never been dequeued. After a certain time a stack overflow will happen. + * + * \code + * void RTC1_IRQHandler(void) { + if(NRF_RTC1->EVENTS_COMPARE[1]) { + // never return... + OS_Tick_Handler(); + } else { + us_ticker_handler(); + } + } + * \endcode + */ + +#endif + +/** + * Return the next number of clock cycle needed for the next tick. + * @note This function has been carrefuly optimized for a systick occuring every 1000us. + */ +static uint32_t get_next_tick_cc_delta() { + uint32_t delta = 0; + + if (os_clockrate != 1000) { + // In RTX, by default SYSTICK is is used. + // A tick event is generated every os_trv + 1 clock cycles of the system timer. + delta = os_trv + 1; + } else { + // If the clockrate is set to 1000us then 1000 tick should happen every second. + // Unfortunatelly, when clockrate is set to 1000, os_trv is equal to 31. + // If (os_trv + 1) is used as the delta value between two ticks, 1000 ticks will be + // generated in 32000 clock cycle instead of 32768 clock cycles. + // As a result, if a user schedule an OS timer to start in 100s, the timer will start + // instead after 97.656s + // The code below fix this issue, a clock rate of 1000s will generate 1000 ticks in 32768 + // clock cycles. + // The strategy is simple, for 1000 ticks: + // * 768 ticks will occur 33 clock cycles after the previous tick + // * 232 ticks will occur 32 clock cycles after the previous tick + // By default every delta is equal to 33. + // Every five ticks (20%, 200 delta in one second), the delta is equal to 32 + // The remaining (32) deltas equal to 32 are distributed using primes numbers. + static uint32_t counter = 0; + if ((counter % 5) == 0 || (counter % 31) == 0 || (counter % 139) == 0 || (counter == 503)) { + delta = 32; + } else { + delta = 33; + } + ++counter; + if (counter == 1000) { + counter = 0; + } + } + return delta; +} + +static inline void clear_tick_interrupt() { + NRF_RTC1->EVENTS_COMPARE[1] = 0; + NRF_RTC1->EVTENCLR = (1 << 17); +} + +/** + * Indicate if a value is included in a range which can be wrapped. + * @param begin start of the range + * @param end end of the range + * @param val value to check + * @return true if the value is included in the range and false otherwise. + */ +static inline bool is_in_wrapped_range(uint32_t begin, uint32_t end, uint32_t val) { + // regular case, begin < end + // return true if begin <= val < end + if (begin < end) { + if (begin <= val && val < end) { + return false; + } else { + return true; + } + } else { + // In this case end < begin because it has wrap around the limits + // return false if end < val < begin + if (end < val && val < begin) { + return false; + } else { + return true; + } + } + +} + +/** + * Register the next tick. + */ +static void register_next_tick() { + previous_tick_cc_value = NRF_RTC1->CC[1]; + uint32_t delta = get_next_tick_cc_delta(); + uint32_t new_compare_value = (previous_tick_cc_value + delta) & MAX_RTC_COUNTER_VAL; + + // Disable irq directly for few cycles, + // Validation of the new CC value against the COUNTER, + // Setting the new CC value and enabling CC IRQ should be an atomic operation + // Otherwise, there is a possibility to set an invalid CC value because + // the RTC1 keeps running. + // This code is very short 20-38 cycles in the worst case, it shouldn't + // disturb softdevice. + __disable_irq(); + uint32_t current_counter = NRF_RTC1->COUNTER; + + // If an overflow occur, set the next tick in COUNTER + delta clock cycles + if (is_in_wrapped_range(previous_tick_cc_value, new_compare_value, current_counter) == false) { + new_compare_value = current_counter + delta; + } + NRF_RTC1->CC[1] = new_compare_value; + + // set the interrupt of CC channel 1 and reenable IRQs + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk; + __enable_irq(); +} + +/** + * Initialize alternative hardware timer as RTX kernel timer + * This function is directly called by RTX. + * @note this function shouldn't be called directly. + * @return IRQ number of the alternative hardware timer + */ +int os_tick_init (void) +{ + NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { + // wait for the low frequency clock start + } + + NRF_RTC1->PRESCALER = 0; /* for no pre-scaling. */ + + NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI); + NVIC_ClearPendingIRQ(RTC1_IRQn); + NVIC_EnableIRQ(RTC1_IRQn); + + NRF_RTC1->TASKS_START = 1; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + + NRF_RTC1->CC[1] = 0; + clear_tick_interrupt(); + register_next_tick(); + + os_tick_started = true; + + return RTC1_IRQn; +} + +/** + * Acknowledge the tick interrupt. + * This function is called by the function OS_Tick_Handler of RTX. + * @note this function shouldn't be called directly. + */ +void os_tick_irqack(void) +{ + clear_tick_interrupt(); + register_next_tick(); +} + +/** + * Returns the overflow flag of the alternative hardware timer. + * @note This function is exposed by RTX kernel. + * @return 1 if the timer has overflowed and 0 otherwise. + */ +uint32_t os_tick_ovf(void) { + uint32_t current_counter = NRF_RTC1->COUNTER; + uint32_t next_tick_cc_value = NRF_RTC1->CC[1]; + + return is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter) ? 0 : 1; +} + +/** + * Return the value of the alternative hardware timer. + * @note The documentation is not very clear about what is expected as a result, + * is it an ascending counter, a descending one ? + * None of this is specified. + * The default systick is a descending counter and this function return values in + * descending order, even if the internal counter used is an ascending one. + * @return the value of the alternative hardware timer. + */ +uint32_t os_tick_val(void) { + uint32_t current_counter = NRF_RTC1->COUNTER; + uint32_t next_tick_cc_value = NRF_RTC1->CC[1]; + + // do not use os_tick_ovf because its counter value can be different + if(is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter)) { + if (next_tick_cc_value > previous_tick_cc_value) { + return next_tick_cc_value - current_counter; + } else if(current_counter <= next_tick_cc_value) { + return next_tick_cc_value - current_counter; + } else { + return next_tick_cc_value + (MAX_RTC_COUNTER_VAL - current_counter); + } + } else { + // use (os_trv + 1) has the base step, can be totally inacurate ... + uint32_t clock_cycles_by_tick = os_trv + 1; + + // if current counter has wrap arround, add the limit to it. + if (current_counter < next_tick_cc_value) { + current_counter = current_counter + MAX_RTC_COUNTER_VAL; + } + + return clock_cycles_by_tick - ((current_counter - next_tick_cc_value) % clock_cycles_by_tick); + } + + return 0; +} diff --git a/libraries/tests/rtos/mbed/basic/main.cpp b/libraries/tests/rtos/mbed/basic/main.cpp index 386e24ad13b..5ad41b661d6 100644 --- a/libraries/tests/rtos/mbed/basic/main.cpp +++ b/libraries/tests/rtos/mbed/basic/main.cpp @@ -19,6 +19,8 @@ #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/isr/main.cpp b/libraries/tests/rtos/mbed/isr/main.cpp index 71f20e6b0bc..da89bccab8e 100644 --- a/libraries/tests/rtos/mbed/isr/main.cpp +++ b/libraries/tests/rtos/mbed/isr/main.cpp @@ -22,6 +22,8 @@ #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/mail/main.cpp b/libraries/tests/rtos/mbed/mail/main.cpp index 3b66eff8a8c..3e7e0f0ea1e 100644 --- a/libraries/tests/rtos/mbed/mail/main.cpp +++ b/libraries/tests/rtos/mbed/mail/main.cpp @@ -30,6 +30,8 @@ typedef struct { #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/mutex/main.cpp b/libraries/tests/rtos/mbed/mutex/main.cpp index d0effb2f2a7..7edd0a6ccfe 100644 --- a/libraries/tests/rtos/mbed/mutex/main.cpp +++ b/libraries/tests/rtos/mbed/mutex/main.cpp @@ -17,13 +17,13 @@ #elif defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 + #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F070RB) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F072RB) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) @@ -32,6 +32,8 @@ #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/queue/main.cpp b/libraries/tests/rtos/mbed/queue/main.cpp index 0d3850dc83a..e44021f392c 100644 --- a/libraries/tests/rtos/mbed/queue/main.cpp +++ b/libraries/tests/rtos/mbed/queue/main.cpp @@ -30,6 +30,8 @@ typedef struct { #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/semaphore/main.cpp b/libraries/tests/rtos/mbed/semaphore/main.cpp index 89e8a9b379e..cc57aca08ec 100644 --- a/libraries/tests/rtos/mbed/semaphore/main.cpp +++ b/libraries/tests/rtos/mbed/semaphore/main.cpp @@ -20,13 +20,13 @@ #elif defined(TARGET_STM32F103RB) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/4 + #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F070RB) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F072RB) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR) - #define STACK_SIZE DEFAULT_STACK_SIZE/2 + #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) @@ -35,6 +35,8 @@ #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/libraries/tests/rtos/mbed/signals/main.cpp b/libraries/tests/rtos/mbed/signals/main.cpp index d1de69eb16d..51bff164f23 100644 --- a/libraries/tests/rtos/mbed/signals/main.cpp +++ b/libraries/tests/rtos/mbed/signals/main.cpp @@ -21,6 +21,8 @@ #define STACK_SIZE 768 #elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 1536 +#elif defined(TARGET_MCU_NRF51822) + #define STACK_SIZE 512 #else #define STACK_SIZE DEFAULT_STACK_SIZE #endif diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h b/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h index 18514fd99b7..b17dba590e6 100755 --- a/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h +++ b/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h @@ -178,7 +178,7 @@ osMessageQId osMessageQId_osTimerMessageQ; #endif /* Legacy RTX User Timers not used */ -uint32_t os_tmr = 0U; +uint32_t os_tmr = 0U; uint32_t const *m_tmr = NULL; uint16_t const mp_tmr_size = 0U; @@ -500,6 +500,12 @@ osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, #elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401) #define INITIAL_SP (0x20008000UL) +#elif defined(TARGET_MCU_NORDIC_32K) +#define INITIAL_SP (0x20008000UL) + +#elif defined(TARGET_MCU_NORDIC_16K) +#define INITIAL_SP (0x20004000UL) + #else #error "no target defined" diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c index 5d5e7748d67..fd91efc9f22 100755 --- a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c +++ b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c @@ -59,7 +59,7 @@ || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F334R8) || defined(TARGET_STM32F334C8) \ || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \ || defined(TARGET_SSCI824) || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) \ - || defined(TARGET_EFM32HG_STK3400) + || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_MCU_NRF51822) # define OS_TASKCNT 6 # else # error "no target defined" @@ -97,7 +97,7 @@ # define OS_MAINSTKSIZE 128 # elif defined(TARGET_STM32F334R8) || defined(TARGET_STM32F303RE) || defined(TARGET_STM32F303K8) || defined(TARGET_STM32F334C8) \ || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) \ - || defined(TARGET_EFM32HG_STK3400) + || defined(TARGET_EFM32HG_STK3400) || defined(TARGET_MCU_NRF51822) # define OS_MAINSTKSIZE 112 # else # error "no target defined" @@ -111,7 +111,7 @@ #ifndef OS_PRIVCNT #define OS_PRIVCNT 0 #endif - + // Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4> // Defines the combined stack size for threads with user-provided stack size. // Default: 0 @@ -126,16 +126,16 @@ #ifndef OS_STKCHECK #define OS_STKCHECK 1 #endif - + // Stack usage watermark // Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer. // Enabling this option increases significantly the execution time of osThreadCreate. #ifndef OS_STKINIT #define OS_STKINIT 0 #endif - -// Processor mode for thread execution -// <0=> Unprivileged mode + +// Processor mode for thread execution +// <0=> Unprivileged mode // <1=> Privileged mode // Default: Privileged mode #ifndef OS_RUNPRIV @@ -143,19 +143,23 @@ #endif // - + // RTX Kernel Timer Tick Configuration // ====================================== // Use Cortex-M SysTick timer as RTX Kernel Timer -// Cortex-M processors provide in most cases a SysTick timer that can be used as +// Cortex-M processors provide in most cases a SysTick timer that can be used as // as time-base for RTX. #ifndef OS_SYSTICK - #define OS_SYSTICK 1 +# if defined(TARGET_MCU_NRF51822) +# define OS_SYSTICK 0 +# else +# define OS_SYSTICK 1 +# endif #endif // // RTOS Kernel Timer input clock frequency [Hz] <1-1000000000> -// Defines the input frequency of the RTOS Kernel Timer. -// When the Cortex-M SysTick timer is used, the input clock +// Defines the input frequency of the RTOS Kernel Timer. +// When the Cortex-M SysTick timer is used, the input clock // is on most systems identical with the core clock. #ifndef OS_CLOCK # if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_TEENSY3_1) @@ -250,11 +254,14 @@ # include "clocking.h" # define OS_CLOCK REFERENCE_FREQUENCY +#elif defined(TARGET_MCU_NRF51822) +# define OS_CLOCK 32768 + # else # error "no target defined" # endif #endif - + // RTX Timer tick interval value [us] <1-1000000> // The RTX Timer tick interval value is used to calculate timeout values. // When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer. @@ -302,14 +309,14 @@ #ifndef OS_TIMERPRIO #define OS_TIMERPRIO 5 #endif - + // Timer Thread stack size [bytes] <64-4096:8><#/4> // Defines stack size for Timer thread. // Default: 200 #ifndef OS_TIMERSTKSZ #define OS_TIMERSTKSZ 200 #endif - + // Timer Callback Queue size <1-32> // Number of concurrent active timer callback functions. // Default: 4 diff --git a/workspace_tools/build_travis.py b/workspace_tools/build_travis.py index edf199d2eeb..7189dba8399 100644 --- a/workspace_tools/build_travis.py +++ b/workspace_tools/build_travis.py @@ -92,10 +92,10 @@ { "target": "LPC4088", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb", "fat"] }, { "target": "ARCH_PRO", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, { "target": "LPC1549", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, - { "target": "NRF51822", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, + { "target": "NRF51822", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, { "target": "DELTA_DFCM_NNN40", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, - { "target": "NRF51_DK", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, - { "target": "NRF51_MICROBIT", "toolchains": "GCC_ARM", "libs": ["dsp", "fat"] }, + { "target": "NRF51_DK", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, + { "target": "NRF51_MICROBIT", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "fat"] }, { "target": "EFM32ZG_STK3200", "toolchains": "GCC_ARM", "libs": ["dsp"] }, { "target": "EFM32HG_STK3400", "toolchains": "GCC_ARM", "libs": ["dsp", "rtos", "usb"] }, diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index 1063c38ee42..924c0280633 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -714,7 +714,8 @@ "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_2", "description": "Mutex resource lock", @@ -727,9 +728,10 @@ "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", - "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", + "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_3", "description": "Semaphore resource lock", @@ -744,7 +746,8 @@ "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_4", "description": "Signals messaging", @@ -758,7 +761,8 @@ "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_5", "description": "Queue messaging", @@ -770,9 +774,10 @@ "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", - "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", + "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_6", "description": "Mail messaging", @@ -784,9 +789,10 @@ "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", - "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", + "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_7", "description": "Timer", @@ -800,9 +806,10 @@ "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", - "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", + "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_8", "description": "ISR (Queue)", @@ -814,9 +821,10 @@ "RZ_A1H", "VK_RZ_A1H", "DISCO_F407VG", "DISCO_F429ZI", "NUCLEO_F411RE", "DISCO_F469NI", "NUCLEO_F410RB", "NUCLEO_F401RE", "NUCLEO_F334R8", "DISCO_F334C8", "NUCLEO_F302R8", "NUCLEO_F030R8", "NUCLEO_F070RB", "NUCLEO_L031K6", "NUCLEO_L053R8", "DISCO_L053C8", "NUCLEO_L073RZ", "NUCLEO_F072RB", "NUCLEO_F091RC", "DISCO_L476VG", "NUCLEO_L476RG", - "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", + "DISCO_F401VC", "NUCLEO_F303RE", "NUCLEO_F303K8", "MAXWSNENV", "MAX32600MBED", "NUCLEO_L152RE", "NUCLEO_F446RE", "NUCLEO_F103RB", "DISCO_F746NG", "NUCLEO_F746ZG", "MOTE_L152RC", "B96B_F446VE", - "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800"], + "EFM32HG_STK3400", "EFM32PG_STK3401", "EFM32LG_STK3600", "EFM32GG_STK3700", "EFM32WG_STK3800", + "NRF51822", "NRF51_DK", "NRF51_MICROBIT", "SEEED_TINY_BLE"], }, { "id": "RTOS_9", "description": "SD File write-read",