diff --git a/events/source/equeue_mbed.cpp b/events/source/equeue_mbed.cpp index 2380df4..9d9deae 100644 --- a/events/source/equeue_mbed.cpp +++ b/events/source/equeue_mbed.cpp @@ -38,7 +38,7 @@ #if MBED_CONF_RTOS_API_PRESENT #include "rtos/Kernel.h" -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" void equeue_tick_init() { diff --git a/platform/include/platform/internal/SysTimer.h b/platform/include/platform/internal/SysTimer.h new file mode 100644 index 0000000..229d535 --- /dev/null +++ b/platform/include/platform/internal/SysTimer.h @@ -0,0 +1,264 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2019 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SYS_TIMER_H +#define MBED_SYS_TIMER_H + +#include "platform/NonCopyable.h" +#include "platform/mbed_atomic.h" +#include "drivers/TimerEvent.h" +#include +#include "cmsis.h" + +extern "C" { +#if defined(TARGET_CORTEX_A) +#include "irq_ctrl.h" +#endif +} + +namespace mbed { +namespace internal { + +/** + * \defgroup mbed_SysTimer SysTimer class + * \ingroup platform-internal-api + * @{ + */ + +/** + * The SysTimer class is used to provide timing for system suspension, and + * the idle loop in TICKLESS mode. + * + * Template for speed for testing - only one instance will be used normally. + * + * @note SysTimer is not the part of Mbed API. + */ +template +class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable > { +public: + + /* pseudo-Clock for our ticks - see TickerDataClock for more discussion */ + using rep = uint64_t; + using period = Period; + using duration = std::chrono::duration; + using time_point = std::chrono::time_point; + static const bool is_steady = false; + + /** duration type used for underlying high-res timer */ + using highres_duration = TickerDataClock::duration; + /** time_point type used for underlying high-res timer */ + using highres_time_point = TickerDataClock::time_point; + /** period of underlying high-res timer */ + using highres_period = TickerDataClock::period; + + static_assert(std::ratio_divide::den == 1, "Tick period must be an exact multiple of highres time period"); + + /** + * Default constructor uses LPTICKER if available (so the timer will + * continue to run in deep sleep), else USTICKER. + */ + SysTimer(); + + SysTimer(const ticker_data_t *data); + +protected: + ~SysTimer(); + +public: + /** + * Get the interrupt number for the tick + * + * @return interrupt number + */ +#if TARGET_CORTEX_A + static IRQn_ID_t get_irq_number(); +#elif TARGET_CORTEX_M + static IRQn_Type get_irq_number(); +#endif + + /** + * Set the wake time + * + * Schedules an interrupt to cause wake-up in time for the event. Interrupt + * may be arranged early to account for latency. If the time has already + * passed, no interrupt will be scheduled. + * + * This is called from outside a critical section, as it is known to be + * a slow operation. + * + * If the wake time is already set, this is a no-op. But that check is racy, + * which means wake_time_set() should be rechecked after taking a critical + * section. + * + * As a side-effect, this clears the unacknowledged tick count - the caller + * is expected to use update_and_get_tick() after the suspend operation. + * + * @param at Wake up tick + * @warning If the ticker tick is already scheduled it needs to be cancelled first! + */ + void set_wake_time(time_point at); + + /** + * Check whether the wake time has passed + * + * This is a fast operation, based on checking whether the wake interrupt + * has run. + * + * @return true if the specified wake tick has passed + */ + bool wake_time_passed() const + { + return core_util_atomic_load_bool(&_wake_time_passed); + } + + /** + * Check whether wake timer is active + * + * @return true if the wake timer is active. + */ + bool wake_time_set() const + { + return core_util_atomic_load_bool(&_wake_time_set); + } + + /** + * Cancel any pending wake + */ + void cancel_wake(); + + /** + * Schedule an os tick to fire + * + * Ticks will be rescheduled automatically every tick until cancel_tick is called. + * + * A tick will be fired immediately if there are any unacknowledged ticks. + * + * @warning If a tick is already scheduled it needs to be cancelled first! + */ + void start_tick(); + + /** + * Acknowledge an os tick + * + * This will queue another os tick immediately if the os is running slow + */ + void acknowledge_tick(); + + /** + * Prevent any more scheduled ticks from triggering + * + * If called from OS tick context, there may be remaining unacknowledged ticks. + */ + void cancel_tick(); + + /** + * Check whether ticker is active + * + * Each time the tick interrupt fires, it is automatically rescheduled, + * so this will remain true once the tick is started, except during + * processing. + * + * @return true if the ticker is active. + */ + bool ticking() const + { + return core_util_atomic_load_bool(&_ticking); + } + + /** + * Check unacknowledged ticks + * + * Returns the count of how many times the OS timer has been queued minus + * the number of times is has been acknowledged. + * + * get_tick() - unacknowledged_ticks() should equal the OS's tick count, + * although such a calculation is not atomic if the ticker is currently running. + * + * @return number of unacknowledged ticks + */ + std::chrono::duration unacknowledged_ticks() const + { + return std::chrono::duration(core_util_atomic_load_u8(&_unacknowledged_ticks)); + } + + /** Get the current tick count + * + * This count is updated by the ticker interrupt, if the ticker interrupt + * is running. It the ticker interrupt is not running, update_and_get_tick() + * should be used instead. + * + * This indicates how many ticks have been generated by the tick interrupt. + * The os_timer should equal this number minus the number of unacknowledged ticks. + * + * @return The number of ticks since timer creation. + */ + time_point get_tick() const; + + /** Update and get the current tick count + * + * This is a slow operation that reads the timer and adjusts for elapsed time. + * Can only be used when the ticker is not running, as there is no IRQ + * synchronization. + * + * This clears the unacknowledged tick counter - the caller is assumed to update + * their timer based on this return. + * + * @return The number of ticks since timer creation. + */ + time_point update_and_get_tick(); + + /** + * Returns time since last tick + * + * @return Relative time in microseconds + */ + highres_duration get_time_since_tick() const; + + /** + * Get the time + * + * Returns the instantaneous precision time from underlying timer. + * This is a slow operation so should not be called from critical sections. + * + * @return Current time in microseconds + */ + highres_time_point get_time() const; + +protected: + using highres_duration_u32 = std::chrono::duration; + void handler() override; + void _increment_tick(); + void _schedule_tick(); + duration _elapsed_ticks() const; + static void _set_irq_pending(); + static void _clear_irq_pending(); + const highres_time_point _epoch; + highres_time_point _time; + uint64_t _tick; + uint8_t _unacknowledged_ticks; + bool _wake_time_set; + bool _wake_time_passed; + bool _wake_early; + bool _ticking; + bool _deep_sleep_locked; +}; + +/** @} */ + +} +} + +#endif diff --git a/platform/include/platform/internal/mbed_error_hist.h b/platform/include/platform/internal/mbed_error_hist.h new file mode 100644 index 0000000..0bec541 --- /dev/null +++ b/platform/include/platform/internal/mbed_error_hist.h @@ -0,0 +1,122 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ERROR_HIST_H +#define MBED_ERROR_HIST_H + +#ifndef MBED_CONF_PLATFORM_ERROR_HIST_SIZE +#define MBED_CONF_PLATFORM_ERROR_HIST_SIZE 4 +#else +#if MBED_CONF_PLATFORM_ERROR_HIST_SIZE == 0 +#define MBED_CONF_PLATFORM_ERROR_HIST_SIZE 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** \ingroup mbed-os-internal */ +/** \addtogroup platform-internal-api */ +/** @{*/ + +/* + * Puts/Adds an error entry into the error history list + * + * @param error_ctx pointer to the mbed_error_ctx struct with the error context + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_WRITE_FAILED if writing to file failed + * MBED_ERROR_INVALID_ARGUMENT if path is not valid + * + * + */ +mbed_error_status_t mbed_error_hist_put(mbed_error_ctx *error_ctx); + +/* + * Reads the error entry from the error list with the specified index + * + * @param index Index of the error context to be retrieved. It starts from 0 and 0 is the oldest. + * @param error_ctx pointer to the mbed_error_ctx struct where the error context will be filled, this should be allocated by the caller + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_WRITE_FAILED if writing to file failed + * MBED_ERROR_INVALID_ARGUMENT if path is not valid + * + * + */ +mbed_error_status_t mbed_error_hist_get(int index, mbed_error_ctx *error_ctx); + +/* + * Gets a reference to the next error entry in the error log where in the error ctx can be filled in. + * Its like reserving the next error entry to fill in the error info + * + * @return Returns the pointer to the next error ctx entry + * + * + */ +mbed_error_ctx *mbed_error_hist_get_entry(void); + +/* + * Reads the last(latest) error entry from the error history + * + * @param error_ctx pointer to the mbed_error_ctx struct where the error context will be filled, this should be allocated by the caller + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_WRITE_FAILED if writing to file failed + * MBED_ERROR_INVALID_ARGUMENT if path is not valid + * + * + */ +mbed_error_status_t mbed_error_hist_get_last_error(mbed_error_ctx *error_ctx); + +/* + * Returns the number of error entries in the error history list + * + * @return Number of entries in the history list + * + * + */ +int mbed_error_hist_get_count(void); + +/* + * Resets the error log by resetting the number of errors to 0 and clears all previous errors in the history list + * + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_WRITE_FAILED if writing to file failed + * MBED_ERROR_INVALID_ARGUMENT if path is not valid + * + * + */ +mbed_error_status_t mbed_error_hist_reset(void); + +/* + * Saves the error log information to a file + * + * @param path path to the file in the filesystem + * @return 0 or MBED_SUCCESS on success. + * MBED_ERROR_WRITE_FAILED if writing to file failed + * MBED_ERROR_INVALID_ARGUMENT if path is not valid + * + * @note Filesystem support is required in order for this function to work. + * + */ +mbed_error_status_t mbed_save_error_hist(const char *path); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif diff --git a/platform/include/platform/internal/mbed_os_timer.h b/platform/include/platform/internal/mbed_os_timer.h new file mode 100644 index 0000000..29d78c1 --- /dev/null +++ b/platform/include/platform/internal/mbed_os_timer.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2006-2019, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_MBED_SLEEP_TIMER_H +#define MBED_MBED_SLEEP_TIMER_H + +#include +#include "platform/internal/SysTimer.h" + +#if MBED_CONF_RTOS_PRESENT +extern "C" { +#include "rtx_lib.h" +} +#endif + +namespace mbed { +namespace internal { + +#if MBED_CONF_RTOS_PRESENT +using OsTimer = SysTimer>; +#else +using OsTimer = SysTimer; +#endif + +/* A SysTimer is used to provide the timed sleep - this provides access to share it for + * other use, such as ticks. If accessed this way, it must not be in use when a sleep function below is called. + */ +extern OsTimer *os_timer; +OsTimer *init_os_timer(); + +/** A C++11 chrono TrivialClock for os_timer + * + * Due to the nature of OsTimer/SysTimer, this does not have a single `now` method, but has + * multiple ways to report the current state: + * + * High-res timeline ------------------------------------------------------------- + * Ticks | a | b | b | b | c | c | c | c | c | d ^ + * ^ ^ ^ os_timer->get_time() + * acknowledged_ticks() reported_ticks() now() + * + * (a) is time read from hardware by OsTimer, reported to the user of OsTimer, and acknowledged by that user. + * (b) is time read from hardware by OsTimer, reported to the user of OsTimer, but not yet acknowledged. + * (c) is time already elapsed in the hardware but yet to be read and processed as ticks by OsTimer. + * (d) is time already elapsed in the hardware that doesn't yet form a tick. + * + * Time is "reported" either by: + * * calls to the OsTimer's handler following start_tick - these must be acknowledged + * * the result of OsTimer::update_and_get_tick() / OsClock::now() - calling this implies acknowledgment. + * + * As such `now()` is used when the ticker is not in use - it processes ticks that would have been + * processed by the tick handler. If the ticker is in uses `reported_ticks` or `acknowleged_ticks` must be used. + * + * @note To fit better into the chrono framework, OsClock uses + * chrono::milliseconds as its representation, which makes it signed + * and at least 45 bits, so it will be int64_t or equivalent, unlike + * OsTimer which uses uint64_t rep. + */ +struct OsClock { + /* Standard TrivialClock fields */ + using period = OsTimer::period; + using rep = std::chrono::milliseconds::rep; + using duration = std::chrono::duration; // == std::chrono::milliseconds, if period is std::milli + using time_point = std::chrono::time_point; + static constexpr bool is_steady = true; + // Read the hardware, and return the updated time_point. + // Initialize the timing system if necessary - this could be the first call. + // See SysTimer::update_and_get_tick for more details. + static time_point now() + { + // We are a real Clock with a well-defined epoch. As such we distinguish ourselves + // from the less-well-defined SysTimer pseudo-Clock. This means our time_points + // are not convertible, so need to fiddle here. + return time_point(init_os_timer()->update_and_get_tick().time_since_epoch()); + } + // Return the current reported tick count, without update. + // Assumes timer has already been initialized, as ticker should have been in use to + // keep that tick count up-to-date. See SysTimer::get_tick for more details. + static time_point reported_ticks() + { + return time_point(os_timer->get_tick().time_since_epoch()); + } + // Return the acknowledged tick count. + static time_point acknowledged_ticks() + { + return reported_ticks() - os_timer->unacknowledged_ticks(); + } + // Slightly-optimised variant of OsClock::now() that assumes os_timer is initialised. + static time_point now_with_init_done() + { + return time_point(os_timer->update_and_get_tick().time_since_epoch()); + } + static void set_wake_time(time_point wake_time) + { + return os_timer->set_wake_time(OsTimer::time_point(wake_time.time_since_epoch())); + } + /* Extension to + * make it easy to use 32-bit durations for some APIs, as we historically do */ + using duration_u32 = std::chrono::duration; +}; + +/* time_point::max() is effectively "sleep forever" */ +OsClock::time_point do_timed_sleep_absolute(OsClock::time_point wake_time, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); + +#if MBED_CONF_RTOS_PRESENT +/* Maximum sleep time is 2^32-1 ticks; timer is always set to achieve this */ +/* Assumes that ticker has been in use prior to call, so restricted to RTOS use */ +OsClock::duration_u32 do_timed_sleep_relative_to_acknowledged_ticks(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); +#else + +void do_untimed_sleep(bool (*wake_predicate)(void *), void *wake_predicate_handle = NULL); + +/* duration_u32::max() delay is sleep forever */ + +void do_timed_sleep_relative_or_forever(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); + +#endif + +} +} + +#endif diff --git a/platform/source/SysTimer.cpp b/platform/source/SysTimer.cpp index 7dac341..2345e68 100644 --- a/platform/source/SysTimer.cpp +++ b/platform/source/SysTimer.cpp @@ -22,7 +22,7 @@ #include "mbed_assert.h" #include "platform/mbed_power_mgmt.h" #include "platform/CriticalSectionLock.h" -#include "source/SysTimer.h" +#include "platform/internal/SysTimer.h" extern "C" { #if MBED_CONF_RTOS_PRESENT #include "rtx_lib.h" diff --git a/platform/source/SysTimer.h b/platform/source/SysTimer.h deleted file mode 100644 index 229d535..0000000 --- a/platform/source/SysTimer.h +++ /dev/null @@ -1,264 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2019 ARM Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_SYS_TIMER_H -#define MBED_SYS_TIMER_H - -#include "platform/NonCopyable.h" -#include "platform/mbed_atomic.h" -#include "drivers/TimerEvent.h" -#include -#include "cmsis.h" - -extern "C" { -#if defined(TARGET_CORTEX_A) -#include "irq_ctrl.h" -#endif -} - -namespace mbed { -namespace internal { - -/** - * \defgroup mbed_SysTimer SysTimer class - * \ingroup platform-internal-api - * @{ - */ - -/** - * The SysTimer class is used to provide timing for system suspension, and - * the idle loop in TICKLESS mode. - * - * Template for speed for testing - only one instance will be used normally. - * - * @note SysTimer is not the part of Mbed API. - */ -template -class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable > { -public: - - /* pseudo-Clock for our ticks - see TickerDataClock for more discussion */ - using rep = uint64_t; - using period = Period; - using duration = std::chrono::duration; - using time_point = std::chrono::time_point; - static const bool is_steady = false; - - /** duration type used for underlying high-res timer */ - using highres_duration = TickerDataClock::duration; - /** time_point type used for underlying high-res timer */ - using highres_time_point = TickerDataClock::time_point; - /** period of underlying high-res timer */ - using highres_period = TickerDataClock::period; - - static_assert(std::ratio_divide::den == 1, "Tick period must be an exact multiple of highres time period"); - - /** - * Default constructor uses LPTICKER if available (so the timer will - * continue to run in deep sleep), else USTICKER. - */ - SysTimer(); - - SysTimer(const ticker_data_t *data); - -protected: - ~SysTimer(); - -public: - /** - * Get the interrupt number for the tick - * - * @return interrupt number - */ -#if TARGET_CORTEX_A - static IRQn_ID_t get_irq_number(); -#elif TARGET_CORTEX_M - static IRQn_Type get_irq_number(); -#endif - - /** - * Set the wake time - * - * Schedules an interrupt to cause wake-up in time for the event. Interrupt - * may be arranged early to account for latency. If the time has already - * passed, no interrupt will be scheduled. - * - * This is called from outside a critical section, as it is known to be - * a slow operation. - * - * If the wake time is already set, this is a no-op. But that check is racy, - * which means wake_time_set() should be rechecked after taking a critical - * section. - * - * As a side-effect, this clears the unacknowledged tick count - the caller - * is expected to use update_and_get_tick() after the suspend operation. - * - * @param at Wake up tick - * @warning If the ticker tick is already scheduled it needs to be cancelled first! - */ - void set_wake_time(time_point at); - - /** - * Check whether the wake time has passed - * - * This is a fast operation, based on checking whether the wake interrupt - * has run. - * - * @return true if the specified wake tick has passed - */ - bool wake_time_passed() const - { - return core_util_atomic_load_bool(&_wake_time_passed); - } - - /** - * Check whether wake timer is active - * - * @return true if the wake timer is active. - */ - bool wake_time_set() const - { - return core_util_atomic_load_bool(&_wake_time_set); - } - - /** - * Cancel any pending wake - */ - void cancel_wake(); - - /** - * Schedule an os tick to fire - * - * Ticks will be rescheduled automatically every tick until cancel_tick is called. - * - * A tick will be fired immediately if there are any unacknowledged ticks. - * - * @warning If a tick is already scheduled it needs to be cancelled first! - */ - void start_tick(); - - /** - * Acknowledge an os tick - * - * This will queue another os tick immediately if the os is running slow - */ - void acknowledge_tick(); - - /** - * Prevent any more scheduled ticks from triggering - * - * If called from OS tick context, there may be remaining unacknowledged ticks. - */ - void cancel_tick(); - - /** - * Check whether ticker is active - * - * Each time the tick interrupt fires, it is automatically rescheduled, - * so this will remain true once the tick is started, except during - * processing. - * - * @return true if the ticker is active. - */ - bool ticking() const - { - return core_util_atomic_load_bool(&_ticking); - } - - /** - * Check unacknowledged ticks - * - * Returns the count of how many times the OS timer has been queued minus - * the number of times is has been acknowledged. - * - * get_tick() - unacknowledged_ticks() should equal the OS's tick count, - * although such a calculation is not atomic if the ticker is currently running. - * - * @return number of unacknowledged ticks - */ - std::chrono::duration unacknowledged_ticks() const - { - return std::chrono::duration(core_util_atomic_load_u8(&_unacknowledged_ticks)); - } - - /** Get the current tick count - * - * This count is updated by the ticker interrupt, if the ticker interrupt - * is running. It the ticker interrupt is not running, update_and_get_tick() - * should be used instead. - * - * This indicates how many ticks have been generated by the tick interrupt. - * The os_timer should equal this number minus the number of unacknowledged ticks. - * - * @return The number of ticks since timer creation. - */ - time_point get_tick() const; - - /** Update and get the current tick count - * - * This is a slow operation that reads the timer and adjusts for elapsed time. - * Can only be used when the ticker is not running, as there is no IRQ - * synchronization. - * - * This clears the unacknowledged tick counter - the caller is assumed to update - * their timer based on this return. - * - * @return The number of ticks since timer creation. - */ - time_point update_and_get_tick(); - - /** - * Returns time since last tick - * - * @return Relative time in microseconds - */ - highres_duration get_time_since_tick() const; - - /** - * Get the time - * - * Returns the instantaneous precision time from underlying timer. - * This is a slow operation so should not be called from critical sections. - * - * @return Current time in microseconds - */ - highres_time_point get_time() const; - -protected: - using highres_duration_u32 = std::chrono::duration; - void handler() override; - void _increment_tick(); - void _schedule_tick(); - duration _elapsed_ticks() const; - static void _set_irq_pending(); - static void _clear_irq_pending(); - const highres_time_point _epoch; - highres_time_point _time; - uint64_t _tick; - uint8_t _unacknowledged_ticks; - bool _wake_time_set; - bool _wake_time_passed; - bool _wake_early; - bool _ticking; - bool _deep_sleep_locked; -}; - -/** @} */ - -} -} - -#endif diff --git a/platform/source/mbed_error.c b/platform/source/mbed_error.c index c98ea68..17ec1cf 100644 --- a/platform/source/mbed_error.c +++ b/platform/source/mbed_error.c @@ -26,7 +26,7 @@ #include "platform/mbed_power_mgmt.h" #include "platform/mbed_stats.h" #include "platform/internal/mbed_fault_handler.h" -#include "source/mbed_error_hist.h" +#include "platform/internal/mbed_error_hist.h" #include "drivers/MbedCRC.h" #include "mbed_rtx.h" #ifdef MBED_CONF_RTOS_PRESENT diff --git a/platform/source/mbed_error_hist.c b/platform/source/mbed_error_hist.c index 8c3cf28..4b8f0ba 100644 --- a/platform/source/mbed_error_hist.c +++ b/platform/source/mbed_error_hist.c @@ -21,7 +21,7 @@ #include "platform/mbed_critical.h" #if MBED_CONF_PLATFORM_ERROR_HIST_ENABLED -#include "source/mbed_error_hist.h" +#include "platform/internal/mbed_error_hist.h" static mbed_error_ctx mbed_error_ctx_log[MBED_CONF_PLATFORM_ERROR_HIST_SIZE] = {0}; static int error_log_count = -1; diff --git a/platform/source/mbed_error_hist.h b/platform/source/mbed_error_hist.h deleted file mode 100644 index 0bec541..0000000 --- a/platform/source/mbed_error_hist.h +++ /dev/null @@ -1,122 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_ERROR_HIST_H -#define MBED_ERROR_HIST_H - -#ifndef MBED_CONF_PLATFORM_ERROR_HIST_SIZE -#define MBED_CONF_PLATFORM_ERROR_HIST_SIZE 4 -#else -#if MBED_CONF_PLATFORM_ERROR_HIST_SIZE == 0 -#define MBED_CONF_PLATFORM_ERROR_HIST_SIZE 1 -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** \ingroup mbed-os-internal */ -/** \addtogroup platform-internal-api */ -/** @{*/ - -/* - * Puts/Adds an error entry into the error history list - * - * @param error_ctx pointer to the mbed_error_ctx struct with the error context - * @return 0 or MBED_SUCCESS on success. - * MBED_ERROR_WRITE_FAILED if writing to file failed - * MBED_ERROR_INVALID_ARGUMENT if path is not valid - * - * - */ -mbed_error_status_t mbed_error_hist_put(mbed_error_ctx *error_ctx); - -/* - * Reads the error entry from the error list with the specified index - * - * @param index Index of the error context to be retrieved. It starts from 0 and 0 is the oldest. - * @param error_ctx pointer to the mbed_error_ctx struct where the error context will be filled, this should be allocated by the caller - * @return 0 or MBED_SUCCESS on success. - * MBED_ERROR_WRITE_FAILED if writing to file failed - * MBED_ERROR_INVALID_ARGUMENT if path is not valid - * - * - */ -mbed_error_status_t mbed_error_hist_get(int index, mbed_error_ctx *error_ctx); - -/* - * Gets a reference to the next error entry in the error log where in the error ctx can be filled in. - * Its like reserving the next error entry to fill in the error info - * - * @return Returns the pointer to the next error ctx entry - * - * - */ -mbed_error_ctx *mbed_error_hist_get_entry(void); - -/* - * Reads the last(latest) error entry from the error history - * - * @param error_ctx pointer to the mbed_error_ctx struct where the error context will be filled, this should be allocated by the caller - * @return 0 or MBED_SUCCESS on success. - * MBED_ERROR_WRITE_FAILED if writing to file failed - * MBED_ERROR_INVALID_ARGUMENT if path is not valid - * - * - */ -mbed_error_status_t mbed_error_hist_get_last_error(mbed_error_ctx *error_ctx); - -/* - * Returns the number of error entries in the error history list - * - * @return Number of entries in the history list - * - * - */ -int mbed_error_hist_get_count(void); - -/* - * Resets the error log by resetting the number of errors to 0 and clears all previous errors in the history list - * - * @return 0 or MBED_SUCCESS on success. - * MBED_ERROR_WRITE_FAILED if writing to file failed - * MBED_ERROR_INVALID_ARGUMENT if path is not valid - * - * - */ -mbed_error_status_t mbed_error_hist_reset(void); - -/* - * Saves the error log information to a file - * - * @param path path to the file in the filesystem - * @return 0 or MBED_SUCCESS on success. - * MBED_ERROR_WRITE_FAILED if writing to file failed - * MBED_ERROR_INVALID_ARGUMENT if path is not valid - * - * @note Filesystem support is required in order for this function to work. - * - */ -mbed_error_status_t mbed_save_error_hist(const char *path); - -#ifdef __cplusplus -} -#endif - -/**@}*/ - -#endif diff --git a/platform/source/mbed_os_timer.cpp b/platform/source/mbed_os_timer.cpp index ff87cbd..ce51d90 100644 --- a/platform/source/mbed_os_timer.cpp +++ b/platform/source/mbed_os_timer.cpp @@ -17,8 +17,8 @@ #include "platform/mbed_power_mgmt.h" #include "platform/CriticalSectionLock.h" -#include "source/SysTimer.h" -#include "source/mbed_os_timer.h" +#include "paltform/internal/SysTimer.h" +#include "platform/internal/mbed_os_timer.h" #include "us_ticker_api.h" #include "lp_ticker_api.h" #include "mbed_critical.h" diff --git a/platform/source/mbed_os_timer.h b/platform/source/mbed_os_timer.h deleted file mode 100644 index d206742..0000000 --- a/platform/source/mbed_os_timer.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2006-2019, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_MBED_SLEEP_TIMER_H -#define MBED_MBED_SLEEP_TIMER_H - -#include -#include "source/SysTimer.h" - -#if MBED_CONF_RTOS_PRESENT -extern "C" { -#include "rtx_lib.h" -} -#endif - -namespace mbed { -namespace internal { - -#if MBED_CONF_RTOS_PRESENT -using OsTimer = SysTimer>; -#else -using OsTimer = SysTimer; -#endif - -/* A SysTimer is used to provide the timed sleep - this provides access to share it for - * other use, such as ticks. If accessed this way, it must not be in use when a sleep function below is called. - */ -extern OsTimer *os_timer; -OsTimer *init_os_timer(); - -/** A C++11 chrono TrivialClock for os_timer - * - * Due to the nature of OsTimer/SysTimer, this does not have a single `now` method, but has - * multiple ways to report the current state: - * - * High-res timeline ------------------------------------------------------------- - * Ticks | a | b | b | b | c | c | c | c | c | d ^ - * ^ ^ ^ os_timer->get_time() - * acknowledged_ticks() reported_ticks() now() - * - * (a) is time read from hardware by OsTimer, reported to the user of OsTimer, and acknowledged by that user. - * (b) is time read from hardware by OsTimer, reported to the user of OsTimer, but not yet acknowledged. - * (c) is time already elapsed in the hardware but yet to be read and processed as ticks by OsTimer. - * (d) is time already elapsed in the hardware that doesn't yet form a tick. - * - * Time is "reported" either by: - * * calls to the OsTimer's handler following start_tick - these must be acknowledged - * * the result of OsTimer::update_and_get_tick() / OsClock::now() - calling this implies acknowledgment. - * - * As such `now()` is used when the ticker is not in use - it processes ticks that would have been - * processed by the tick handler. If the ticker is in uses `reported_ticks` or `acknowleged_ticks` must be used. - * - * @note To fit better into the chrono framework, OsClock uses - * chrono::milliseconds as its representation, which makes it signed - * and at least 45 bits, so it will be int64_t or equivalent, unlike - * OsTimer which uses uint64_t rep. - */ -struct OsClock { - /* Standard TrivialClock fields */ - using period = OsTimer::period; - using rep = std::chrono::milliseconds::rep; - using duration = std::chrono::duration; // == std::chrono::milliseconds, if period is std::milli - using time_point = std::chrono::time_point; - static constexpr bool is_steady = true; - // Read the hardware, and return the updated time_point. - // Initialize the timing system if necessary - this could be the first call. - // See SysTimer::update_and_get_tick for more details. - static time_point now() - { - // We are a real Clock with a well-defined epoch. As such we distinguish ourselves - // from the less-well-defined SysTimer pseudo-Clock. This means our time_points - // are not convertible, so need to fiddle here. - return time_point(init_os_timer()->update_and_get_tick().time_since_epoch()); - } - // Return the current reported tick count, without update. - // Assumes timer has already been initialized, as ticker should have been in use to - // keep that tick count up-to-date. See SysTimer::get_tick for more details. - static time_point reported_ticks() - { - return time_point(os_timer->get_tick().time_since_epoch()); - } - // Return the acknowledged tick count. - static time_point acknowledged_ticks() - { - return reported_ticks() - os_timer->unacknowledged_ticks(); - } - // Slightly-optimised variant of OsClock::now() that assumes os_timer is initialised. - static time_point now_with_init_done() - { - return time_point(os_timer->update_and_get_tick().time_since_epoch()); - } - static void set_wake_time(time_point wake_time) - { - return os_timer->set_wake_time(OsTimer::time_point(wake_time.time_since_epoch())); - } - /* Extension to - * make it easy to use 32-bit durations for some APIs, as we historically do */ - using duration_u32 = std::chrono::duration; -}; - -/* time_point::max() is effectively "sleep forever" */ -OsClock::time_point do_timed_sleep_absolute(OsClock::time_point wake_time, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); - -#if MBED_CONF_RTOS_PRESENT -/* Maximum sleep time is 2^32-1 ticks; timer is always set to achieve this */ -/* Assumes that ticker has been in use prior to call, so restricted to RTOS use */ -OsClock::duration_u32 do_timed_sleep_relative_to_acknowledged_ticks(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); -#else - -void do_untimed_sleep(bool (*wake_predicate)(void *), void *wake_predicate_handle = NULL); - -/* duration_u32::max() delay is sleep forever */ - -void do_timed_sleep_relative_or_forever(OsClock::duration_u32 wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL); - -#endif - -} -} - -#endif diff --git a/platform/source/mbed_thread.cpp b/platform/source/mbed_thread.cpp index 20cf156..8adce55 100644 --- a/platform/source/mbed_thread.cpp +++ b/platform/source/mbed_thread.cpp @@ -17,7 +17,7 @@ #include "platform/mbed_thread.h" #include "platform/mbed_critical.h" -#include "source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" /* If the RTOS is present, we call the RTOS API to do the work */ /* If the RTOS is not present, the RTOS API calls us to do the work */ diff --git a/rtos/include/rtos/Kernel.h b/rtos/include/rtos/Kernel.h index c653b16..b9e7c57 100644 --- a/rtos/include/rtos/Kernel.h +++ b/rtos/include/rtos/Kernel.h @@ -28,7 +28,7 @@ #include "rtos/mbed_rtos_types.h" #include "platform/mbed_toolchain.h" #if !MBED_CONF_RTOS_PRESENT -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" #endif diff --git a/rtos/source/EventFlags.cpp b/rtos/source/EventFlags.cpp index bd235cd..508f316 100644 --- a/rtos/source/EventFlags.cpp +++ b/rtos/source/EventFlags.cpp @@ -22,7 +22,7 @@ */ #include "rtos/EventFlags.h" #include "rtos/ThisThread.h" -#include "mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" #include #include "platform/mbed_error.h" #include "platform/mbed_assert.h" diff --git a/rtos/source/Kernel.cpp b/rtos/source/Kernel.cpp index 5f99e49..de0491a 100644 --- a/rtos/source/Kernel.cpp +++ b/rtos/source/Kernel.cpp @@ -25,7 +25,7 @@ #include "rtos_idle.h" #include "rtos_handlers.h" #include "platform/mbed_critical.h" -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" #if !MBED_CONF_RTOS_PRESENT /* If the RTOS is not present, we call mbed_thread.cpp to do the work */ diff --git a/rtos/source/Semaphore.cpp b/rtos/source/Semaphore.cpp index 204bfa7..c36afde 100644 --- a/rtos/source/Semaphore.cpp +++ b/rtos/source/Semaphore.cpp @@ -25,7 +25,7 @@ #include "platform/mbed_assert.h" #include "platform/mbed_critical.h" #include "platform/mbed_error.h" -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" #include diff --git a/rtos/source/TARGET_CORTEX/mbed_rtx_idle.cpp b/rtos/source/TARGET_CORTEX/mbed_rtx_idle.cpp index 1fdf070..5fe187e 100644 --- a/rtos/source/TARGET_CORTEX/mbed_rtx_idle.cpp +++ b/rtos/source/TARGET_CORTEX/mbed_rtx_idle.cpp @@ -24,7 +24,7 @@ #include "rtos/source/rtos_idle.h" #include "rtos/Kernel.h" #include "platform/mbed_power_mgmt.h" -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" #include "TimerEvent.h" #include "mbed_critical.h" #include "mbed_assert.h" diff --git a/rtos/source/ThisThread.cpp b/rtos/source/ThisThread.cpp index fe532da..5494dcc 100644 --- a/rtos/source/ThisThread.cpp +++ b/rtos/source/ThisThread.cpp @@ -29,7 +29,7 @@ #include "platform/CriticalSectionLock.h" #include "platform/mbed_assert.h" #include "platform/mbed_critical.h" -#include "platform/source/mbed_os_timer.h" +#include "platform/internal/mbed_os_timer.h" using std::milli; using std::chrono::duration; diff --git a/rtos/tests/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp b/rtos/tests/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp index 6999f01..067848b 100644 --- a/rtos/tests/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp +++ b/rtos/tests/TESTS/mbedmicro-rtos-mbed/systimer/main.cpp @@ -21,7 +21,7 @@ #include "utest.h" #include "ticker_api.h" -#include "platform/source/SysTimer.h" +#include "platform/internal/SysTimer.h" using namespace std::chrono;