diff --git a/mbed.h b/mbed.h index 4f6f6f6024..3e851b4d36 100644 --- a/mbed.h +++ b/mbed.h @@ -87,6 +87,7 @@ #include "platform/LocalFileSystem.h" #include "drivers/InterruptIn.h" #include "platform/mbed_wait_api.h" +#include "platform/mbed_thread.h" #include "hal/sleep_api.h" #include "platform/Atomic.h" #include "platform/mbed_power_mgmt.h" diff --git a/platform/mbed_thread.cpp b/platform/mbed_thread.cpp new file mode 100644 index 0000000000..0cdcae1549 --- /dev/null +++ b/platform/mbed_thread.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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. + */ + +#include "platform/mbed_thread.h" +#include "platform/mbed_critical.h" +#include "platform/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 */ +#if MBED_CONF_RTOS_PRESENT +#include "rtos/Kernel.h" +#include "rtos/ThisThread.h" +#endif + +extern "C" { + + uint64_t get_ms_count(void) + { +#if MBED_CONF_RTOS_PRESENT + return rtos::Kernel::get_ms_count(); +#else + return mbed::internal::init_os_timer()->update_and_get_tick(); +#endif + } + + void thread_sleep_for(uint32_t millisec) + { +#if MBED_CONF_RTOS_PRESENT + rtos::ThisThread::sleep_for(millisec); +#else + // Undocumented, but osDelay(UINT32_MAX) does actually sleep forever + mbed::internal::do_timed_sleep_relative_or_forever(millisec); +#endif + } + + void thread_sleep_until(uint64_t millisec) + { +#if MBED_CONF_RTOS_PRESENT + rtos::ThisThread::sleep_until(millisec); +#else + mbed::internal::do_timed_sleep_absolute(millisec); +#endif + } + +} diff --git a/platform/mbed_thread.h b/platform/mbed_thread.h new file mode 100644 index 0000000000..6968ebd62f --- /dev/null +++ b/platform/mbed_thread.h @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + * Copyright (c) 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_THREAD_H +#define MBED_THREAD_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic thread functions. + * + * These are C versions of functions provided in C++ via rtos::Thread and rtos::ThisThread + */ + +/** Read the current RTOS kernel millisecond tick count. + The tick count corresponds to the tick count the RTOS uses for timing + purposes. It increments monotonically from 0 at boot, so it effectively + never wraps. If the underlying RTOS only provides a 32-bit tick count, + this method expands it to 64 bits. + @return RTOS kernel current tick count + @note Mbed OS always uses millisecond RTOS ticks, and this could only wrap + after half a billion years. + @note In a non-RTOS build, this computes an equivalent time in milliseconds, + based on a HAL timer. The time may be referenced as 0 on first call. + @note You cannot call this function from ISR context. + @note The equivalent functionality is accessible in C++ via rtos::Kernel::get_ms_count. + */ +uint64_t get_ms_count(void); + +/** Sleep for a specified time period in millisec: + @param millisec time delay value + @note You cannot call this function from ISR context. + @note The equivalent functionality is accessible in C++ via rtos::ThisThread::sleep_for. +*/ +void thread_sleep_for(uint32_t millisec); + +/** Sleep until a specified time in millisec + The specified time is according to Kernel::get_ms_count(). + @param millisec absolute time in millisec + @note You cannot call this function from ISR context. + @note if millisec is equal to or lower than the current tick count, this + returns immediately. + @note The equivalent functionality is accessible in C++ via ThisThread::sleep_until. +*/ +void thread_sleep_until(uint64_t millisec); + +#ifdef __cplusplus +} +#endif + + +#endif //MBED_THREAD_H diff --git a/rtos/Kernel.cpp b/rtos/Kernel.cpp index 4751bee053..21664292a1 100644 --- a/rtos/Kernel.cpp +++ b/rtos/Kernel.cpp @@ -26,6 +26,12 @@ #include "platform/mbed_critical.h" #include "platform/mbed_os_timer.h" +#if !MBED_CONF_RTOS_PRESENT +/* If the RTOS is not present, we call mbed_thread.cpp to do the work */ +/* If the RTOS is present, mbed_thread.cpp calls us to do the work */ +#include "platform/mbed_thread.h" +#endif + namespace rtos { uint64_t Kernel::get_ms_count() @@ -63,7 +69,7 @@ uint64_t Kernel::get_ms_count() return ret; } #else - return mbed::internal::init_os_timer()->update_and_get_tick(); + return ::get_ms_count(); #endif } diff --git a/rtos/ThisThread.cpp b/rtos/ThisThread.cpp index cd8af4eea8..50286c214d 100644 --- a/rtos/ThisThread.cpp +++ b/rtos/ThisThread.cpp @@ -31,6 +31,10 @@ #include "platform/mbed_os_timer.h" #if !MBED_CONF_RTOS_PRESENT +/* If the RTOS is not present, we call mbed_thread.cpp to do the work */ +/* If the RTOS is present, mbed_thread.cpp calls us to do the work */ +#include "platform/mbed_thread.h" + static uint32_t thread_flags; /* For the flags to be useful, need a way of setting them, but there's only the main @@ -188,8 +192,7 @@ void ThisThread::sleep_for(uint32_t millisec) osStatus_t status = osDelay(millisec); MBED_ASSERT(status == osOK); #else - // Undocumented, but osDelay(UINT32_MAX) does actually sleep forever - mbed::internal::do_timed_sleep_relative_or_forever(millisec); + thread_sleep_for(millisec); #endif } @@ -213,7 +216,7 @@ void ThisThread::sleep_until(uint64_t millisec) } } #else - mbed::internal::do_timed_sleep_absolute(millisec); + thread_sleep_until(millisec); #endif }