Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-os/rtos/TARGET_CORTEX/SysTimer.cpp@3:f3764f852aa8, 2018-10-11 (annotated)
- Committer:
- kadonotakashi
- Date:
- Thu Oct 11 02:27:46 2018 +0000
- Revision:
- 3:f3764f852aa8
- Parent:
- 0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kadonotakashi | 0:8fdf9a60065b | 1 | /* mbed Microcontroller Library |
kadonotakashi | 0:8fdf9a60065b | 2 | * Copyright (c) 2006-2012 ARM Limited |
kadonotakashi | 0:8fdf9a60065b | 3 | * |
kadonotakashi | 0:8fdf9a60065b | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
kadonotakashi | 0:8fdf9a60065b | 5 | * of this software and associated documentation files (the "Software"), to deal |
kadonotakashi | 0:8fdf9a60065b | 6 | * in the Software without restriction, including without limitation the rights |
kadonotakashi | 0:8fdf9a60065b | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
kadonotakashi | 0:8fdf9a60065b | 8 | * copies of the Software, and to permit persons to whom the Software is |
kadonotakashi | 0:8fdf9a60065b | 9 | * furnished to do so, subject to the following conditions: |
kadonotakashi | 0:8fdf9a60065b | 10 | * |
kadonotakashi | 0:8fdf9a60065b | 11 | * The above copyright notice and this permission notice shall be included in |
kadonotakashi | 0:8fdf9a60065b | 12 | * all copies or substantial portions of the Software. |
kadonotakashi | 0:8fdf9a60065b | 13 | * |
kadonotakashi | 0:8fdf9a60065b | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
kadonotakashi | 0:8fdf9a60065b | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
kadonotakashi | 0:8fdf9a60065b | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
kadonotakashi | 0:8fdf9a60065b | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
kadonotakashi | 0:8fdf9a60065b | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
kadonotakashi | 0:8fdf9a60065b | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
kadonotakashi | 0:8fdf9a60065b | 20 | * SOFTWARE. |
kadonotakashi | 0:8fdf9a60065b | 21 | */ |
kadonotakashi | 0:8fdf9a60065b | 22 | #include "rtos/TARGET_CORTEX/SysTimer.h" |
kadonotakashi | 0:8fdf9a60065b | 23 | |
kadonotakashi | 0:8fdf9a60065b | 24 | #if DEVICE_LPTICKER |
kadonotakashi | 0:8fdf9a60065b | 25 | |
kadonotakashi | 0:8fdf9a60065b | 26 | #include "hal/lp_ticker_api.h" |
kadonotakashi | 0:8fdf9a60065b | 27 | #include "mbed_critical.h" |
kadonotakashi | 0:8fdf9a60065b | 28 | #if defined(TARGET_CORTEX_A) |
kadonotakashi | 0:8fdf9a60065b | 29 | #include "rtx_core_ca.h" |
kadonotakashi | 0:8fdf9a60065b | 30 | #else//Cortex-M |
kadonotakashi | 0:8fdf9a60065b | 31 | #include "rtx_core_cm.h" |
kadonotakashi | 0:8fdf9a60065b | 32 | #endif |
kadonotakashi | 0:8fdf9a60065b | 33 | extern "C" { |
kadonotakashi | 0:8fdf9a60065b | 34 | #include "rtx_lib.h" |
kadonotakashi | 0:8fdf9a60065b | 35 | #if defined(TARGET_CORTEX_A) |
kadonotakashi | 0:8fdf9a60065b | 36 | #include "irq_ctrl.h" |
kadonotakashi | 0:8fdf9a60065b | 37 | #endif |
kadonotakashi | 0:8fdf9a60065b | 38 | } |
kadonotakashi | 0:8fdf9a60065b | 39 | |
kadonotakashi | 0:8fdf9a60065b | 40 | #if (defined(NO_SYSTICK)) |
kadonotakashi | 0:8fdf9a60065b | 41 | /** |
kadonotakashi | 0:8fdf9a60065b | 42 | * Return an IRQ number that can be used in the absence of SysTick |
kadonotakashi | 0:8fdf9a60065b | 43 | * |
kadonotakashi | 0:8fdf9a60065b | 44 | * @return Free IRQ number that can be used |
kadonotakashi | 0:8fdf9a60065b | 45 | */ |
kadonotakashi | 0:8fdf9a60065b | 46 | extern "C" IRQn_Type mbed_get_m0_tick_irqn(void); |
kadonotakashi | 0:8fdf9a60065b | 47 | #endif |
kadonotakashi | 0:8fdf9a60065b | 48 | |
kadonotakashi | 0:8fdf9a60065b | 49 | #if defined(TARGET_CORTEX_A) |
kadonotakashi | 0:8fdf9a60065b | 50 | extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void); |
kadonotakashi | 0:8fdf9a60065b | 51 | #endif |
kadonotakashi | 0:8fdf9a60065b | 52 | |
kadonotakashi | 0:8fdf9a60065b | 53 | namespace rtos { |
kadonotakashi | 0:8fdf9a60065b | 54 | namespace internal { |
kadonotakashi | 0:8fdf9a60065b | 55 | |
kadonotakashi | 0:8fdf9a60065b | 56 | SysTimer::SysTimer() : |
kadonotakashi | 0:8fdf9a60065b | 57 | TimerEvent(get_lp_ticker_data()), _start_time(0), _tick(0) |
kadonotakashi | 0:8fdf9a60065b | 58 | { |
kadonotakashi | 0:8fdf9a60065b | 59 | _start_time = ticker_read_us(_ticker_data); |
kadonotakashi | 0:8fdf9a60065b | 60 | _suspend_time_passed = true; |
kadonotakashi | 0:8fdf9a60065b | 61 | _suspended = false; |
kadonotakashi | 0:8fdf9a60065b | 62 | } |
kadonotakashi | 0:8fdf9a60065b | 63 | |
kadonotakashi | 0:8fdf9a60065b | 64 | SysTimer::SysTimer(const ticker_data_t *data) : |
kadonotakashi | 0:8fdf9a60065b | 65 | TimerEvent(data), _start_time(0), _tick(0) |
kadonotakashi | 0:8fdf9a60065b | 66 | { |
kadonotakashi | 0:8fdf9a60065b | 67 | _start_time = ticker_read_us(_ticker_data); |
kadonotakashi | 0:8fdf9a60065b | 68 | } |
kadonotakashi | 0:8fdf9a60065b | 69 | |
kadonotakashi | 0:8fdf9a60065b | 70 | void SysTimer::setup_irq() |
kadonotakashi | 0:8fdf9a60065b | 71 | { |
kadonotakashi | 0:8fdf9a60065b | 72 | #if (defined(NO_SYSTICK) && !defined (TARGET_CORTEX_A)) |
kadonotakashi | 0:8fdf9a60065b | 73 | NVIC_SetVector(mbed_get_m0_tick_irqn(), (uint32_t)SysTick_Handler); |
kadonotakashi | 0:8fdf9a60065b | 74 | NVIC_SetPriority(mbed_get_m0_tick_irqn(), 0xFF); /* RTOS requires lowest priority */ |
kadonotakashi | 0:8fdf9a60065b | 75 | NVIC_EnableIRQ(mbed_get_m0_tick_irqn()); |
kadonotakashi | 0:8fdf9a60065b | 76 | #else |
kadonotakashi | 0:8fdf9a60065b | 77 | // Ensure SysTick has the correct priority as it is still used |
kadonotakashi | 0:8fdf9a60065b | 78 | // to trigger software interrupts on each tick. The period does |
kadonotakashi | 0:8fdf9a60065b | 79 | // not matter since it will never start counting. |
kadonotakashi | 0:8fdf9a60065b | 80 | OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER); |
kadonotakashi | 0:8fdf9a60065b | 81 | #endif |
kadonotakashi | 0:8fdf9a60065b | 82 | } |
kadonotakashi | 0:8fdf9a60065b | 83 | |
kadonotakashi | 0:8fdf9a60065b | 84 | void SysTimer::suspend(uint32_t ticks) |
kadonotakashi | 0:8fdf9a60065b | 85 | { |
kadonotakashi | 0:8fdf9a60065b | 86 | core_util_critical_section_enter(); |
kadonotakashi | 0:8fdf9a60065b | 87 | |
kadonotakashi | 0:8fdf9a60065b | 88 | remove(); |
kadonotakashi | 0:8fdf9a60065b | 89 | schedule_tick(ticks); |
kadonotakashi | 0:8fdf9a60065b | 90 | _suspend_time_passed = false; |
kadonotakashi | 0:8fdf9a60065b | 91 | _suspended = true; |
kadonotakashi | 0:8fdf9a60065b | 92 | |
kadonotakashi | 0:8fdf9a60065b | 93 | core_util_critical_section_exit(); |
kadonotakashi | 0:8fdf9a60065b | 94 | } |
kadonotakashi | 0:8fdf9a60065b | 95 | |
kadonotakashi | 0:8fdf9a60065b | 96 | bool SysTimer::suspend_time_passed() |
kadonotakashi | 0:8fdf9a60065b | 97 | { |
kadonotakashi | 0:8fdf9a60065b | 98 | return _suspend_time_passed; |
kadonotakashi | 0:8fdf9a60065b | 99 | } |
kadonotakashi | 0:8fdf9a60065b | 100 | |
kadonotakashi | 0:8fdf9a60065b | 101 | uint32_t SysTimer::resume() |
kadonotakashi | 0:8fdf9a60065b | 102 | { |
kadonotakashi | 0:8fdf9a60065b | 103 | core_util_critical_section_enter(); |
kadonotakashi | 0:8fdf9a60065b | 104 | |
kadonotakashi | 0:8fdf9a60065b | 105 | _suspended = false; |
kadonotakashi | 0:8fdf9a60065b | 106 | _suspend_time_passed = true; |
kadonotakashi | 0:8fdf9a60065b | 107 | remove(); |
kadonotakashi | 0:8fdf9a60065b | 108 | |
kadonotakashi | 0:8fdf9a60065b | 109 | uint64_t new_tick = (ticker_read_us(_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000; |
kadonotakashi | 0:8fdf9a60065b | 110 | if (new_tick > _tick) { |
kadonotakashi | 0:8fdf9a60065b | 111 | // Don't update to the current tick. Instead, update to the |
kadonotakashi | 0:8fdf9a60065b | 112 | // previous tick and let the SysTick handler increment it |
kadonotakashi | 0:8fdf9a60065b | 113 | // to the current value. This allows scheduling restart |
kadonotakashi | 0:8fdf9a60065b | 114 | // successfully after the OS is resumed. |
kadonotakashi | 0:8fdf9a60065b | 115 | new_tick--; |
kadonotakashi | 0:8fdf9a60065b | 116 | } |
kadonotakashi | 0:8fdf9a60065b | 117 | uint32_t elapsed_ticks = new_tick - _tick; |
kadonotakashi | 0:8fdf9a60065b | 118 | _tick = new_tick; |
kadonotakashi | 0:8fdf9a60065b | 119 | |
kadonotakashi | 0:8fdf9a60065b | 120 | core_util_critical_section_exit(); |
kadonotakashi | 0:8fdf9a60065b | 121 | return elapsed_ticks; |
kadonotakashi | 0:8fdf9a60065b | 122 | } |
kadonotakashi | 0:8fdf9a60065b | 123 | |
kadonotakashi | 0:8fdf9a60065b | 124 | void SysTimer::schedule_tick(uint32_t delta) |
kadonotakashi | 0:8fdf9a60065b | 125 | { |
kadonotakashi | 0:8fdf9a60065b | 126 | core_util_critical_section_enter(); |
kadonotakashi | 0:8fdf9a60065b | 127 | |
kadonotakashi | 0:8fdf9a60065b | 128 | insert_absolute(_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ); |
kadonotakashi | 0:8fdf9a60065b | 129 | |
kadonotakashi | 0:8fdf9a60065b | 130 | core_util_critical_section_exit(); |
kadonotakashi | 0:8fdf9a60065b | 131 | } |
kadonotakashi | 0:8fdf9a60065b | 132 | |
kadonotakashi | 0:8fdf9a60065b | 133 | void SysTimer::cancel_tick() |
kadonotakashi | 0:8fdf9a60065b | 134 | { |
kadonotakashi | 0:8fdf9a60065b | 135 | core_util_critical_section_enter(); |
kadonotakashi | 0:8fdf9a60065b | 136 | |
kadonotakashi | 0:8fdf9a60065b | 137 | remove(); |
kadonotakashi | 0:8fdf9a60065b | 138 | |
kadonotakashi | 0:8fdf9a60065b | 139 | core_util_critical_section_exit(); |
kadonotakashi | 0:8fdf9a60065b | 140 | } |
kadonotakashi | 0:8fdf9a60065b | 141 | |
kadonotakashi | 0:8fdf9a60065b | 142 | uint32_t SysTimer::get_tick() |
kadonotakashi | 0:8fdf9a60065b | 143 | { |
kadonotakashi | 0:8fdf9a60065b | 144 | return _tick & 0xFFFFFFFF; |
kadonotakashi | 0:8fdf9a60065b | 145 | } |
kadonotakashi | 0:8fdf9a60065b | 146 | |
kadonotakashi | 0:8fdf9a60065b | 147 | us_timestamp_t SysTimer::get_time() |
kadonotakashi | 0:8fdf9a60065b | 148 | { |
kadonotakashi | 0:8fdf9a60065b | 149 | return ticker_read_us(_ticker_data); |
kadonotakashi | 0:8fdf9a60065b | 150 | } |
kadonotakashi | 0:8fdf9a60065b | 151 | |
kadonotakashi | 0:8fdf9a60065b | 152 | SysTimer::~SysTimer() |
kadonotakashi | 0:8fdf9a60065b | 153 | { |
kadonotakashi | 0:8fdf9a60065b | 154 | } |
kadonotakashi | 0:8fdf9a60065b | 155 | |
kadonotakashi | 0:8fdf9a60065b | 156 | void SysTimer::_set_irq_pending() |
kadonotakashi | 0:8fdf9a60065b | 157 | { |
kadonotakashi | 0:8fdf9a60065b | 158 | // Protected function synchronized externally |
kadonotakashi | 0:8fdf9a60065b | 159 | |
kadonotakashi | 0:8fdf9a60065b | 160 | #if (defined(NO_SYSTICK)) |
kadonotakashi | 0:8fdf9a60065b | 161 | NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn()); |
kadonotakashi | 0:8fdf9a60065b | 162 | #elif (TARGET_CORTEX_A) |
kadonotakashi | 0:8fdf9a60065b | 163 | IRQ_SetPending(mbed_get_a9_tick_irqn()); |
kadonotakashi | 0:8fdf9a60065b | 164 | #else |
kadonotakashi | 0:8fdf9a60065b | 165 | SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; |
kadonotakashi | 0:8fdf9a60065b | 166 | #endif |
kadonotakashi | 0:8fdf9a60065b | 167 | } |
kadonotakashi | 0:8fdf9a60065b | 168 | |
kadonotakashi | 0:8fdf9a60065b | 169 | void SysTimer::_increment_tick() |
kadonotakashi | 0:8fdf9a60065b | 170 | { |
kadonotakashi | 0:8fdf9a60065b | 171 | // Protected function synchronized externally |
kadonotakashi | 0:8fdf9a60065b | 172 | |
kadonotakashi | 0:8fdf9a60065b | 173 | _tick++; |
kadonotakashi | 0:8fdf9a60065b | 174 | } |
kadonotakashi | 0:8fdf9a60065b | 175 | |
kadonotakashi | 0:8fdf9a60065b | 176 | void SysTimer::handler() |
kadonotakashi | 0:8fdf9a60065b | 177 | { |
kadonotakashi | 0:8fdf9a60065b | 178 | core_util_critical_section_enter(); |
kadonotakashi | 0:8fdf9a60065b | 179 | |
kadonotakashi | 0:8fdf9a60065b | 180 | if (_suspended) { |
kadonotakashi | 0:8fdf9a60065b | 181 | _suspend_time_passed = true; |
kadonotakashi | 0:8fdf9a60065b | 182 | } else { |
kadonotakashi | 0:8fdf9a60065b | 183 | _set_irq_pending(); |
kadonotakashi | 0:8fdf9a60065b | 184 | _increment_tick(); |
kadonotakashi | 0:8fdf9a60065b | 185 | schedule_tick(); |
kadonotakashi | 0:8fdf9a60065b | 186 | } |
kadonotakashi | 0:8fdf9a60065b | 187 | |
kadonotakashi | 0:8fdf9a60065b | 188 | core_util_critical_section_exit(); |
kadonotakashi | 0:8fdf9a60065b | 189 | } |
kadonotakashi | 0:8fdf9a60065b | 190 | |
kadonotakashi | 0:8fdf9a60065b | 191 | } |
kadonotakashi | 0:8fdf9a60065b | 192 | } |
kadonotakashi | 0:8fdf9a60065b | 193 | |
kadonotakashi | 0:8fdf9a60065b | 194 | #endif |