mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #10104 from kjbracey-arm/sleep_api
Sleep rework, RTOS API for bare metal, wait deprecationspull/11062/head
commit
987533859a
|
@ -313,9 +313,9 @@ void test_deepsleep(void)
|
|||
|
||||
* This should be replaced with a better function that checks if the
|
||||
* hardware buffers are empty. However, such an API does not exist now,
|
||||
* so we'll use the wait_ms() function for now.
|
||||
* so we'll use the ThisThread::sleep_for() function for now.
|
||||
*/
|
||||
wait_ms(20);
|
||||
ThisThread::sleep_for(20);
|
||||
|
||||
timer.start();
|
||||
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us);
|
||||
|
|
|
@ -125,7 +125,7 @@ void rtc_persist_test()
|
|||
rtc_write(start);
|
||||
rtc_free();
|
||||
|
||||
wait(WAIT_TIME);
|
||||
ThisThread::sleep_for(WAIT_TIME * 1000);
|
||||
|
||||
rtc_init();
|
||||
const uint32_t stop = rtc_read();
|
||||
|
@ -167,7 +167,7 @@ void rtc_range_test()
|
|||
for (uint32_t i = 0; i < sizeof(starts) / sizeof(starts[0]); i++) {
|
||||
const uint32_t start = starts[i];
|
||||
rtc_write(start);
|
||||
wait(WAIT_TIME);
|
||||
ThisThread::sleep_for(WAIT_TIME * 1000);
|
||||
const uint32_t stop = rtc_read();
|
||||
TEST_ASSERT_UINT32_WITHIN(WAIT_TOLERANCE, WAIT_TIME, stop - start);
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ void test_error_logging_multithread()
|
|||
errThread[i] = new Thread(osPriorityNormal1, THREAD_STACK_SIZE, NULL, NULL);
|
||||
errThread[i]->start(callback(err_thread_func, &error_status[i]));
|
||||
}
|
||||
wait(2.0);
|
||||
ThisThread::sleep_for(2000);
|
||||
for (i = 0; i < NUM_TEST_THREADS; i++) {
|
||||
errThread[i]->join();
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MBED_TICKLESS
|
||||
#error [NOT_SUPPORTED] Tickless mode not supported for this target.
|
||||
#endif
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
|
@ -26,9 +23,10 @@
|
|||
extern "C" {
|
||||
#include "rtx_lib.h"
|
||||
}
|
||||
#include "rtos/TARGET_CORTEX/SysTimer.h"
|
||||
#include "platform/SysTimer.h"
|
||||
|
||||
#define TEST_TICKS 42UL
|
||||
#define TEST_TICKS 42
|
||||
#define TEST_TICK_US (TEST_TICKS * 1000)
|
||||
#define DELAY_DELTA_US 2500ULL
|
||||
|
||||
/* Use a specific delta value for deep sleep, as entry/exit adds up extra latency.
|
||||
|
@ -40,29 +38,29 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
using namespace utest::v1;
|
||||
using mbed::internal::SysTimer;
|
||||
|
||||
const us_timestamp_t DELAY_US = 1000000ULL * TEST_TICKS / OS_TICK_FREQ;
|
||||
const us_timestamp_t DELAY_US = TEST_TICK_US;
|
||||
|
||||
// Override the handler() -- the SysTick interrupt must not be set as pending by the test code.
|
||||
class SysTimerTest: public rtos::internal::SysTimer {
|
||||
// The SysTick interrupt must not be set as pending by the test code.
|
||||
template <uint32_t US_IN_TICK>
|
||||
class SysTimerTest: public SysTimer<US_IN_TICK, false> {
|
||||
private:
|
||||
Semaphore _sem;
|
||||
virtual void handler()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
_increment_tick();
|
||||
core_util_critical_section_exit();
|
||||
_sem.release();
|
||||
SysTimer<US_IN_TICK, false>::handler();
|
||||
}
|
||||
|
||||
public:
|
||||
SysTimerTest() :
|
||||
SysTimer(), _sem(0, 1)
|
||||
SysTimer<US_IN_TICK, false>(), _sem(0, 1)
|
||||
{
|
||||
}
|
||||
|
||||
SysTimerTest(const ticker_data_t *data) :
|
||||
SysTimer(data), _sem(0, 1)
|
||||
SysTimer<US_IN_TICK, false>(data), _sem(0, 1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -153,7 +151,7 @@ void mock_ticker_reset()
|
|||
*/
|
||||
void test_created_with_zero_tick_count(void)
|
||||
{
|
||||
SysTimerTest st;
|
||||
SysTimerTest<1000> st;
|
||||
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
|
||||
}
|
||||
|
||||
|
@ -164,26 +162,27 @@ void test_created_with_zero_tick_count(void)
|
|||
* Then the tick count is not updated
|
||||
* When @a suspend and @a resume methods are called again after a delay
|
||||
* Then the tick count is updated
|
||||
* and the number of ticks incremented is equal TEST_TICKS - 1
|
||||
* and the number of ticks incremented is equal TEST_TICKS
|
||||
* When @a suspend and @a resume methods are called again without a delay
|
||||
* Then the tick count is not updated
|
||||
*/
|
||||
void test_update_tick(void)
|
||||
{
|
||||
mock_ticker_reset();
|
||||
SysTimerTest st(&mock_ticker_data);
|
||||
st.suspend(TEST_TICKS * 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(0, st.resume());
|
||||
SysTimerTest<1000> st(&mock_ticker_data);
|
||||
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
|
||||
st.cancel_wake();
|
||||
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
|
||||
|
||||
st.suspend(TEST_TICKS * 2);
|
||||
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
|
||||
mock_ticker_timestamp = DELAY_US;
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.resume());
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick());
|
||||
st.cancel_wake();
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.update_and_get_tick());
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.get_tick());
|
||||
|
||||
st.suspend(TEST_TICKS * 2);
|
||||
TEST_ASSERT_EQUAL_UINT32(0, st.resume());
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick());
|
||||
st.set_wake_time(st.get_tick() + TEST_TICKS * 2);
|
||||
st.cancel_wake();
|
||||
TEST_ASSERT_EQUAL_UINT32(TEST_TICKS, st.get_tick());
|
||||
}
|
||||
|
||||
/** Test get_time returns correct time
|
||||
|
@ -195,7 +194,7 @@ void test_update_tick(void)
|
|||
void test_get_time(void)
|
||||
{
|
||||
mock_ticker_reset();
|
||||
SysTimerTest st(&mock_ticker_data);
|
||||
SysTimerTest<1000> st(&mock_ticker_data);
|
||||
us_timestamp_t t1 = st.get_time();
|
||||
|
||||
mock_ticker_timestamp = DELAY_US;
|
||||
|
@ -212,9 +211,9 @@ void test_get_time(void)
|
|||
*/
|
||||
void test_cancel_tick(void)
|
||||
{
|
||||
SysTimerTest st;
|
||||
SysTimerTest<TEST_TICK_US> st;
|
||||
st.cancel_tick();
|
||||
st.schedule_tick(TEST_TICKS);
|
||||
st.start_tick();
|
||||
|
||||
st.cancel_tick();
|
||||
bool acquired = st.sem_try_acquire((DELAY_US + DELAY_DELTA_US) / 1000ULL);
|
||||
|
@ -222,50 +221,41 @@ void test_cancel_tick(void)
|
|||
TEST_ASSERT_EQUAL_UINT32(0, st.get_tick());
|
||||
}
|
||||
|
||||
/** Test schedule zero
|
||||
*
|
||||
* Given a SysTimer
|
||||
* When a tick is scheduled with delta = 0 ticks
|
||||
* Then the handler is called instantly
|
||||
*/
|
||||
void test_schedule_zero(void)
|
||||
{
|
||||
SysTimerTest st;
|
||||
|
||||
st.schedule_tick(0UL);
|
||||
bool acquired = st.sem_try_acquire(0);
|
||||
TEST_ASSERT_TRUE(acquired);
|
||||
}
|
||||
|
||||
/** Test handler called once
|
||||
/** Test handler called twice
|
||||
*
|
||||
* Given a SysTimer with a tick scheduled with delta = TEST_TICKS
|
||||
* When the handler is called
|
||||
* Then the tick count is incremented by 1
|
||||
* and elapsed time is equal 1000000ULL * TEST_TICKS / OS_TICK_FREQ;
|
||||
* When more time elapses
|
||||
* Then the handler is not called again
|
||||
* Repeat a second time.
|
||||
*/
|
||||
void test_handler_called_once(void)
|
||||
void test_handler_called_twice(void)
|
||||
{
|
||||
SysTimerTest st;
|
||||
st.schedule_tick(TEST_TICKS);
|
||||
SysTimerTest<TEST_TICK_US> st;
|
||||
us_timestamp_t t1 = st.get_time();
|
||||
bool acquired = st.sem_try_acquire(0);
|
||||
TEST_ASSERT_FALSE(acquired);
|
||||
|
||||
st.start_tick();
|
||||
// Wait in a busy loop to prevent entering sleep or deepsleep modes.
|
||||
while (!acquired) {
|
||||
do {
|
||||
acquired = st.sem_try_acquire(0);
|
||||
}
|
||||
} while (!acquired);
|
||||
us_timestamp_t t2 = st.get_time();
|
||||
TEST_ASSERT_TRUE(acquired);
|
||||
TEST_ASSERT_EQUAL_UINT32(1, st.get_tick());
|
||||
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, t2 - t1);
|
||||
|
||||
acquired = st.sem_try_acquire((DELAY_US + DELAY_DELTA_US) / 1000ULL);
|
||||
TEST_ASSERT_FALSE(acquired);
|
||||
TEST_ASSERT_EQUAL_UINT32(1, st.get_tick());
|
||||
// Wait in a busy loop to prevent entering sleep or deepsleep modes.
|
||||
do {
|
||||
acquired = st.sem_try_acquire(0);
|
||||
} while (!acquired);
|
||||
t2 = st.get_time();
|
||||
TEST_ASSERT_TRUE(acquired);
|
||||
TEST_ASSERT_EQUAL_UINT32(2, st.get_tick());
|
||||
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US * 2, t2 - t1);
|
||||
st.cancel_tick();
|
||||
}
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
@ -281,16 +271,17 @@ void test_handler_called_once(void)
|
|||
void test_sleep(void)
|
||||
{
|
||||
Timer timer;
|
||||
SysTimerTest st;
|
||||
SysTimerTest<TEST_TICK_US> st;
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
timer.start();
|
||||
st.schedule_tick(TEST_TICKS);
|
||||
st.start_tick();
|
||||
|
||||
TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be disallowed");
|
||||
st.sem_acquire();
|
||||
|
||||
timer.stop();
|
||||
st.cancel_tick();
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
|
||||
TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, timer.read_high_resolution_us());
|
||||
|
@ -319,13 +310,14 @@ void test_deepsleep(void)
|
|||
wait_ms(10);
|
||||
// Regular Timer might be disabled during deepsleep.
|
||||
LowPowerTimer lptimer;
|
||||
SysTimerTest st;
|
||||
SysTimerTest<TEST_TICK_US> st;
|
||||
|
||||
lptimer.start();
|
||||
st.schedule_tick(TEST_TICKS);
|
||||
st.start_tick();
|
||||
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep_test_check(), "Deep sleep should be allowed");
|
||||
st.sem_acquire();
|
||||
lptimer.stop();
|
||||
st.cancel_tick();
|
||||
|
||||
TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_DELAY_DELTA_US, DELAY_US, lptimer.read_high_resolution_us());
|
||||
}
|
||||
|
@ -334,7 +326,7 @@ void test_deepsleep(void)
|
|||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(5, "default_auto");
|
||||
GREENTEA_SETUP(15, "default_auto");
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
|
@ -343,8 +335,7 @@ Case cases[] = {
|
|||
Case("Tick count is updated correctly", test_update_tick),
|
||||
Case("Time is updated correctly", test_get_time),
|
||||
Case("Tick can be cancelled", test_cancel_tick),
|
||||
Case("Schedule zero ticks", test_schedule_zero),
|
||||
Case("Handler called once", test_handler_called_once),
|
||||
Case("Handler called twice", test_handler_called_twice),
|
||||
#if DEVICE_SLEEP
|
||||
Case("Wake up from sleep", test_sleep),
|
||||
#if DEVICE_LPTICKER && !MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER
|
||||
|
|
|
@ -81,5 +81,5 @@ void ASYNCHRONOUS_DNS_CANCEL()
|
|||
|
||||
delete[] data;
|
||||
|
||||
wait(5.0);
|
||||
ThisThread::sleep_for(5000);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ void ASYNCHRONOUS_DNS_EXTERNAL_EVENT_QUEUE()
|
|||
TEST_ASSERT_EQUAL(0, result_exp_timeout);
|
||||
|
||||
// Give event queue time to finalise before destructors
|
||||
wait(2.0);
|
||||
ThisThread::sleep_for(2000);
|
||||
|
||||
nsapi_dns_call_in_set(0);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ void ASYNCHRONOUS_DNS_TIMEOUTS()
|
|||
TEST_ASSERT(result_exp_timeout > 0);
|
||||
|
||||
// Give event queue time to finalise before destructors
|
||||
wait(2.0);
|
||||
ThisThread::sleep_for(2000);
|
||||
|
||||
nsapi_dns_call_in_set(0);
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ void UDPSOCKET_ECHOTEST_BURST()
|
|||
} else if (recvd < 0) {
|
||||
pkg_fail += BURST_PKTS - j; // Assume all the following packets of the burst to be lost
|
||||
printf("[%02d] network error %d\n", i, recvd);
|
||||
wait(recv_timeout);
|
||||
ThisThread::sleep_for(recv_timeout * 1000);
|
||||
recv_timeout *= 2; // Back off,
|
||||
break;
|
||||
} else if (temp_addr != udp_addr) {
|
||||
|
|
|
@ -45,7 +45,7 @@ void UDPSOCKET_SENDTO_REPEAT()
|
|||
break;
|
||||
}
|
||||
oom_earlier = true;
|
||||
wait(1);
|
||||
ThisThread::sleep_for(1000);
|
||||
continue;
|
||||
}
|
||||
oom_earlier = false;
|
||||
|
|
|
@ -153,7 +153,7 @@ void NETWORKINTERFACE_STATUS_GET()
|
|||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
|
||||
|
||||
while (net->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) {
|
||||
wait(0.5);
|
||||
ThisThread::sleep_for(500);
|
||||
}
|
||||
|
||||
err = net->disconnect();
|
||||
|
|
|
@ -944,7 +944,7 @@ static void bg_traffic_thread(SInfo *info)
|
|||
tr_err("Background sent: \"%s\"", sbuffer);
|
||||
tr_err("Background received: \"%s\"", rbuffer);
|
||||
}
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,9 @@ endif(COVERAGE)
|
|||
# UNIT TESTS
|
||||
####################
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNITTEST")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST")
|
||||
|
||||
# Set include dirs.
|
||||
set(unittest-includes-base
|
||||
"${PROJECT_SOURCE_DIR}/target_h"
|
||||
|
|
|
@ -26,5 +26,5 @@ set(unittest-test-sources
|
|||
stubs/CellularUtil_stub.cpp
|
||||
stubs/us_ticker_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/mbed_wait_api_stub.cpp
|
||||
stubs/ThisThread_stub.cpp
|
||||
)
|
||||
|
|
|
@ -23,7 +23,6 @@ set(unittest-test-sources
|
|||
stubs/EventQueue_stub.cpp
|
||||
stubs/FileHandle_stub.cpp
|
||||
stubs/us_ticker_stub.cpp
|
||||
stubs/mbed_wait_api_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/mbed_poll_stub.cpp
|
||||
stubs/Timer_stub.cpp
|
||||
|
|
|
@ -130,11 +130,6 @@ int UARTSerial::enable_output(bool enabled)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::wait_ms(uint32_t millisec)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UARTSerial::set_flow_control(mbed::SerialBase::Flow, PinName, PinName)
|
||||
{
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#define __MUTEX_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos_types.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
|
||||
namespace rtos {
|
||||
|
||||
|
|
|
@ -525,14 +525,14 @@ static void rf_if_reset_radio(void)
|
|||
#endif
|
||||
rf->IRQ.rise(0);
|
||||
rf->RST = 1;
|
||||
wait_ms(1);
|
||||
ThisThread::sleep_for(2);
|
||||
rf->RST = 0;
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
CS_RELEASE();
|
||||
rf->SLP_TR = 0;
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
rf->RST = 1;
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
|
||||
rf->IRQ.rise(&rf_if_interrupt_handler);
|
||||
}
|
||||
|
@ -883,15 +883,16 @@ static uint8_t rf_if_read_rnd(void)
|
|||
rf_if_write_register(TRX_RPC, RX_RPC_CTRL | TRX_RPC_RSVD_1);
|
||||
}
|
||||
|
||||
wait_ms(1);
|
||||
|
||||
wait_ns(1000);
|
||||
temp = ((rf_if_read_register(PHY_RSSI) >> 5) << 6);
|
||||
wait_ms(1);
|
||||
wait_ns(1000);
|
||||
temp |= ((rf_if_read_register(PHY_RSSI) >> 5) << 4);
|
||||
wait_ms(1);
|
||||
wait_ns(1000);
|
||||
temp |= ((rf_if_read_register(PHY_RSSI) >> 5) << 2);
|
||||
wait_ms(1);
|
||||
wait_ns(1000);
|
||||
temp |= ((rf_if_read_register(PHY_RSSI) >> 5));
|
||||
wait_ms(1);
|
||||
wait_ns(1000);
|
||||
if (rf_part_num == PART_AT86RF233) {
|
||||
rf_if_write_register(TRX_RPC, tmp_rpc_val);
|
||||
}
|
||||
|
|
|
@ -1083,10 +1083,10 @@ static void rf_reset(void)
|
|||
{
|
||||
// Shutdown
|
||||
rf->SDN = 1;
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
// Wake up
|
||||
rf->SDN = 0;
|
||||
wait_ms(10);
|
||||
ThisThread::sleep_for(10);
|
||||
}
|
||||
|
||||
static void rf_init(void)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "STModCellular.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "mbed_trace.h"
|
||||
|
||||
#define TRACE_GROUP "CELL"
|
||||
|
@ -38,14 +38,14 @@ STModCellular::STModCellular(FileHandle *fh) : STMOD_CELLULAR_MODEM(fh),
|
|||
// start with modem disabled
|
||||
m_powerkey.write(0);
|
||||
m_reset.write(1);
|
||||
wait_ms(200);
|
||||
rtos::ThisThread::sleep_for(200);
|
||||
m_reset.write(0);
|
||||
wait_ms(150);
|
||||
rtos::ThisThread::sleep_for(150);
|
||||
|
||||
wait_ms(50);
|
||||
rtos::ThisThread::sleep_for(50);
|
||||
m_simsel0.write(MBED_CONF_STMOD_CELLULAR_SIM_SELECTION & 0x01);
|
||||
m_simsel1.write(MBED_CONF_STMOD_CELLULAR_SIM_SELECTION & 0x02);
|
||||
wait_ms(50);
|
||||
rtos::ThisThread::sleep_for(50);
|
||||
}
|
||||
|
||||
STModCellular::~STModCellular()
|
||||
|
@ -59,28 +59,28 @@ nsapi_error_t STModCellular::soft_power_on()
|
|||
#if (MBED_CONF_STMOD_CELLULAR_TYPE == STMOD_UG96)
|
||||
tr_debug("Booting UG96\r\n");
|
||||
m_reset.write(1);
|
||||
wait_ms(200);
|
||||
rtos::ThisThread::sleep_for(200);
|
||||
m_reset.write(0);
|
||||
wait_ms(150);
|
||||
rtos::ThisThread::sleep_for(150);
|
||||
m_powerkey.write(1);
|
||||
wait_ms(150);
|
||||
rtos::ThisThread::sleep_for(150);
|
||||
m_powerkey.write(0);
|
||||
/* Because modem status is not available on STMOD+ connector,
|
||||
* let's wait for Modem complete boot */
|
||||
wait_ms(2300);
|
||||
rtos::ThisThread::sleep_for(2300);
|
||||
#endif
|
||||
#if (MBED_CONF_STMOD_CELLULAR_TYPE == STMOD_BG96)
|
||||
tr_debug("Booting BG96\r\n");
|
||||
m_powerkey.write(1);
|
||||
m_reset.write(1);
|
||||
wait_ms(150);
|
||||
rtos::ThisThread::sleep_for(150);
|
||||
m_powerkey.write(0);
|
||||
m_reset.write(0);
|
||||
wait_ms(100);
|
||||
rtos::ThisThread::sleep_for(100);
|
||||
m_powerkey.write(1);
|
||||
wait_ms(200);
|
||||
rtos::ThisThread::sleep_for(200);
|
||||
m_powerkey.write(0);
|
||||
wait_ms(5000);
|
||||
rtos::ThisThread::sleep_for(5000);
|
||||
#endif
|
||||
|
||||
nsapi_error_t err = STMOD_CELLULAR_MODEM::soft_power_on();
|
||||
|
@ -133,7 +133,7 @@ nsapi_error_t STModCellular::soft_power_on()
|
|||
}
|
||||
#endif
|
||||
|
||||
wait_ms(500);
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
|
||||
#if MBED_CONF_CELLULAR_DEBUG_AT
|
||||
_at->lock();
|
||||
|
@ -150,7 +150,7 @@ nsapi_error_t STModCellular::soft_power_off()
|
|||
{
|
||||
_at->cmd_start("AT+QPOWD");
|
||||
_at->cmd_stop();
|
||||
wait_ms(1000);
|
||||
rtos::ThisThread::sleep_for(1000);
|
||||
// should wait for POWERED DOWN with a time out up to 65 second according to the manual.
|
||||
// we cannot afford such a long wait though.
|
||||
return STMOD_CELLULAR_MODEM::soft_power_off();
|
||||
|
|
|
@ -661,8 +661,8 @@ int DataFlashBlockDevice::_sync(void)
|
|||
break;
|
||||
/* wait the typical write period before trying again */
|
||||
} else {
|
||||
DEBUG_PRINTF("wait_ms: %d\r\n", DATAFLASH_TIMING_ERASE_PROGRAM_PAGE);
|
||||
wait_ms(DATAFLASH_TIMING_ERASE_PROGRAM_PAGE);
|
||||
DEBUG_PRINTF("sleep_for: %d\r\n", DATAFLASH_TIMING_ERASE_PROGRAM_PAGE);
|
||||
rtos::ThisThread::sleep_for(DATAFLASH_TIMING_ERASE_PROGRAM_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "QSPIFBlockDevice.h"
|
||||
#include <string.h>
|
||||
#include "mbed_wait_api.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
#ifndef MBED_CONF_MBED_TRACE_ENABLE
|
||||
#define MBED_CONF_MBED_TRACE_ENABLE 0
|
||||
|
@ -1146,7 +1146,7 @@ bool QSPIFBlockDevice::_is_mem_ready()
|
|||
bool mem_ready = true;
|
||||
|
||||
do {
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
retries++;
|
||||
//Read the Status Register from device
|
||||
memset(status_value, 0xFF, QSPI_MAX_STATUS_REGISTER_SIZE);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "SPIFReducedBlockDevice.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
|
@ -224,7 +224,7 @@ int SPIFReducedBlockDevice::_sync()
|
|||
return 0;
|
||||
}
|
||||
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
}
|
||||
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
|
@ -244,7 +244,7 @@ int SPIFReducedBlockDevice::_wren()
|
|||
return 0;
|
||||
}
|
||||
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
}
|
||||
|
||||
return BD_ERROR_DEVICE_ERROR;
|
||||
|
@ -278,7 +278,7 @@ int SPIFReducedBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_
|
|||
addr += chunk;
|
||||
size -= chunk;
|
||||
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
|
||||
err = _sync();
|
||||
if (err) {
|
||||
|
|
|
@ -139,8 +139,8 @@
|
|||
#if DEVICE_SPI
|
||||
|
||||
#include "SDBlockDevice.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "platform/mbed_debug.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
@ -872,7 +872,7 @@ uint32_t SDBlockDevice::_go_idle_state()
|
|||
if (R1_IDLE_STATE == response) {
|
||||
break;
|
||||
}
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
*/
|
||||
|
||||
#include "SPIFBlockDevice.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "mbed_critical.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
#include "mbed_trace.h"
|
||||
#define TRACE_GROUP "SPIF"
|
||||
|
@ -910,7 +910,7 @@ bool SPIFBlockDevice::_is_mem_ready()
|
|||
bool mem_ready = true;
|
||||
|
||||
do {
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
retries++;
|
||||
//Read the Status Register from device
|
||||
if (SPIF_BD_ERROR_OK != _spi_send_general_command(SPIF_RDSR, SPI_NO_ADDRESS_COMMAND, NULL, 0, status_value,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "MbedTester.h"
|
||||
#include "fpga_config.h"
|
||||
#include "BlockDevice.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "drivers/MbedCRC.h"
|
||||
|
@ -1731,7 +1732,7 @@ uint8_t MbedTester::get_pwm_cycles_high()
|
|||
|
||||
uint16_t MbedTester::get_analogmuxin_measurement()
|
||||
{
|
||||
wait_ms(1);//wait for value to stabalize
|
||||
rtos::ThisThread::sleep_for(1);//wait for value to stabalize
|
||||
//take snapshot of conversion value to make safe for reading
|
||||
set_snapshot();
|
||||
uint16_t an_mux_analogin_measurement = 0;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_atomic.h"
|
||||
#include "platform/mbed_debug.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
#ifndef MBED_CONF_ESP8266_DEBUG
|
||||
#define MBED_CONF_ESP8266_DEBUG false
|
||||
|
@ -49,6 +49,7 @@
|
|||
#define TRACE_GROUP "ESPI" // ESP8266 Interface
|
||||
|
||||
using namespace mbed;
|
||||
using namespace rtos;
|
||||
|
||||
#if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX
|
||||
ESP8266Interface::ESP8266Interface()
|
||||
|
@ -459,7 +460,7 @@ nsapi_error_t ESP8266Interface::_reset()
|
|||
_rst_pin.rst_assert();
|
||||
// If you happen to use Pin7 CH_EN as reset pin, not needed otherwise
|
||||
// https://www.espressif.com/sites/default/files/documentation/esp8266_hardware_design_guidelines_en.pdf
|
||||
wait_ms(2); // Documentation says 200 us should have been enough, but experimentation shows that 1ms was not enough
|
||||
ThisThread::sleep_for(2); // Documentation says 200 us; need 2 ticks to get minimum 1 ms.
|
||||
_esp.flush();
|
||||
_rst_pin.rst_deassert();
|
||||
} else {
|
||||
|
|
|
@ -19,12 +19,7 @@
|
|||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
|
||||
#include "platform/mbed_poll.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#include "rtos/ThisThread.h"
|
||||
#else
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#endif
|
||||
#include "platform/mbed_thread.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -114,7 +109,7 @@ int UARTSerial::sync()
|
|||
while (!_txbuf.empty()) {
|
||||
api_unlock();
|
||||
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
|
||||
wait_ms(1);
|
||||
thread_sleep_for(1);
|
||||
api_lock();
|
||||
}
|
||||
|
||||
|
@ -178,7 +173,7 @@ ssize_t UARTSerial::write(const void *buffer, size_t length)
|
|||
}
|
||||
do {
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
thread_sleep_for(1); // XXX todo - proper wait?
|
||||
api_lock();
|
||||
} while (_txbuf.full());
|
||||
}
|
||||
|
@ -221,7 +216,7 @@ ssize_t UARTSerial::read(void *buffer, size_t length)
|
|||
return -EAGAIN;
|
||||
}
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
thread_sleep_for(1); // XXX todo - proper wait?
|
||||
api_lock();
|
||||
}
|
||||
|
||||
|
@ -407,17 +402,6 @@ int UARTSerial::enable_output(bool enabled)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::wait_ms(uint32_t millisec)
|
||||
{
|
||||
/* wait_ms implementation for RTOS spins until exact microseconds - we
|
||||
* want to just sleep until next tick.
|
||||
*/
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
rtos::ThisThread::sleep_for(millisec);
|
||||
#else
|
||||
::wait_ms(millisec);
|
||||
#endif
|
||||
}
|
||||
} //namespace mbed
|
||||
|
||||
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
|
|
|
@ -255,8 +255,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void wait_ms(uint32_t millisec);
|
||||
|
||||
/** SerialBase lock override */
|
||||
virtual void lock(void);
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ int equeue_create_inplace(equeue_t *q, size_t size, void *buffer)
|
|||
q->slab.data = q->buffer;
|
||||
|
||||
q->queue = 0;
|
||||
equeue_tick_init();
|
||||
q->tick = equeue_tick();
|
||||
q->generation = 0;
|
||||
q->break_requested = false;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "cmsis.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "drivers/Timer.h"
|
||||
#include "drivers/Ticker.h"
|
||||
|
@ -33,11 +34,43 @@
|
|||
using namespace mbed;
|
||||
|
||||
// Ticker operations
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#if MBED_CONF_RTOS_API_PRESENT
|
||||
|
||||
#include "rtos/Kernel.h"
|
||||
#include "platform/mbed_os_timer.h"
|
||||
|
||||
void equeue_tick_init()
|
||||
{
|
||||
#if defined MBED_TICKLESS || !MBED_CONF_RTOS_PRESENT
|
||||
mbed::internal::init_os_timer();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned equeue_tick()
|
||||
{
|
||||
return osKernelGetTickCount();
|
||||
#if defined MBED_TICKLESS || !MBED_CONF_RTOS_PRESENT
|
||||
// It is not safe to call get_ms_count from ISRs, both
|
||||
// because documentation says so, and because it will give
|
||||
// a stale value from the RTOS if the interrupt has woken
|
||||
// us out of sleep - the RTOS will not have updated its
|
||||
// ticks yet.
|
||||
if (core_util_is_isr_active()) {
|
||||
// And the documentation further says that this
|
||||
// should not be called from critical sections, for
|
||||
// performance reasons, but I don't have a good
|
||||
// current alternative!
|
||||
return mbed::internal::os_timer->get_time() / 1000;
|
||||
} else {
|
||||
return rtos::Kernel::get_ms_count();
|
||||
}
|
||||
#else
|
||||
// And this is the legacy behaviour - if running in
|
||||
// non-tickless mode, this works fine, despite Mbed OS
|
||||
// documentation saying no. (Most recent CMSIS-RTOS
|
||||
// permits `ososKernelGetTickCount` from IRQ, and our
|
||||
// `rtos::Kernel` wrapper copes too).
|
||||
return rtos::Kernel::get_ms_count();
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -53,7 +86,6 @@ unsigned equeue_tick()
|
|||
#define ALIAS_TIMEOUT Timeout
|
||||
#endif
|
||||
|
||||
static bool equeue_tick_inited = false;
|
||||
static volatile unsigned equeue_minutes = 0;
|
||||
static unsigned equeue_timer[
|
||||
(sizeof(ALIAS_TIMER) + sizeof(unsigned) - 1) / sizeof(unsigned)];
|
||||
|
@ -66,7 +98,7 @@ static void equeue_tick_update()
|
|||
reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->reset();
|
||||
}
|
||||
|
||||
static void equeue_tick_init()
|
||||
void equeue_tick_init()
|
||||
{
|
||||
MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(ALIAS_TIMER),
|
||||
"The equeue_timer buffer must fit the class Timer");
|
||||
|
@ -78,16 +110,10 @@ static void equeue_tick_init()
|
|||
equeue_minutes = 0;
|
||||
timer->start();
|
||||
ticker->attach_us(equeue_tick_update, 1000 << 16);
|
||||
|
||||
equeue_tick_inited = true;
|
||||
}
|
||||
|
||||
unsigned equeue_tick()
|
||||
{
|
||||
if (!equeue_tick_inited) {
|
||||
equeue_tick_init();
|
||||
}
|
||||
|
||||
unsigned minutes;
|
||||
unsigned ms;
|
||||
|
||||
|
@ -120,27 +146,28 @@ void equeue_mutex_unlock(equeue_mutex_t *m)
|
|||
|
||||
|
||||
// Semaphore operations
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
#ifdef MBED_CONF_RTOS_API_PRESENT
|
||||
|
||||
#include "rtos/EventFlags.h"
|
||||
|
||||
MBED_STATIC_ASSERT(sizeof(equeue_sema_t) == sizeof(rtos::EventFlags), "equeue_sema_t / rtos::EventFlags mismatch");
|
||||
|
||||
int equeue_sema_create(equeue_sema_t *s)
|
||||
{
|
||||
osEventFlagsAttr_t attr;
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.cb_mem = &s->mem;
|
||||
attr.cb_size = sizeof(s->mem);
|
||||
|
||||
s->id = osEventFlagsNew(&attr);
|
||||
return !s->id ? -1 : 0;
|
||||
new (s) rtos::EventFlags("equeue");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void equeue_sema_destroy(equeue_sema_t *s)
|
||||
{
|
||||
osEventFlagsDelete(s->id);
|
||||
rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
|
||||
ef->~EventFlags();
|
||||
}
|
||||
|
||||
void equeue_sema_signal(equeue_sema_t *s)
|
||||
{
|
||||
osEventFlagsSet(s->id, 1);
|
||||
rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
|
||||
ef->set(1);
|
||||
}
|
||||
|
||||
bool equeue_sema_wait(equeue_sema_t *s, int ms)
|
||||
|
@ -149,7 +176,8 @@ bool equeue_sema_wait(equeue_sema_t *s, int ms)
|
|||
ms = osWaitForever;
|
||||
}
|
||||
|
||||
return (osEventFlagsWait(s->id, 1, osFlagsWaitAny, ms) == 1);
|
||||
rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
|
||||
return ef->wait_any(1, ms) == 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -157,7 +185,7 @@ bool equeue_sema_wait(equeue_sema_t *s, int ms)
|
|||
// Semaphore operations
|
||||
int equeue_sema_create(equeue_sema_t *s)
|
||||
{
|
||||
*s = false;
|
||||
*s = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -177,23 +205,21 @@ static void equeue_sema_timeout(equeue_sema_t *s)
|
|||
|
||||
bool equeue_sema_wait(equeue_sema_t *s, int ms)
|
||||
{
|
||||
int signal = 0;
|
||||
ALIAS_TIMEOUT timeout;
|
||||
if (ms == 0) {
|
||||
return false;
|
||||
} else if (ms > 0) {
|
||||
if (ms > 0) {
|
||||
timeout.attach_us(callback(equeue_sema_timeout, s), (us_timestamp_t)ms * 1000);
|
||||
}
|
||||
|
||||
core_util_critical_section_enter();
|
||||
while (!*s) {
|
||||
while (!*s && ms != 0) {
|
||||
sleep();
|
||||
core_util_critical_section_exit();
|
||||
__ISB();
|
||||
core_util_critical_section_enter();
|
||||
}
|
||||
|
||||
signal = *s;
|
||||
*s = false;
|
||||
int signal = *s;
|
||||
*s = 0;
|
||||
core_util_critical_section_exit();
|
||||
|
||||
return (signal > 0);
|
||||
|
|
|
@ -26,6 +26,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Currently supported platforms
|
||||
//
|
||||
|
@ -63,6 +64,7 @@ extern "C" {
|
|||
// limited by the accuracy of this tick.
|
||||
//
|
||||
// Must intentionally overflow to 0 after 2^32-1
|
||||
void equeue_tick_init(void);
|
||||
unsigned equeue_tick(void);
|
||||
|
||||
|
||||
|
@ -114,13 +116,19 @@ typedef struct equeue_sema {
|
|||
pthread_cond_t cond;
|
||||
bool signal;
|
||||
} equeue_sema_t;
|
||||
#elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT)
|
||||
#elif defined(EQUEUE_PLATFORM_MBED) && MBED_CONF_RTOS_API_PRESENT
|
||||
typedef struct equeue_sema {
|
||||
osEventFlagsId_t id;
|
||||
mbed_rtos_storage_event_flags_t mem;
|
||||
// We will actually store a C++ rtos:EventQueue in here;
|
||||
// attempt to match layout for storage, and assert size in equeue_mbed.cpp
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osEventFlagsId_t _id;
|
||||
mbed_rtos_storage_event_flags_t _obj_mem;
|
||||
#else
|
||||
uint32_t _flags;
|
||||
#endif
|
||||
} equeue_sema_t;
|
||||
#elif defined(EQUEUE_PLATFORM_MBED)
|
||||
typedef volatile int equeue_sema_t;
|
||||
typedef int equeue_sema_t;
|
||||
#endif
|
||||
|
||||
// Platform semaphore operations
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
|
||||
|
||||
// Tick operations
|
||||
void equeue_tick_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned equeue_tick(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "ATHandler.h"
|
||||
#include "mbed_poll.h"
|
||||
#include "FileHandle.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "mbed_debug.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "Kernel.h"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
#include "UARTSerial.h"
|
||||
#endif // #if DEVICE_SERIAL
|
||||
#include "mbed_wait_api.h"
|
||||
#include "ThisThread.h"
|
||||
|
||||
#define NETWORK_TIMEOUT 30 * 60 * 1000 // 30 minutes
|
||||
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
|
||||
|
@ -45,6 +45,7 @@
|
|||
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace mbed;
|
||||
using namespace rtos;
|
||||
|
||||
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularBase(at), _is_connected(false), _current_op(OP_INVALID), _fh(0), _cp_req(cp_req),
|
||||
|
@ -891,7 +892,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
_cb_data.error == NSAPI_ERROR_OK) {
|
||||
if (!_apn) {
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
wait(1); // need to wait to access SIM in some modems
|
||||
ThisThread::sleep_for(1000); // need to wait to access SIM in some modems
|
||||
_cb_data.error = _device->open_information()->get_imsi(imsi, sizeof(imsi));
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
const char *apn_config = apnconfig(imsi);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "mbed_wait_api.h"
|
||||
#include "ThisThread.h"
|
||||
#include "AT_CellularSMS.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularLog.h"
|
||||
|
@ -26,6 +26,7 @@
|
|||
using namespace mbed_cellular_util;
|
||||
using namespace mbed;
|
||||
using namespace std;
|
||||
using namespace rtos;
|
||||
|
||||
#define CTRL_Z "\x1a"
|
||||
#define ESC "\x1b"
|
||||
|
@ -406,12 +407,12 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
int write_size = 0;
|
||||
int remove_plus_sign = (phone_number[0] == '+') ? 1 : 0;
|
||||
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
|
||||
if (_mode == CellularSMSMmodeText) {
|
||||
_at.cmd_start_stop("+CMGS", "=", "%s", phone_number + remove_plus_sign);
|
||||
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
_at.resp_start("> ", true);
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
|
@ -474,7 +475,7 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
|
||||
_at.cmd_start_stop("+CMGS", "=", "%d", (pdu_len - 2) / 2);
|
||||
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
_at.resp_start("> ", true);
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
|
@ -564,7 +565,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *b
|
|||
/*
|
||||
* +CMGR: <stat>,<oa>,<alpha>,<scts>[,<tooa>,<fo>,<pid>,<dcs>,<sca>,<tosca>,<length>]<CR><LF><data><CR><LF>OK<CR><LF>
|
||||
*/
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
_at.cmd_start_stop("+CMGR", "=", "%d", msg_index);
|
||||
|
||||
// TODO: NOTE: If the selected <mem1> can contain different types of SMs (e.g. SMS-DELIVERs, SMS-SUBMITs, SMS-STATUS-REPORTs and SMS-COMMANDs),
|
||||
|
@ -621,7 +622,7 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char
|
|||
int pduSize;
|
||||
|
||||
for (int i = 0; i < sms->parts; i++) {
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
_at.cmd_start_stop("+CMGR", "=", "%d", sms->msg_index[i]);
|
||||
_at.resp_start("+CMGR:");
|
||||
|
||||
|
@ -744,7 +745,7 @@ nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_inf
|
|||
// read first the lower part of first octet as there is message type
|
||||
index++;
|
||||
tmp = hex_str_to_int(pdu + index, 1);
|
||||
//wait_ms(200);
|
||||
//ThisThread::sleep_for(200);
|
||||
if ((tmp & 0x03) == 0) {// SMS-DELIVER type, last two bits should be zero
|
||||
// UDH present? Check from first octets higher part
|
||||
tmp = hex_str_to_int(pdu + (--index), 1);
|
||||
|
@ -1071,7 +1072,7 @@ AT_CellularSMS::sms_info_t *AT_CellularSMS::get_oldest_sms_index()
|
|||
nsapi_size_or_error_t err = 0;
|
||||
while (current) {
|
||||
if (_mode == CellularSMSMmodeText) {
|
||||
wait_ms(_sim_wait_time);
|
||||
ThisThread::sleep_for(_sim_wait_time);
|
||||
err = read_sms_from_index(current->msg_index[0], NULL, 0, NULL, current->date);
|
||||
if (err != 0) {
|
||||
return NULL;
|
||||
|
|
|
@ -211,7 +211,7 @@ bool UBLOX_AT_CellularContext::activate_profile(const char *apn,
|
|||
if (activated) { //If context is activated, exit while loop and return status
|
||||
break;
|
||||
}
|
||||
wait_ms(5000); //Wait for 5 seconds and then try again
|
||||
rtos::ThisThread::sleep_for(5000); //Wait for 5 seconds and then try again
|
||||
}
|
||||
t1.stop();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "drivers/Timer.h"
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "mbed_atomic.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "mbed_error.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "ThisThread.h"
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -836,7 +836,7 @@ int NVStore::init()
|
|||
init_attempts_val = core_util_atomic_incr_u32(&_init_attempts, 1);
|
||||
if (init_attempts_val != 1) {
|
||||
while (!_init_done) {
|
||||
wait_ms(1);
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
}
|
||||
return NVSTORE_SUCCESS;
|
||||
}
|
||||
|
|
3
mbed.h
3
mbed.h
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "platform/mbed_version.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#if MBED_CONF_RTOS_API_PRESENT
|
||||
#include "rtos/rtos.h"
|
||||
#endif
|
||||
|
||||
|
@ -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"
|
||||
|
|
|
@ -37,8 +37,9 @@
|
|||
* - When the RTOS is absent, all methods are defined as noop.
|
||||
*/
|
||||
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
#ifdef MBED_CONF_RTOS_API_PRESENT
|
||||
|
||||
// rtos::Mutex is itself a dummy class if the RTOS API is present, but not the RTOS
|
||||
#include "rtos/Mutex.h"
|
||||
typedef rtos::Mutex PlatformMutex;
|
||||
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
#include "mbed_atomic.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#include "platform/mbed_power_mgmt.h"
|
||||
#include "platform/CriticalSectionLock.h"
|
||||
#include "platform/SysTimer.h"
|
||||
extern "C" {
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#include "rtx_lib.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(NO_SYSTICK))
|
||||
/**
|
||||
* Return an IRQ number that can be used in the absence of SysTick
|
||||
*
|
||||
* @return Free IRQ number that can be used
|
||||
*/
|
||||
extern "C" IRQn_Type mbed_get_m0_tick_irqn(void);
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void);
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
namespace internal {
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
SysTimer<US_IN_TICK, IRQ>::SysTimer() :
|
||||
#if DEVICE_LPTICKER
|
||||
TimerEvent(get_lp_ticker_data()),
|
||||
#else
|
||||
TimerEvent(get_us_ticker_data()),
|
||||
#endif
|
||||
_time_us(ticker_read_us(_ticker_data)),
|
||||
_tick(0),
|
||||
_unacknowledged_ticks(0),
|
||||
_wake_time_set(false),
|
||||
_wake_time_passed(false),
|
||||
_ticking(false),
|
||||
_deep_sleep_locked(false)
|
||||
{
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
SysTimer<US_IN_TICK, IRQ>::SysTimer(const ticker_data_t *data) :
|
||||
TimerEvent(data),
|
||||
_time_us(ticker_read_us(_ticker_data)),
|
||||
_tick(0),
|
||||
_unacknowledged_ticks(0),
|
||||
_wake_time_set(false),
|
||||
_wake_time_passed(false),
|
||||
_ticking(false),
|
||||
_deep_sleep_locked(false)
|
||||
{
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
SysTimer<US_IN_TICK, IRQ>::~SysTimer()
|
||||
{
|
||||
cancel_tick();
|
||||
cancel_wake();
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::set_wake_time(uint64_t at)
|
||||
{
|
||||
// SysTimer must not be active - we must be in suspend state
|
||||
MBED_ASSERT(!_ticking);
|
||||
|
||||
// There is a potential race here, when called from outside
|
||||
// a critical section. See function documentation for notes on
|
||||
// handling it.
|
||||
if (core_util_atomic_load_bool(&_wake_time_set)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Analyse the timers
|
||||
if (update_and_get_tick() >= at) {
|
||||
_wake_time_passed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t ticks_to_sleep = at - _tick;
|
||||
uint64_t wake_time = at * US_IN_TICK;
|
||||
|
||||
/* Set this first, before attaching the interrupt that can unset it */
|
||||
_wake_time_set = true;
|
||||
_wake_time_passed = false;
|
||||
|
||||
if (!_deep_sleep_locked && !_ticker_data->interface->runs_in_deep_sleep) {
|
||||
_deep_sleep_locked = true;
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
|
||||
/* If deep sleep is unlocked, and we have enough time, let's go for it */
|
||||
if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 &&
|
||||
ticks_to_sleep > MBED_CONF_TARGET_DEEP_SLEEP_LATENCY &&
|
||||
sleep_manager_can_deep_sleep()) {
|
||||
/* Schedule the wake up interrupt early, allowing for the deep sleep latency */
|
||||
_wake_early = true;
|
||||
insert_absolute(wake_time - MBED_CONF_TARGET_DEEP_SLEEP_LATENCY * US_IN_TICK);
|
||||
} else {
|
||||
/* Otherwise, we'll set up for shallow sleep at the precise time.
|
||||
* To make absolutely sure it's shallow so we don't incur the latency,
|
||||
* take our own lock, to avoid a race on a thread unlocking it.
|
||||
*/
|
||||
_wake_early = false;
|
||||
if (MBED_CONF_TARGET_DEEP_SLEEP_LATENCY > 0 && !_deep_sleep_locked) {
|
||||
_deep_sleep_locked = true;
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
insert_absolute(wake_time);
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::cancel_wake()
|
||||
{
|
||||
MBED_ASSERT(!_ticking);
|
||||
// Remove ensures serialized access to SysTimer by stopping timer interrupt
|
||||
remove();
|
||||
|
||||
_wake_time_set = false;
|
||||
_wake_time_passed = false;
|
||||
|
||||
if (_deep_sleep_locked) {
|
||||
_deep_sleep_locked = false;
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
uint64_t SysTimer<US_IN_TICK, IRQ>::_elapsed_ticks() const
|
||||
{
|
||||
uint64_t elapsed_us = ticker_read_us(_ticker_data) - _time_us;
|
||||
if (elapsed_us < US_IN_TICK) {
|
||||
return 0;
|
||||
} else if (elapsed_us < 2 * US_IN_TICK) {
|
||||
return 1;
|
||||
} else if (elapsed_us <= 0xFFFFFFFF) {
|
||||
// Fast common case avoiding 64-bit division
|
||||
return (uint32_t) elapsed_us / US_IN_TICK;
|
||||
} else {
|
||||
return elapsed_us / US_IN_TICK;
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::start_tick()
|
||||
{
|
||||
_ticking = true;
|
||||
if (_unacknowledged_ticks > 0) {
|
||||
_set_irq_pending();
|
||||
}
|
||||
_schedule_tick();
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::_schedule_tick()
|
||||
{
|
||||
insert_absolute(_time_us + US_IN_TICK);
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::acknowledge_tick()
|
||||
{
|
||||
// Try to avoid missed ticks if OS's IRQ level is not keeping
|
||||
// up with our handler.
|
||||
// 8-bit counter to save space, and also make sure it we don't
|
||||
// try TOO hard to resync if something goes really awry -
|
||||
// resync will reset if the count hits 256.
|
||||
if (core_util_atomic_decr_u8(&_unacknowledged_ticks, 1) > 0) {
|
||||
_set_irq_pending();
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::cancel_tick()
|
||||
{
|
||||
// Underlying call is interrupt safe
|
||||
|
||||
remove();
|
||||
_ticking = false;
|
||||
|
||||
_clear_irq_pending();
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
uint64_t SysTimer<US_IN_TICK, IRQ>::get_tick() const
|
||||
{
|
||||
// Atomic is necessary as this can be called from any foreground context,
|
||||
// while IRQ can update it.
|
||||
return core_util_atomic_load_u64(&_tick);
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
uint64_t SysTimer<US_IN_TICK, IRQ>::update_and_get_tick()
|
||||
{
|
||||
MBED_ASSERT(!_ticking && !_wake_time_set);
|
||||
// Can only be used when no interrupts are scheduled
|
||||
// Update counters to reflect elapsed time
|
||||
uint64_t elapsed_ticks = _elapsed_ticks();
|
||||
_unacknowledged_ticks = 0;
|
||||
_time_us += elapsed_ticks * US_IN_TICK;
|
||||
_tick += elapsed_ticks;
|
||||
|
||||
return _tick;
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time() const
|
||||
{
|
||||
// Underlying call is interrupt safe
|
||||
|
||||
return ticker_read_us(_ticker_data);
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
us_timestamp_t SysTimer<US_IN_TICK, IRQ>::get_time_since_tick() const
|
||||
{
|
||||
// Underlying call is interrupt safe, and _time_us is not updated by IRQ
|
||||
|
||||
return get_time() - _time_us;
|
||||
}
|
||||
|
||||
#if (defined(NO_SYSTICK))
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
|
||||
{
|
||||
return mbed_get_m0_tick_irqn();
|
||||
}
|
||||
#elif (TARGET_CORTEX_M)
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
IRQn_Type SysTimer<US_IN_TICK, IRQ>::get_irq_number()
|
||||
{
|
||||
return SysTick_IRQn;
|
||||
}
|
||||
#elif (TARGET_CORTEX_A)
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
IRQn_ID_t SysTimer<US_IN_TICK, IRQ>::get_irq_number()
|
||||
{
|
||||
return mbed_get_a9_tick_irqn();
|
||||
}
|
||||
#endif
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::_set_irq_pending()
|
||||
{
|
||||
// Protected function synchronized externally
|
||||
if (!IRQ) {
|
||||
return;
|
||||
}
|
||||
#if (defined(NO_SYSTICK))
|
||||
NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn());
|
||||
#elif (TARGET_CORTEX_M)
|
||||
SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
|
||||
#else
|
||||
IRQ_SetPending(mbed_get_a9_tick_irqn());
|
||||
#endif
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::_clear_irq_pending()
|
||||
{
|
||||
// Protected function synchronized externally
|
||||
if (!IRQ) {
|
||||
return;
|
||||
}
|
||||
#if (defined(NO_SYSTICK))
|
||||
NVIC_ClearPendingIRQ(mbed_get_m0_tick_irqn());
|
||||
#elif (TARGET_CORTEX_M)
|
||||
SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
|
||||
#else
|
||||
IRQ_ClearPending(mbed_get_a9_tick_irqn());
|
||||
#endif
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::_increment_tick()
|
||||
{
|
||||
// Protected function synchronized externally
|
||||
|
||||
_tick++;
|
||||
_time_us += US_IN_TICK;
|
||||
}
|
||||
|
||||
template<uint32_t US_IN_TICK, bool IRQ>
|
||||
void SysTimer<US_IN_TICK, IRQ>::handler()
|
||||
{
|
||||
/* To reduce IRQ latency problems, we do not re-arm in the interrupt handler */
|
||||
if (_wake_time_set) {
|
||||
_wake_time_set = false;
|
||||
if (!_wake_early) {
|
||||
_wake_time_passed = true;
|
||||
}
|
||||
/* If this was an early interrupt, user has the responsibility to check and
|
||||
* note the combination of (!set, !passed), and re-arm the wake timer if
|
||||
* necessary.
|
||||
*/
|
||||
} else if (_ticking) {
|
||||
_unacknowledged_ticks++;
|
||||
_set_irq_pending();
|
||||
_increment_tick();
|
||||
// We do this now, rather than in acknowledgement, as we get it "for free"
|
||||
// here - because we're in the ticker handler, the programming gets deferred
|
||||
// until end of dispatch, and the ticker would likely be rescheduling
|
||||
// anyway after dispatch.
|
||||
|
||||
_schedule_tick();
|
||||
}
|
||||
}
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
/* Whatever the OS wants (in case it isn't 1ms) */
|
||||
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
|
||||
#define OS_TICK_US (1000000 / OS_TICK_FREQ)
|
||||
#if OS_TICK_US != 1000
|
||||
template class SysTimer<OS_TICK_US>;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Standard 1ms SysTimer */
|
||||
template class SysTimer<1000>;
|
||||
|
||||
/* Standard 1ms SysTimer that doesn't set interrupts, used for Greentea tests */
|
||||
template class SysTimer<1000, false>;
|
||||
|
||||
/* Slowed-down SysTimer that doesn't set interrupts, used for Greentea tests */
|
||||
template class SysTimer<42000, false>;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace mbed
|
|
@ -0,0 +1,251 @@
|
|||
/* 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 "cmsis.h"
|
||||
|
||||
extern "C" {
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
#include "irq_ctrl.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace mbed {
|
||||
namespace internal {
|
||||
|
||||
/**
|
||||
* @cond MBED_INTERNAL
|
||||
*
|
||||
* @addtogroup mbed
|
||||
* @{
|
||||
*
|
||||
* @defgroup mbed_SysTimer SysTimer class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 <uint32_t US_IN_TICK, bool IRQ = true>
|
||||
class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable<SysTimer<US_IN_TICK, IRQ> > {
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
~SysTimer();
|
||||
|
||||
/**
|
||||
* 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(uint64_t 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
|
||||
*/
|
||||
int unacknowledged_ticks() const
|
||||
{
|
||||
return 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.
|
||||
*/
|
||||
uint64_t 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.
|
||||
*/
|
||||
uint64_t update_and_get_tick();
|
||||
|
||||
/**
|
||||
* Returns time since last tick
|
||||
*
|
||||
* @return Relative time in microseconds
|
||||
*/
|
||||
us_timestamp_t 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
|
||||
*/
|
||||
us_timestamp_t get_time() const;
|
||||
|
||||
protected:
|
||||
virtual void handler();
|
||||
void _increment_tick();
|
||||
void _schedule_tick();
|
||||
uint64_t _elapsed_ticks() const;
|
||||
static void _set_irq_pending();
|
||||
static void _clear_irq_pending();
|
||||
us_timestamp_t _time_us;
|
||||
uint64_t _tick;
|
||||
uint8_t _unacknowledged_ticks;
|
||||
bool _wake_time_set;
|
||||
bool _wake_time_passed;
|
||||
bool _wake_early;
|
||||
bool _ticking;
|
||||
bool _deep_sleep_locked;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "platform/mbed_power_mgmt.h"
|
||||
#include "platform/mbed_os_timer.h"
|
||||
#include "platform/CriticalSectionLock.h"
|
||||
#include "platform/SysTimer.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#include <new>
|
||||
|
||||
/* This provides the marshalling point for a system global SysTimer, which
|
||||
* is used to provide:
|
||||
* - timed sleeps (for default idle hook in RTOS tickless mode, or non-RTOS sleeps)
|
||||
* - regular ticks for RTOS
|
||||
* - absolute system timing (directly for non-RTOS, or indirectly via RTOS tick count)
|
||||
*/
|
||||
|
||||
namespace mbed {
|
||||
namespace internal {
|
||||
|
||||
OsTimer *os_timer;
|
||||
|
||||
namespace {
|
||||
uint64_t os_timer_data[(sizeof(OsTimer) + 7) / 8];
|
||||
}
|
||||
|
||||
OsTimer *init_os_timer()
|
||||
{
|
||||
// Do not use SingletonPtr since this relies on the RTOS.
|
||||
// Locking not required as it will be first called during
|
||||
// OS init, or else we're a non-RTOS single-threaded setup.
|
||||
if (!os_timer) {
|
||||
#if MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER && DEVICE_USTICKER
|
||||
os_timer = new (os_timer_data) OsTimer(get_us_ticker_data());
|
||||
#elif !MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER && DEVICE_LPTICKER
|
||||
os_timer = new (os_timer_data) OsTimer(get_lp_ticker_data());
|
||||
#else
|
||||
MBED_ASSERT("OS timer not available - check MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER" && false);
|
||||
return NULL;
|
||||
#endif
|
||||
//os_timer->setup_irq();
|
||||
}
|
||||
|
||||
return os_timer;
|
||||
}
|
||||
|
||||
/* These traits classes are designed to permit chunks of code to be
|
||||
* omitted - in particular eliminating timers. However, we don't want
|
||||
* to cause template bloat, so don't have too many traits variants.
|
||||
*/
|
||||
|
||||
/* Optionally timed operation, with optional predicate */
|
||||
struct timed_predicate_op {
|
||||
timed_predicate_op(uint64_t t) : wake_time(t), orig_predicate(NULL), orig_handle(NULL)
|
||||
{
|
||||
init_os_timer();
|
||||
}
|
||||
|
||||
timed_predicate_op(uint64_t t, bool (*wake_predicate)(void *), void *wake_predicate_handle) : wake_time(t), orig_predicate(wake_predicate), orig_handle(wake_predicate_handle)
|
||||
{
|
||||
init_os_timer();
|
||||
}
|
||||
|
||||
~timed_predicate_op()
|
||||
{
|
||||
// Make sure wake timer is cancelled. (It may or may not be, depending on
|
||||
// why we woke).
|
||||
os_timer->cancel_wake();
|
||||
}
|
||||
|
||||
bool wake_condition() const
|
||||
{
|
||||
return (orig_predicate && orig_predicate(orig_handle)) || os_timer->wake_time_passed();
|
||||
}
|
||||
|
||||
void sleep_prepare()
|
||||
{
|
||||
if (wake_time != (uint64_t) -1) {
|
||||
os_timer->set_wake_time(wake_time);
|
||||
}
|
||||
}
|
||||
|
||||
bool sleep_prepared()
|
||||
{
|
||||
return wake_time == (uint64_t) -1 || os_timer->wake_time_set();
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t wake_time;
|
||||
bool (*orig_predicate)(void *);
|
||||
void *orig_handle;
|
||||
};
|
||||
|
||||
/* Untimed operation with predicate */
|
||||
struct untimed_op {
|
||||
untimed_op(bool (*wake_predicate)(void *), void *wake_predicate_handle) : orig_predicate(wake_predicate), orig_handle(wake_predicate_handle)
|
||||
{
|
||||
}
|
||||
|
||||
bool wake_condition() const
|
||||
{
|
||||
return orig_predicate(orig_handle);
|
||||
}
|
||||
|
||||
void sleep_prepare()
|
||||
{
|
||||
}
|
||||
|
||||
bool sleep_prepared()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool (*orig_predicate)(void *);
|
||||
void *orig_handle;
|
||||
};
|
||||
|
||||
/* We require that this is called from thread context, outside a critical section,
|
||||
* and the kernel already suspended if an RTOS, meaning we don't have to worry
|
||||
* about any potential threading issues.
|
||||
*
|
||||
* The wake predicate will be called from both outside and inside a critical
|
||||
* section, so appropriate atomic care must be taken.
|
||||
*/
|
||||
template <class OpT>
|
||||
void do_sleep_operation(OpT &op)
|
||||
{
|
||||
// We assume the ticker is not already in use - without RTOS, it
|
||||
// is never used, with RTOS, it will have been disabled with OS_Tick_Disable
|
||||
while (!op.wake_condition()) {
|
||||
// Set (or re-set) the wake time - outside a critical section, as
|
||||
// it could take long enough to cause UART data loss on some platforms.
|
||||
op.sleep_prepare();
|
||||
|
||||
// If no target sleep function, nothing else to do - just keep
|
||||
// rechecking the wake condition.
|
||||
#if DEVICE_SLEEP
|
||||
// Now we need to enter the critical section for the race-free sleep
|
||||
{
|
||||
CriticalSectionLock lock;
|
||||
|
||||
// Recheck wake conditions before starting sleep, avoiding race
|
||||
if (op.wake_condition()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// It's possible that an intermediate wake interrupt occurred
|
||||
// between "set_wake_time" and the critical lock - only sleep
|
||||
// if we see that the timer is armed or we don't need it. Otherwise,
|
||||
// we go round to set the timer again.
|
||||
if (op.sleep_prepared()) {
|
||||
// Enter HAL sleep (normal or deep)
|
||||
sleep();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure interrupts get a chance to fire, which allows new result from
|
||||
// wake_predicate() and wake_time_passed()
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* We require that this is called from thread context, outside a critical section,
|
||||
* and the kernel already suspended if an RTOS, meaning we don't have to worry
|
||||
* about any potential threading issues.
|
||||
*
|
||||
* The wake predicate will be called from both outside and inside a critical
|
||||
* section, so appropriate atomic care must be taken.
|
||||
*/
|
||||
uint64_t do_timed_sleep_absolute(uint64_t wake_time, bool (*wake_predicate)(void *), void *wake_predicate_handle)
|
||||
{
|
||||
{
|
||||
timed_predicate_op op(wake_time, wake_predicate, wake_predicate_handle);
|
||||
do_sleep_operation(op);
|
||||
}
|
||||
|
||||
return os_timer->update_and_get_tick();
|
||||
}
|
||||
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
/* The 32-bit limit is part of the API - we will always wake within 2^32 ticks */
|
||||
/* This version is tuned for RTOS use, where the RTOS needs to know the time spent sleeping */
|
||||
uint32_t do_timed_sleep_relative(uint32_t wake_delay, bool (*wake_predicate)(void *), void *wake_predicate_handle)
|
||||
{
|
||||
uint64_t sleep_start = init_os_timer()->get_tick();
|
||||
// When running with RTOS, the requested delay will be based on the kernel's tick count.
|
||||
// If it missed a tick as entering idle, we should reflect that by moving the
|
||||
// start time back to reflect its current idea of time.
|
||||
// Example: OS tick count = 100, our tick count = 101, requested delay = 50
|
||||
// We need to schedule wake for tick 150, report 50 ticks back to our caller, and
|
||||
// clear the unacknowledged tick count.
|
||||
sleep_start -= os_timer->unacknowledged_ticks();
|
||||
|
||||
uint64_t sleep_finish = do_timed_sleep_absolute(sleep_start + wake_delay, wake_predicate, wake_predicate_handle);
|
||||
|
||||
return static_cast<uint32_t>(sleep_finish - sleep_start);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void do_untimed_sleep(bool (*wake_predicate)(void *), void *wake_predicate_handle)
|
||||
{
|
||||
untimed_op op(wake_predicate, wake_predicate_handle);
|
||||
|
||||
do_sleep_operation(op);
|
||||
}
|
||||
|
||||
/* (uint32_t)-1 delay is treated as "wait forever" */
|
||||
/* This version is tuned for non-RTOS use, where we don't need to return sleep time, and waiting forever is possible */
|
||||
void do_timed_sleep_relative_or_forever(uint32_t wake_delay, bool (*wake_predicate)(void *), void *wake_predicate_handle)
|
||||
{
|
||||
// Special-case 0 delay, to save multiple callers having to do it. Just call the predicate once.
|
||||
if (wake_delay == 0) {
|
||||
wake_predicate(wake_predicate_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t wake_time;
|
||||
if (wake_delay == (uint32_t) -1) {
|
||||
wake_time = (uint64_t) -1;
|
||||
} else {
|
||||
wake_time = init_os_timer()->update_and_get_tick() + wake_delay;
|
||||
}
|
||||
/* Always use timed_predicate_op here to save pulling in two templates */
|
||||
timed_predicate_op op(wake_time, wake_predicate, wake_predicate_handle);
|
||||
do_sleep_operation(op);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
} // namespace mbed
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 "platform/SysTimer.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
extern "C" {
|
||||
#include "rtx_lib.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
namespace internal {
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#define OS_TICK_US (1000000 / OS_TICK_FREQ)
|
||||
#else
|
||||
#define OS_TICK_US 1000
|
||||
#endif
|
||||
typedef SysTimer<OS_TICK_US> OsTimer;
|
||||
|
||||
/* 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();
|
||||
|
||||
/* -1 is effectively "sleep forever" */
|
||||
uint64_t do_timed_sleep_absolute(uint64_t 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 */
|
||||
uint32_t do_timed_sleep_relative(uint32_t 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);
|
||||
|
||||
/* (uint32_t)-1 delay is sleep forever */
|
||||
|
||||
void do_timed_sleep_relative_or_forever(uint32_t wake_delay, bool (*wake_predicate)(void *) = NULL, void *wake_predicate_handle = NULL);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,14 +16,7 @@
|
|||
*/
|
||||
#include "mbed_poll.h"
|
||||
#include "FileHandle.h"
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
using namespace rtos;
|
||||
#else
|
||||
#include "drivers/Timer.h"
|
||||
#include "drivers/LowPowerTimer.h"
|
||||
#endif
|
||||
#include "mbed_thread.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -39,23 +32,10 @@ int poll(pollfh fhs[], unsigned nfhs, int timeout)
|
|||
* interested in. In future, his spinning behaviour will be replaced with
|
||||
* condition variables.
|
||||
*/
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
uint64_t start_time = 0;
|
||||
if (timeout > 0) {
|
||||
start_time = Kernel::get_ms_count();
|
||||
start_time = get_ms_count();
|
||||
}
|
||||
#define TIME_ELAPSED() int64_t(Kernel::get_ms_count() - start_time)
|
||||
#else
|
||||
#if MBED_CONF_PLATFORM_POLL_USE_LOWPOWER_TIMER
|
||||
LowPowerTimer timer;
|
||||
#else
|
||||
Timer timer;
|
||||
#endif
|
||||
if (timeout > 0) {
|
||||
timer.start();
|
||||
}
|
||||
#define TIME_ELAPSED() timer.read_ms()
|
||||
#endif // MBED_CONF_RTOS_PRESENT
|
||||
|
||||
int count = 0;
|
||||
for (;;) {
|
||||
|
@ -78,14 +58,12 @@ int poll(pollfh fhs[], unsigned nfhs, int timeout)
|
|||
}
|
||||
|
||||
/* Nothing selected - this is where timeout handling would be needed */
|
||||
if (timeout == 0 || (timeout > 0 && TIME_ELAPSED() > timeout)) {
|
||||
if (timeout == 0 || (timeout > 0 && int64_t(get_ms_count() - start_time) > timeout)) {
|
||||
break;
|
||||
}
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
// TODO - proper blocking
|
||||
// wait for condition variable, wait queue whatever here
|
||||
rtos::ThisThread::sleep_for(1);
|
||||
#endif
|
||||
thread_sleep_for(1);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -32,18 +33,18 @@
|
|||
|
||||
// deep sleep locking counter. A target is allowed to deep sleep if counter == 0
|
||||
static uint16_t deep_sleep_lock = 0U;
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
static us_timestamp_t sleep_time = 0;
|
||||
static us_timestamp_t deep_sleep_time = 0;
|
||||
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
static ticker_data_t *sleep_ticker = NULL;
|
||||
static const ticker_data_t *sleep_ticker = NULL;
|
||||
#endif
|
||||
|
||||
static inline us_timestamp_t read_us(void)
|
||||
{
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
if (NULL == sleep_ticker) {
|
||||
sleep_ticker = (ticker_data_t *)get_lp_ticker_data();
|
||||
sleep_ticker = get_lp_ticker_data();
|
||||
}
|
||||
return ticker_read_us(sleep_ticker);
|
||||
#else
|
||||
|
@ -53,7 +54,11 @@ static inline us_timestamp_t read_us(void)
|
|||
|
||||
us_timestamp_t mbed_time_idle(void)
|
||||
{
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
return (sleep_time + deep_sleep_time);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
us_timestamp_t mbed_uptime(void)
|
||||
|
@ -63,12 +68,20 @@ us_timestamp_t mbed_uptime(void)
|
|||
|
||||
us_timestamp_t mbed_time_sleep(void)
|
||||
{
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
return sleep_time;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
us_timestamp_t mbed_time_deepsleep(void)
|
||||
{
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
return deep_sleep_time;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MBED_SLEEP_TRACING_ENABLED
|
||||
|
@ -211,27 +224,33 @@ void sleep_manager_sleep_auto(void)
|
|||
sleep_tracker_print_stats();
|
||||
#endif
|
||||
core_util_critical_section_enter();
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
us_timestamp_t start = read_us();
|
||||
bool deep = false;
|
||||
#endif
|
||||
|
||||
// debug profile should keep debuggers attached, no deep sleep allowed
|
||||
#ifdef MBED_DEBUG
|
||||
hal_sleep();
|
||||
#else
|
||||
if (sleep_manager_can_deep_sleep()) {
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
deep = true;
|
||||
#endif
|
||||
hal_deepsleep();
|
||||
} else {
|
||||
hal_sleep();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && DEVICE_LPTICKER
|
||||
us_timestamp_t end = read_us();
|
||||
if (true == deep) {
|
||||
deep_sleep_time += end - start;
|
||||
} else {
|
||||
sleep_time += end - start;
|
||||
}
|
||||
#endif
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,12 @@
|
|||
#include "device.h"
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
#include "cmsis_os2.h"
|
||||
#include "rtos_idle.h"
|
||||
#elif defined(MBED_STACK_STATS_ENABLED) || defined(MBED_THREAD_STATS_ENABLED) || defined(MBED_CPU_STATS_ENABLED)
|
||||
#elif defined(MBED_STACK_STATS_ENABLED) || defined(MBED_THREAD_STATS_ENABLED)
|
||||
#warning Statistics are currently not supported without the rtos.
|
||||
#endif
|
||||
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && (!DEVICE_LPTICKER || !DEVICE_SLEEP)
|
||||
#warning CPU statistics are not supported without low power timer support.
|
||||
#if defined(MBED_CPU_STATS_ENABLED) && (!DEVICE_SLEEP)
|
||||
#warning CPU statistics are not supported without sleep support.
|
||||
#endif
|
||||
|
||||
void mbed_stats_cpu_get(mbed_stats_cpu_t *stats)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <stdint.h>
|
||||
|
||||
#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
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef MBED_WAIT_API_H
|
||||
#define MBED_WAIT_API_H
|
||||
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/mbed_atomic.h"
|
||||
#include "device.h"
|
||||
|
||||
|
@ -62,7 +63,16 @@ extern "C" {
|
|||
* If the RTOS is present, this function spins to get the exact number of microseconds for
|
||||
* microsecond precision up to 10 milliseconds. If delay is larger than 10 milliseconds and not in ISR, it is the same as
|
||||
* `wait_ms`. We recommend `wait_us` and `wait_ms` over `wait`.
|
||||
*
|
||||
* @deprecated
|
||||
* 'wait' is deprecated in favor of explicit sleep functions. To sleep, 'wait' should be replaced by
|
||||
* 'ThisThread::sleep_for' (C++) or 'thread_sleep_for' (C). If you wish to wait (without sleeping), call
|
||||
* 'wait_us'. 'wait_us' is safe to call from ISR context.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.14",
|
||||
"'wait' is deprecated in favor of explicit sleep functions. To sleep, 'wait' should be replaced by "
|
||||
"'ThisThread::sleep_for' (C++) or 'thread_sleep_for' (C). If you wish to wait (without sleeping), call "
|
||||
"'wait_us'. 'wait_us' is safe to call from ISR context.")
|
||||
void wait(float s);
|
||||
|
||||
/** Waits a number of milliseconds.
|
||||
|
@ -72,7 +82,16 @@ void wait(float s);
|
|||
* @note
|
||||
* If the RTOS is present, it calls ThisThread::sleep_for(), which is same as CMSIS osDelay().
|
||||
* You can't call this from interrupts, and it doesn't lock hardware sleep.
|
||||
*
|
||||
* @deprecated
|
||||
* 'wait_ms' is deprecated in favor of explicit sleep functions. To sleep, 'wait_ms' should be replaced by
|
||||
* 'ThisThread::sleep_for' (C++) or 'thread_sleep_for' (C). If you wish to wait (without sleeping), call
|
||||
* 'wait_us'. 'wait_us' is safe to call from ISR context.
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.14",
|
||||
"'wait_ms' is deprecated in favor of explicit sleep functions. To sleep, 'wait_ms' should be replaced by "
|
||||
"'ThisThread::sleep_for' (C++) or 'thread_sleep_for' (C). If you wish to wait (without sleeping), call "
|
||||
"'wait_us'. 'wait_us' is safe to call from ISR context.")
|
||||
void wait_ms(int ms);
|
||||
|
||||
/** Waits a number of microseconds.
|
||||
|
@ -82,7 +101,7 @@ void wait_ms(int ms);
|
|||
* @note
|
||||
* This function always spins to get the exact number of microseconds.
|
||||
* This will affect power and multithread performance. Therefore, spinning for
|
||||
* millisecond wait is not recommended, and wait_ms() should
|
||||
* millisecond wait is not recommended, and ThisThread::sleep_for should
|
||||
* be used instead.
|
||||
*
|
||||
* @note You may call this function from ISR context, but large delays may
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
*/
|
||||
|
||||
// This implementation of the wait functions will be compiled only
|
||||
// if the RTOS is present.
|
||||
// if the RTOS is present. Note that we still use these old
|
||||
// bare metal versions of wait and wait_ms rather than using
|
||||
// thread_sleep_for for backwards compatibility. People should
|
||||
// be prompted to shift via their deprecation.
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
|
||||
#include "platform/mbed_wait_api.h"
|
||||
|
@ -30,7 +33,7 @@
|
|||
void wait(float s)
|
||||
{
|
||||
if ((s >= 0.01f) && core_util_are_interrupts_enabled()) {
|
||||
wait_ms(s * 1000.0f);
|
||||
rtos::ThisThread::sleep_for(s * 1000.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,14 +26,16 @@
|
|||
#include "mbed_error.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
|
||||
namespace rtos {
|
||||
|
||||
ConditionVariable::Waiter::Waiter(): sem(0), prev(NULL), next(NULL), in_list(false)
|
||||
ConditionVariable::Waiter::Waiter(): sem(0), prev(nullptr), next(nullptr), in_list(false)
|
||||
{
|
||||
// No initialization to do
|
||||
}
|
||||
|
||||
ConditionVariable::ConditionVariable(Mutex &mutex): _mutex(mutex), _wait_list(NULL)
|
||||
ConditionVariable::ConditionVariable(Mutex &mutex): _mutex(mutex), _wait_list(nullptr)
|
||||
{
|
||||
// No initialization to do
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ bool ConditionVariable::wait_until(uint64_t millisec)
|
|||
void ConditionVariable::notify_one()
|
||||
{
|
||||
MBED_ASSERT(_mutex.get_owner() == ThisThread::get_id());
|
||||
if (_wait_list != NULL) {
|
||||
if (_wait_list != nullptr) {
|
||||
_wait_list->sem.release();
|
||||
_remove_wait_list(&_wait_list, _wait_list);
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ void ConditionVariable::notify_one()
|
|||
void ConditionVariable::notify_all()
|
||||
{
|
||||
MBED_ASSERT(_mutex.get_owner() == ThisThread::get_id());
|
||||
while (_wait_list != NULL) {
|
||||
while (_wait_list != nullptr) {
|
||||
_wait_list->sem.release();
|
||||
_remove_wait_list(&_wait_list, _wait_list);
|
||||
}
|
||||
|
@ -101,7 +103,7 @@ void ConditionVariable::notify_all()
|
|||
|
||||
void ConditionVariable::_add_wait_list(Waiter **wait_list, Waiter *waiter)
|
||||
{
|
||||
if (NULL == *wait_list) {
|
||||
if (nullptr == *wait_list) {
|
||||
// Nothing in the list so add it directly.
|
||||
// Update prev and next pointer to reference self
|
||||
*wait_list = waiter;
|
||||
|
@ -135,18 +137,20 @@ void ConditionVariable::_remove_wait_list(Waiter **wait_list, Waiter *waiter)
|
|||
|
||||
if (*wait_list == waiter) {
|
||||
// This was the last element in the list
|
||||
*wait_list = NULL;
|
||||
*wait_list = nullptr;
|
||||
}
|
||||
|
||||
// Invalidate pointers
|
||||
waiter->next = NULL;
|
||||
waiter->prev = NULL;
|
||||
waiter->next = nullptr;
|
||||
waiter->prev = nullptr;
|
||||
waiter->in_list = false;
|
||||
}
|
||||
|
||||
ConditionVariable::~ConditionVariable()
|
||||
{
|
||||
MBED_ASSERT(NULL == _wait_list);
|
||||
MBED_ASSERT(nullptr == _wait_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
#define CONDITIONVARIABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
|
@ -328,4 +330,6 @@ protected:
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
#include "rtos/EventFlags.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "mbed_os_timer.h"
|
||||
#include <string.h>
|
||||
#include "mbed_error.h"
|
||||
#include "mbed_assert.h"
|
||||
|
@ -28,7 +30,7 @@ namespace rtos {
|
|||
|
||||
EventFlags::EventFlags()
|
||||
{
|
||||
constructor();
|
||||
constructor("application_unnamed_event_flags");
|
||||
}
|
||||
|
||||
EventFlags::EventFlags(const char *name)
|
||||
|
@ -38,27 +40,43 @@ EventFlags::EventFlags(const char *name)
|
|||
|
||||
void EventFlags::constructor(const char *name)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osEventFlagsAttr_t attr = { 0 };
|
||||
attr.name = name ? name : "application_unnamed_event_flags";
|
||||
attr.name = name;
|
||||
attr.cb_mem = &_obj_mem;
|
||||
attr.cb_size = sizeof(_obj_mem);
|
||||
_id = osEventFlagsNew(&attr);
|
||||
MBED_ASSERT(_id);
|
||||
#else
|
||||
_flags = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t EventFlags::set(uint32_t flags)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osEventFlagsSet(_id, flags);
|
||||
#else
|
||||
return core_util_atomic_fetch_or_u32(&_flags, flags) | flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t EventFlags::clear(uint32_t flags)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osEventFlagsClear(_id, flags);
|
||||
#else
|
||||
return core_util_atomic_fetch_and_u32(&_flags, ~flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t EventFlags::get() const
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osEventFlagsGet(_id);
|
||||
#else
|
||||
return core_util_atomic_load_u32(&_flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t EventFlags::wait_all(uint32_t flags, uint32_t millisec, bool clear)
|
||||
|
@ -73,7 +91,9 @@ uint32_t EventFlags::wait_any(uint32_t flags, uint32_t millisec, bool clear)
|
|||
|
||||
EventFlags::~EventFlags()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osEventFlagsDelete(_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool clear)
|
||||
|
@ -82,7 +102,24 @@ uint32_t EventFlags::wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool
|
|||
opt |= osFlagsNoClear;
|
||||
}
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osEventFlagsWait(_id, flags, opt, millisec);
|
||||
#else
|
||||
rtos::internal::flags_check_capture check;
|
||||
check.flags = &_flags;
|
||||
check.options = opt;
|
||||
check.flags_wanted = flags;
|
||||
check.result = 0;
|
||||
check.match = false;
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(millisec, rtos::internal::non_rtos_check_flags, &check);
|
||||
if (check.match) {
|
||||
return check.result;
|
||||
} else if (millisec == 0) {
|
||||
return osErrorResource;
|
||||
} else {
|
||||
return osErrorTimeout;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
#define EVENT_FLAG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
|
@ -112,10 +112,14 @@ public:
|
|||
~EventFlags();
|
||||
|
||||
private:
|
||||
void constructor(const char *name = NULL);
|
||||
void constructor(const char *name = nullptr);
|
||||
uint32_t wait(uint32_t flags, uint32_t opt, uint32_t millisec, bool clear);
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osEventFlagsId_t _id;
|
||||
mbed_rtos_storage_event_flags_t _obj_mem;
|
||||
#else
|
||||
uint32_t _flags;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** @}*/
|
||||
|
|
|
@ -20,16 +20,23 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "rtos/rtos_handlers.h"
|
||||
#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()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
// CMSIS-RTOS 2.1.0 and 2.1.1 differ in the time type. We assume
|
||||
// our header at least matches the implementation, so we don't try looking
|
||||
// at the run-time version report. (There's no compile-time version report)
|
||||
|
@ -61,8 +68,12 @@ uint64_t Kernel::get_ms_count()
|
|||
core_util_critical_section_exit();
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
return ::get_ms_count();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
void Kernel::attach_idle_hook(void (*fptr)(void))
|
||||
{
|
||||
rtos_attach_idle_hook(fptr);
|
||||
|
@ -72,5 +83,6 @@ void Kernel::attach_thread_terminate_hook(void (*fptr)(osThreadId_t id))
|
|||
{
|
||||
rtos_attach_thread_terminate_hook(fptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define KERNEL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
|
|
|
@ -3,12 +3,9 @@ as can be found: LICENSE-apache-2.0.txt.
|
|||
|
||||
Files licensed under MIT:
|
||||
|
||||
- TARGET_CORTEX/mbed_rtos1_types.h
|
||||
- TARGET_CORTEX/mbed_rtos_storage.h
|
||||
- TARGET_CORTEX/mbed_rtx_conf.h
|
||||
- TARGET_CORTEX/mbed_rtx_idle.cpp
|
||||
- TARGET_CORTEX/SysTimer.h
|
||||
- TARGET_CORTEX/SysTimer.cpp
|
||||
- ConditionVariable.cpp
|
||||
- ConditionVariable.h
|
||||
- EventFlags.cpp
|
||||
|
|
26
rtos/Mail.h
26
rtos/Mail.h
|
@ -25,11 +25,11 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Queue.h"
|
||||
#include "MemoryPool.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "rtos/Queue.h"
|
||||
#include "rtos/MemoryPool.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
@ -38,6 +38,8 @@
|
|||
using namespace rtos;
|
||||
#endif
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
|
@ -95,7 +97,7 @@ public:
|
|||
*
|
||||
* @param millisec Not used (see note).
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context.
|
||||
* @note If blocking is required, use Mail::alloc_for or Mail::alloc_until
|
||||
|
@ -109,7 +111,7 @@ public:
|
|||
*
|
||||
* @param millisec Timeout value, or osWaitForever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
|
@ -122,7 +124,7 @@ public:
|
|||
*
|
||||
* @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
|
@ -139,7 +141,7 @@ public:
|
|||
*
|
||||
* @param millisec Not used (see note).
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
* @note If blocking is required, use Mail::calloc_for or Mail::calloc_until
|
||||
|
@ -153,7 +155,7 @@ public:
|
|||
*
|
||||
* @param millisec Timeout value, or osWaitForever.
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
|
@ -166,7 +168,7 @@ public:
|
|||
*
|
||||
* @param millisec Absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
*
|
||||
* @return Pointer to memory block that you can fill with mail or NULL in case error.
|
||||
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
|
||||
*
|
||||
* @note You cannot call this function from ISR context.
|
||||
* @note the underlying RTOS may have a limit to the maximum wait time
|
||||
|
@ -238,5 +240,5 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
|
@ -76,7 +77,7 @@ public:
|
|||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking.
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
|
@ -87,7 +88,7 @@ public:
|
|||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking.
|
||||
@param millisec timeout value (osWaitForever to wait forever)
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
|
@ -98,7 +99,7 @@ public:
|
|||
|
||||
/** Allocate a memory block from a memory pool, blocking.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
|
@ -121,14 +122,14 @@ public:
|
|||
}
|
||||
|
||||
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
T *calloc(void)
|
||||
{
|
||||
T *item = alloc();
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
|
@ -136,14 +137,14 @@ public:
|
|||
|
||||
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
|
||||
@param millisec timeout value (osWaitForever to wait forever)
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You may call this function from ISR context if the millisec parameter is set to 0.
|
||||
*/
|
||||
T *calloc_for(uint32_t millisec)
|
||||
{
|
||||
T *item = alloc_for(millisec);
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
|
@ -151,7 +152,7 @@ public:
|
|||
|
||||
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
|
||||
@param millisec absolute timeout time, referenced to Kernel::get_ms_count().
|
||||
@return address of the allocated memory block or NULL in case of no memory available.
|
||||
@return address of the allocated memory block or nullptr in case of no memory available.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
@note the underlying RTOS may have a limit to the maximum wait time
|
||||
|
@ -162,7 +163,7 @@ public:
|
|||
T *calloc_until(uint64_t millisec)
|
||||
{
|
||||
T *item = alloc_until(millisec);
|
||||
if (item != NULL) {
|
||||
if (item != nullptr) {
|
||||
memset(item, 0, sizeof(T));
|
||||
}
|
||||
return item;
|
||||
|
@ -171,7 +172,7 @@ public:
|
|||
/** Free a memory block.
|
||||
@param block address of the allocated memory block to be freed.
|
||||
@return osOK on successful deallocation, osErrorParameter if given memory block id
|
||||
is NULL or invalid, or osErrorResource if given memory block is in an
|
||||
is nullptr or invalid, or osErrorResource if given memory block is in an
|
||||
invalid memory pool state.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
|
@ -191,3 +192,4 @@ private:
|
|||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
#include "mbed_error.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
|
||||
namespace rtos {
|
||||
|
||||
Mutex::Mutex(): _count(0)
|
||||
Mutex::Mutex()
|
||||
{
|
||||
constructor();
|
||||
}
|
||||
|
@ -40,6 +42,7 @@ Mutex::Mutex(const char *name)
|
|||
|
||||
void Mutex::constructor(const char *name)
|
||||
{
|
||||
_count = 0;
|
||||
osMutexAttr_t attr =
|
||||
{ 0 };
|
||||
attr.name = name ? name : "application_unnamed_mutex";
|
||||
|
@ -147,3 +150,5 @@ Mutex::~Mutex()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
62
rtos/Mutex.h
62
rtos/Mutex.h
|
@ -23,9 +23,9 @@
|
|||
#define MUTEX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/ScopedLock.h"
|
||||
|
@ -56,6 +56,8 @@ typedef mbed::ScopedLock<Mutex> ScopedMutexLock;
|
|||
/** The Mutex class is used to synchronize the execution of threads.
|
||||
This is, for example, used to protect access to a shared resource.
|
||||
|
||||
In bare-metal builds, the Mutex class is a dummy, so lock() and unlock() are no-ops.
|
||||
|
||||
@note You cannot use member functions of this class in ISR context. If you require Mutex functionality within
|
||||
ISR handler, consider using @a Semaphore.
|
||||
|
||||
|
@ -88,7 +90,11 @@ public:
|
|||
@note This function treats RTOS errors as fatal system errors, so it can only return osOK.
|
||||
Use of the return value is deprecated, as the return is expected to become void in the future.
|
||||
*/
|
||||
osStatus lock(void);
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus lock();
|
||||
#else
|
||||
void lock(); // Value return backwards compatibility not required for non-RTOS
|
||||
#endif
|
||||
|
||||
/**
|
||||
Wait until a Mutex becomes available.
|
||||
|
@ -150,14 +156,18 @@ public:
|
|||
@note This function treats RTOS errors as fatal system errors, so it can only return osOK.
|
||||
Use of the return value is deprecated, as the return is expected to become void in the future.
|
||||
*/
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus unlock();
|
||||
#else
|
||||
void unlock(); // Value return backwards compatibility not required for non-RTOS
|
||||
#endif
|
||||
|
||||
/** Get the owner the this mutex
|
||||
@return the current owner of this mutex.
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
osThreadId get_owner();
|
||||
osThreadId_t get_owner();
|
||||
|
||||
/** Mutex destructor
|
||||
*
|
||||
|
@ -166,13 +176,53 @@ public:
|
|||
~Mutex();
|
||||
|
||||
private:
|
||||
void constructor(const char *name = NULL);
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
void constructor(const char *name = nullptr);
|
||||
friend class ConditionVariable;
|
||||
|
||||
osMutexId_t _id;
|
||||
mbed_rtos_storage_mutex_t _obj_mem;
|
||||
uint32_t _count;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !MBED_CONF_RTOS_PRESENT
|
||||
inline Mutex::Mutex()
|
||||
{
|
||||
}
|
||||
|
||||
inline Mutex::Mutex(const char *)
|
||||
{
|
||||
}
|
||||
|
||||
inline Mutex::~Mutex()
|
||||
{
|
||||
}
|
||||
|
||||
inline void Mutex::lock()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_for(uint32_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Mutex::trylock_until(uint64_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Mutex::unlock()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
}
|
||||
|
|
14
rtos/Queue.h
14
rtos/Queue.h
|
@ -22,12 +22,14 @@
|
|||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
|
@ -185,8 +187,8 @@ public:
|
|||
osEvent get(uint32_t millisec = osWaitForever)
|
||||
{
|
||||
osEvent event;
|
||||
T *data = NULL;
|
||||
osStatus_t res = osMessageQueueGet(_id, &data, NULL, millisec);
|
||||
T *data = nullptr;
|
||||
osStatus_t res = osMessageQueueGet(_id, &data, nullptr, millisec);
|
||||
|
||||
switch (res) {
|
||||
case osOK:
|
||||
|
@ -219,4 +221,6 @@ private:
|
|||
|
||||
} // namespace rtos
|
||||
|
||||
#endif
|
||||
|
||||
#endif // QUEUE_H
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
|
||||
namespace rtos {
|
||||
|
||||
void RtosTimer::constructor(mbed::Callback<void()> func, os_timer_type type)
|
||||
|
@ -54,3 +56,5 @@ RtosTimer::~RtosTimer()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
#define RTOS_TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
|
@ -60,7 +62,7 @@ namespace rtos {
|
|||
RtosTimer timer(&blink);
|
||||
int main() {
|
||||
timer.start(1000); // call blink every 1s
|
||||
wait_ms(5000);
|
||||
ThisThread::sleep_for(5000);
|
||||
timer.stop(); // stop after 5s
|
||||
}
|
||||
@endcode
|
||||
|
@ -89,7 +91,7 @@ public:
|
|||
/** Create timer.
|
||||
@param func function to be executed by this timer.
|
||||
@param type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. (default: osTimerPeriodic)
|
||||
@param argument argument to the timer call back function. (default: NULL)
|
||||
@param argument argument to the timer call back function. (default: nullptr)
|
||||
@deprecated Replaced with RtosTimer(Callback<void()>, os_timer_type)
|
||||
@deprecated
|
||||
The RtosTimer has been superseded by the EventQueue. See RtosTimer.h for more details
|
||||
|
@ -100,7 +102,7 @@ public:
|
|||
"Replaced with RtosTimer(Callback<void()>, os_timer_type)")
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.2",
|
||||
"The RtosTimer has been superseded by the EventQueue. See RtosTimer.h for more details")
|
||||
RtosTimer(void (*func)(void const *argument), os_timer_type type = osTimerPeriodic, void *argument = NULL)
|
||||
RtosTimer(void (*func)(void const *argument), os_timer_type type = osTimerPeriodic, void *argument = nullptr)
|
||||
{
|
||||
constructor(mbed::callback((void (*)(void *))func, argument), type);
|
||||
}
|
||||
|
@ -188,4 +190,4 @@ private:
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "platform/mbed_os_timer.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -40,22 +42,51 @@ Semaphore::Semaphore(int32_t count, uint16_t max_count)
|
|||
|
||||
void Semaphore::constructor(int32_t count, uint16_t max_count)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osSemaphoreAttr_t attr = { 0 };
|
||||
attr.cb_mem = &_obj_mem;
|
||||
attr.cb_size = sizeof(_obj_mem);
|
||||
_id = osSemaphoreNew(max_count, count, &attr);
|
||||
MBED_ASSERT(_id != NULL);
|
||||
MBED_ASSERT(_id != nullptr);
|
||||
#else
|
||||
_count = count;
|
||||
_max_count = max_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !MBED_CONF_RTOS_PRESENT
|
||||
struct sem_wait_capture {
|
||||
Semaphore *sem;
|
||||
bool acquired;
|
||||
};
|
||||
|
||||
bool Semaphore::semaphore_available(void *handle)
|
||||
{
|
||||
sem_wait_capture *wait = static_cast<sem_wait_capture *>(handle);
|
||||
return wait->acquired = wait->sem->try_acquire();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Semaphore::try_acquire()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus_t status = osSemaphoreAcquire(_id, 0);
|
||||
if (status != osOK && status != osErrorResource) {
|
||||
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed", status);
|
||||
}
|
||||
return status == osOK;
|
||||
#else
|
||||
int32_t old_count = core_util_atomic_load_s32(&_count);
|
||||
do {
|
||||
if (old_count == 0) {
|
||||
return false;
|
||||
}
|
||||
} while (!core_util_atomic_cas_s32(&_count, &old_count, old_count - 1));
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
/* To sidestep deprecation warnings */
|
||||
int32_t Semaphore::_wait(uint32_t millisec)
|
||||
{
|
||||
|
@ -71,14 +102,26 @@ int32_t Semaphore::_wait(uint32_t millisec)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t Semaphore::wait(uint32_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return _wait(millisec);
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(millisec, semaphore_available, &capture);
|
||||
if (capture.acquired) {
|
||||
return core_util_atomic_load_s32(&_count) + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t Semaphore::wait_until(uint64_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
|
||||
if (now >= millisec) {
|
||||
|
@ -89,18 +132,36 @@ int32_t Semaphore::wait_until(uint64_t millisec)
|
|||
} else {
|
||||
return _wait(millisec - now);
|
||||
}
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_absolute(millisec, semaphore_available, &capture);
|
||||
if (capture.acquired) {
|
||||
return core_util_atomic_load_s32(&_count) + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Semaphore::acquire()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus_t status = osSemaphoreAcquire(_id, osWaitForever);
|
||||
if (status != osOK) {
|
||||
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed", status);
|
||||
}
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_untimed_sleep(semaphore_available, &capture);
|
||||
if (!capture.acquired) {
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Semaphore::try_acquire_for(uint32_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus_t status = osSemaphoreAcquire(_id, millisec);
|
||||
if (status == osOK) {
|
||||
return true;
|
||||
|
@ -113,10 +174,16 @@ bool Semaphore::try_acquire_for(uint32_t millisec)
|
|||
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_SEMAPHORE_LOCK_FAILED), "Semaphore acquire failed", status);
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(millisec, semaphore_available, &capture);
|
||||
return capture.acquired;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Semaphore::try_acquire_until(uint64_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
|
||||
if (now >= millisec) {
|
||||
|
@ -127,16 +194,33 @@ bool Semaphore::try_acquire_until(uint64_t millisec)
|
|||
} else {
|
||||
return try_acquire_for(millisec - now);
|
||||
}
|
||||
#else
|
||||
sem_wait_capture capture = { this, false };
|
||||
mbed::internal::do_timed_sleep_absolute(millisec, semaphore_available, &capture);
|
||||
return capture.acquired;
|
||||
#endif
|
||||
}
|
||||
|
||||
osStatus Semaphore::release(void)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osSemaphoreRelease(_id);
|
||||
#else
|
||||
int32_t old_count = core_util_atomic_load_s32(&_count);
|
||||
do {
|
||||
if (old_count == _max_count) {
|
||||
return osErrorResource;
|
||||
}
|
||||
} while (!core_util_atomic_cas_s32(&_count, &old_count, old_count + 1));
|
||||
#endif
|
||||
return osOK;
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osSemaphoreDelete(_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
#define SEMAPHORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
|
@ -141,10 +141,16 @@ public:
|
|||
private:
|
||||
void constructor(int32_t count, uint16_t max_count);
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
int32_t _wait(uint32_t millisec);
|
||||
|
||||
osSemaphoreId_t _id;
|
||||
mbed_rtos_storage_semaphore_t _obj_mem;
|
||||
#else
|
||||
static bool semaphore_available(void *);
|
||||
int32_t _count;
|
||||
uint16_t _max_count;
|
||||
#endif
|
||||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2012 ARM Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#include "rtos/TARGET_CORTEX/SysTimer.h"
|
||||
|
||||
#if MBED_TICKLESS
|
||||
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
#include "rtx_core_ca.h"
|
||||
#else//Cortex-M
|
||||
#include "rtx_core_cm.h"
|
||||
#endif
|
||||
extern "C" {
|
||||
#include "rtx_lib.h"
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
#include "irq_ctrl.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
#define US_IN_TICK (1000000 / OS_TICK_FREQ)
|
||||
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
|
||||
|
||||
#if (defined(NO_SYSTICK))
|
||||
/**
|
||||
* Return an IRQ number that can be used in the absence of SysTick
|
||||
*
|
||||
* @return Free IRQ number that can be used
|
||||
*/
|
||||
extern "C" IRQn_Type mbed_get_m0_tick_irqn(void);
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void);
|
||||
#endif
|
||||
|
||||
namespace rtos {
|
||||
namespace internal {
|
||||
|
||||
SysTimer::SysTimer() :
|
||||
#if DEVICE_LPTICKER
|
||||
TimerEvent(get_lp_ticker_data()),
|
||||
#else
|
||||
TimerEvent(get_us_ticker_data()),
|
||||
#endif
|
||||
_time_us(0), _tick(0)
|
||||
{
|
||||
_time_us = ticker_read_us(_ticker_data);
|
||||
_suspend_time_passed = true;
|
||||
_suspended = false;
|
||||
}
|
||||
|
||||
SysTimer::SysTimer(const ticker_data_t *data) :
|
||||
TimerEvent(data), _time_us(0), _tick(0)
|
||||
{
|
||||
_time_us = ticker_read_us(_ticker_data);
|
||||
_suspend_time_passed = true;
|
||||
_suspended = false;
|
||||
}
|
||||
|
||||
void SysTimer::setup_irq()
|
||||
{
|
||||
#if (defined(NO_SYSTICK) && !defined (TARGET_CORTEX_A))
|
||||
NVIC_SetVector(mbed_get_m0_tick_irqn(), (uint32_t)SysTick_Handler);
|
||||
NVIC_SetPriority(mbed_get_m0_tick_irqn(), 0xFF); /* RTOS requires lowest priority */
|
||||
NVIC_EnableIRQ(mbed_get_m0_tick_irqn());
|
||||
#else
|
||||
// Ensure SysTick has the correct priority as it is still used
|
||||
// to trigger software interrupts on each tick. The period does
|
||||
// not matter since it will never start counting.
|
||||
OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SysTimer::suspend(uint32_t ticks)
|
||||
{
|
||||
// Remove ensures serialized access to SysTimer by stopping timer interrupt
|
||||
remove();
|
||||
|
||||
_suspend_time_passed = false;
|
||||
_suspended = true;
|
||||
|
||||
schedule_tick(ticks);
|
||||
}
|
||||
|
||||
bool SysTimer::suspend_time_passed()
|
||||
{
|
||||
return _suspend_time_passed;
|
||||
}
|
||||
|
||||
uint32_t SysTimer::resume()
|
||||
{
|
||||
// Remove ensures serialized access to SysTimer by stopping timer interrupt
|
||||
remove();
|
||||
|
||||
_suspended = false;
|
||||
_suspend_time_passed = true;
|
||||
|
||||
uint64_t elapsed_ticks = (ticker_read_us(_ticker_data) - _time_us) / US_IN_TICK;
|
||||
if (elapsed_ticks > 0) {
|
||||
// Don't update to the current tick. Instead, update to the
|
||||
// previous tick and let the SysTick handler increment it
|
||||
// to the current value. This allows scheduling restart
|
||||
// successfully after the OS is resumed.
|
||||
elapsed_ticks--;
|
||||
}
|
||||
_time_us += elapsed_ticks * US_IN_TICK;
|
||||
_tick += elapsed_ticks;
|
||||
|
||||
return elapsed_ticks;
|
||||
}
|
||||
|
||||
void SysTimer::schedule_tick(uint32_t delta)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
||||
insert_absolute(_time_us + delta * US_IN_TICK);
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void SysTimer::cancel_tick()
|
||||
{
|
||||
// Underlying call is interrupt safe
|
||||
|
||||
remove();
|
||||
}
|
||||
|
||||
uint32_t SysTimer::get_tick()
|
||||
{
|
||||
return _tick & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
us_timestamp_t SysTimer::get_time()
|
||||
{
|
||||
// Underlying call is interrupt safe
|
||||
|
||||
return ticker_read_us(_ticker_data);
|
||||
}
|
||||
|
||||
SysTimer::~SysTimer()
|
||||
{
|
||||
}
|
||||
|
||||
void SysTimer::_set_irq_pending()
|
||||
{
|
||||
// Protected function synchronized externally
|
||||
|
||||
#if (defined(NO_SYSTICK))
|
||||
NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn());
|
||||
#elif (TARGET_CORTEX_A)
|
||||
IRQ_SetPending(mbed_get_a9_tick_irqn());
|
||||
#else
|
||||
SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SysTimer::_increment_tick()
|
||||
{
|
||||
// Protected function synchronized externally
|
||||
|
||||
_tick++;
|
||||
_time_us += US_IN_TICK;
|
||||
}
|
||||
|
||||
void SysTimer::handler()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
||||
if (_suspended) {
|
||||
_suspend_time_passed = true;
|
||||
} else {
|
||||
_set_irq_pending();
|
||||
_increment_tick();
|
||||
schedule_tick();
|
||||
}
|
||||
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MBED_TICKLESS
|
|
@ -1,137 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2012 ARM Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MBED_SYS_TIMER_H
|
||||
#define MBED_SYS_TIMER_H
|
||||
|
||||
#if MBED_TICKLESS || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "drivers/TimerEvent.h"
|
||||
|
||||
namespace rtos {
|
||||
namespace internal {
|
||||
|
||||
/**
|
||||
* @cond RTOS_INTERNAL
|
||||
*
|
||||
* @addtogroup rtos
|
||||
* @{
|
||||
*
|
||||
* @defgroup rtos_SysTimer SysTimer class
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The SysTimer class is used exclusively by RTX idle loop in TICKLESS mode.
|
||||
*
|
||||
* @note SysTimer is not the part of Mbed RTOS API.
|
||||
*/
|
||||
class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable<SysTimer> {
|
||||
public:
|
||||
|
||||
SysTimer();
|
||||
SysTimer(const ticker_data_t *data);
|
||||
virtual ~SysTimer();
|
||||
|
||||
/**
|
||||
* Enable an IRQ/SysTick with the correct priority.
|
||||
*/
|
||||
static void setup_irq();
|
||||
|
||||
/**
|
||||
* Set wakeup time and schedule a wakeup event after delta ticks
|
||||
*
|
||||
* After suspend has been called the function suspend_time_passed
|
||||
* can be used to determine if the suspend time has passed.
|
||||
*
|
||||
* @param delta Ticks to remain suspended
|
||||
*/
|
||||
void suspend(uint32_t delta);
|
||||
|
||||
/**
|
||||
* Check if the suspend time has passed
|
||||
*
|
||||
* @return true if the specified number of ticks has passed otherwise false
|
||||
*/
|
||||
bool suspend_time_passed();
|
||||
|
||||
/**
|
||||
* Exit suspend mode and return elapsed ticks
|
||||
*
|
||||
* Due to a scheduling issue, the number of ticks returned is decremented
|
||||
* by 1 so that a handler can be called and update to the current value.
|
||||
* This allows scheduling restart successfully after the OS is resumed.
|
||||
*
|
||||
* @return the number of elapsed ticks minus 1
|
||||
*/
|
||||
uint32_t resume();
|
||||
|
||||
/**
|
||||
* Schedule an os tick to fire
|
||||
*
|
||||
* @param delta Tick to fire at relative to current tick
|
||||
*
|
||||
* @warning If a tick is already scheduled it needs to be cancelled first!
|
||||
*/
|
||||
void schedule_tick(uint32_t delta = 1);
|
||||
|
||||
/**
|
||||
* Prevent any scheduled ticks from triggering
|
||||
*/
|
||||
void cancel_tick();
|
||||
|
||||
/** Get the current tick count
|
||||
*
|
||||
* @return The number of ticks since timer creation. For the os_timer this
|
||||
* should match RTX's tick count (the number of ticks since boot).
|
||||
*/
|
||||
uint32_t get_tick();
|
||||
|
||||
/**
|
||||
* Get the time
|
||||
*
|
||||
* @return Current time in microseconds
|
||||
*/
|
||||
us_timestamp_t get_time();
|
||||
|
||||
protected:
|
||||
virtual void handler();
|
||||
void _increment_tick();
|
||||
static void _set_irq_pending();
|
||||
us_timestamp_t _time_us;
|
||||
uint64_t _tick;
|
||||
bool _suspend_time_passed;
|
||||
bool _suspended;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"name": "rtos",
|
||||
"config": {
|
||||
"present": 1,
|
||||
"main-thread-stack-size": {
|
||||
"help": "The size of the main thread's stack",
|
||||
"value": 4096
|
||||
},
|
||||
"timer-thread-stack-size": {
|
||||
"help": "The size of the timer thread's stack",
|
||||
"value": 768
|
||||
},
|
||||
"idle-thread-stack-size": {
|
||||
"help": "The size of the idle thread's stack",
|
||||
"value": 512
|
||||
},
|
||||
"thread-stack-size": {
|
||||
"help": "The default stack size of new threads",
|
||||
"value": 4096
|
||||
},
|
||||
"idle-thread-stack-size-tickless-extra": {
|
||||
"help": "Additional size to add to the idle thread when a specific target or application implementation requires it or in case tickless is enabled and LPTICKER_DELAY_TICKS is used",
|
||||
"value": 256
|
||||
},
|
||||
"idle-thread-stack-size-debug-extra": {
|
||||
"help": "Additional size to add to the idle thread when code compilation optimisation is disabled",
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
"macros": ["_RTE_"],
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"target.boot-stack-size": "0x400"
|
||||
},
|
||||
"STM": {
|
||||
"idle-thread-stack-size-debug-extra": 128
|
||||
},
|
||||
"STM32L1": {
|
||||
"idle-thread-stack-size-debug-extra": 512
|
||||
},
|
||||
"MCU_NRF51": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF52840": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF52832": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF51_UNIFIED": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"NUVOTON": {
|
||||
"idle-thread-stack-size-debug-extra": 512
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MBED_RTOS_RTX1_TYPES_H
|
||||
#define MBED_RTOS_RTX1_TYPES_H
|
||||
|
||||
#include "rtx4/cmsis_os.h"
|
||||
|
||||
#endif
|
|
@ -22,9 +22,8 @@
|
|||
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "platform/mbed_power_mgmt.h"
|
||||
#include "platform/mbed_os_timer.h"
|
||||
#include "TimerEvent.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#include <new>
|
||||
|
@ -34,7 +33,8 @@
|
|||
extern "C" {
|
||||
#include "rtx_lib.h"
|
||||
|
||||
using namespace mbed;
|
||||
using mbed::internal::os_timer;
|
||||
using mbed::internal::OsTimer;
|
||||
|
||||
#ifdef MBED_TICKLESS
|
||||
|
||||
|
@ -46,26 +46,39 @@ extern "C" {
|
|||
#error Low power ticker required when MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER is false
|
||||
#endif
|
||||
|
||||
#include "rtos/TARGET_CORTEX/SysTimer.h"
|
||||
// Setup OS Tick timer to generate periodic RTOS Kernel Ticks
|
||||
int32_t OS_Tick_Setup(uint32_t freq, IRQHandler_t handler)
|
||||
{
|
||||
MBED_ASSERT(freq == 1000);
|
||||
|
||||
static rtos::internal::SysTimer *os_timer;
|
||||
static uint64_t os_timer_data[sizeof(rtos::internal::SysTimer) / 8];
|
||||
#ifdef TARGET_CORTEX_A
|
||||
IRQn_ID_t irq = OsTimer::get_irq_number();
|
||||
|
||||
IRQ_SetPriority(irq, 0xFF);
|
||||
IRQ_SetHandler(irq, handler);
|
||||
IRQ_EnableIRQ(irq);
|
||||
#else
|
||||
IRQn_Type irq = OsTimer::get_irq_number();
|
||||
|
||||
NVIC_SetPriority(irq, 0xFF);
|
||||
#ifdef NVIC_RAM_VECTOR_ADDRESS
|
||||
NVIC_SetVector(irq, (uint32_t)handler);
|
||||
#else
|
||||
MBED_ASSERT(handler == (IRQHandler_t)NVIC_GetVector(irq));
|
||||
#endif
|
||||
if (irq >= 0) {
|
||||
NVIC_EnableIRQ(irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Enable System Timer.
|
||||
void OS_Tick_Enable(void)
|
||||
{
|
||||
// Do not use SingletonPtr since this relies on the RTOS
|
||||
if (NULL == os_timer) {
|
||||
#if MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER
|
||||
os_timer = new (os_timer_data) rtos::internal::SysTimer(get_us_ticker_data());
|
||||
#else
|
||||
os_timer = new (os_timer_data) rtos::internal::SysTimer(get_lp_ticker_data());
|
||||
#endif
|
||||
os_timer->setup_irq();
|
||||
}
|
||||
|
||||
// set to fire interrupt on next tick
|
||||
os_timer->schedule_tick();
|
||||
mbed::internal::init_os_timer()->start_tick();
|
||||
}
|
||||
|
||||
// Disable System Timer.
|
||||
|
@ -77,66 +90,54 @@ extern "C" {
|
|||
// Acknowledge System Timer IRQ.
|
||||
void OS_Tick_AcknowledgeIRQ(void)
|
||||
{
|
||||
|
||||
os_timer->acknowledge_tick();
|
||||
}
|
||||
|
||||
// Get System Timer count.
|
||||
uint32_t OS_Tick_GetCount(void)
|
||||
{
|
||||
return os_timer->get_time() & 0xFFFFFFFF;
|
||||
return (uint32_t) os_timer->get_time_since_tick();
|
||||
}
|
||||
|
||||
// Get OS Tick IRQ number.
|
||||
int32_t OS_Tick_GetIRQn(void)
|
||||
{
|
||||
return -1;
|
||||
return os_timer->get_irq_number();
|
||||
}
|
||||
|
||||
// Get OS Tick overflow status.
|
||||
uint32_t OS_Tick_GetOverflow(void)
|
||||
{
|
||||
// No need to indicate overflow - we let OS_Tick_GetCount overflow above
|
||||
// OS_Tick_GetInterval.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get OS Tick timer clock frequency
|
||||
uint32_t OS_Tick_GetClock(void)
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
// Get OS Tick interval.
|
||||
uint32_t OS_Tick_GetInterval(void)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
static bool rtos_event_pending(void *)
|
||||
{
|
||||
return core_util_atomic_load_u8(&osRtxInfo.kernel.pendSV);
|
||||
}
|
||||
|
||||
static void default_idle_hook(void)
|
||||
{
|
||||
uint32_t ticks_to_sleep = osKernelSuspend();
|
||||
const bool block_deep_sleep = MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER ||
|
||||
(ticks_to_sleep <= MBED_CONF_TARGET_DEEP_SLEEP_LATENCY);
|
||||
|
||||
if (block_deep_sleep) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
} else {
|
||||
ticks_to_sleep -= MBED_CONF_TARGET_DEEP_SLEEP_LATENCY;
|
||||
}
|
||||
os_timer->suspend(ticks_to_sleep);
|
||||
|
||||
bool event_pending = false;
|
||||
while (!os_timer->suspend_time_passed() && !event_pending) {
|
||||
|
||||
core_util_critical_section_enter();
|
||||
if (osRtxInfo.kernel.pendSV) {
|
||||
event_pending = true;
|
||||
} else {
|
||||
sleep();
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
|
||||
// Ensure interrupts get a chance to fire
|
||||
__ISB();
|
||||
}
|
||||
|
||||
if (block_deep_sleep) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
|
||||
osKernelResume(os_timer->resume());
|
||||
// osKernelSuspend will call OS_Tick_Disable, cancelling the tick, which frees
|
||||
// up the os timer for the timed sleep
|
||||
uint64_t ticks_slept = mbed::internal::do_timed_sleep_relative(ticks_to_sleep, rtos_event_pending);
|
||||
MBED_ASSERT(ticks_slept < osWaitForever);
|
||||
osKernelResume((uint32_t) ticks_slept);
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,8 +159,8 @@ extern "C" {
|
|||
|
||||
void rtos_attach_idle_hook(void (*fptr)(void))
|
||||
{
|
||||
//Attach the specified idle hook, or the default idle hook in case of a NULL pointer
|
||||
if (fptr != NULL) {
|
||||
//Attach the specified idle hook, or the default idle hook in case of a null pointer
|
||||
if (fptr != nullptr) {
|
||||
idle_hook_fptr = fptr;
|
||||
} else {
|
||||
idle_hook_fptr = default_idle_hook;
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MBED_RTOS_STORAGE_H
|
||||
#define MBED_RTOS_STORAGE_H
|
||||
#ifndef MBED_RTX_STORAGE_H
|
||||
#define MBED_RTX_STORAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
|
@ -23,39 +23,123 @@
|
|||
#define __STDC_LIMIT_MACROS
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/rtos_idle.h"
|
||||
#include "platform/CriticalSectionLock.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#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"
|
||||
|
||||
static uint32_t thread_flags;
|
||||
|
||||
/* For the flags to be useful, need a way of setting them, but there's only the main
|
||||
* thread, and that has no Thread object, so Thread class is not provided. Implement
|
||||
* one CMSIS-RTOS function to provide access.
|
||||
*/
|
||||
extern "C"
|
||||
uint32_t osThreadFlagsSet(osThreadId_t /*thread_id*/, uint32_t flags)
|
||||
{
|
||||
return core_util_atomic_fetch_or_u32(&thread_flags, flags) | flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace rtos {
|
||||
|
||||
uint32_t ThisThread::flags_clear(uint32_t flags)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
flags = osThreadFlagsClear(flags);
|
||||
MBED_ASSERT(!(flags & osFlagsError));
|
||||
#else
|
||||
flags = core_util_atomic_fetch_and_u32(&thread_flags, ~flags);
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_get()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osThreadFlagsGet();
|
||||
#else
|
||||
return core_util_atomic_load_u32(&thread_flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !MBED_CONF_RTOS_PRESENT
|
||||
namespace internal {
|
||||
bool non_rtos_check_flags(void *handle)
|
||||
{
|
||||
flags_check_capture *check = static_cast<flags_check_capture *>(handle);
|
||||
uint32_t cur_flags = core_util_atomic_load_u32(check->flags);
|
||||
uint32_t set_flags;
|
||||
do {
|
||||
set_flags = cur_flags & check->flags_wanted;
|
||||
check->result = set_flags;
|
||||
if ((check->options & osFlagsWaitAll) ? set_flags == check->flags_wanted : set_flags != 0) {
|
||||
if (check->options & osFlagsNoClear) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} while (!core_util_atomic_cas_u32(check->flags, &cur_flags, cur_flags & ~set_flags));
|
||||
check->match = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t flags_wait_for(uint32_t flags, uint32_t millisec, bool clear, uint32_t options)
|
||||
{
|
||||
if (!clear) {
|
||||
options |= osFlagsNoClear;
|
||||
}
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
flags = osThreadFlagsWait(flags, options, millisec);
|
||||
if (flags & osFlagsError) {
|
||||
MBED_ASSERT((flags == osFlagsErrorTimeout && millisec != osWaitForever) ||
|
||||
(flags == osFlagsErrorResource && millisec == 0));
|
||||
flags = ThisThread::flags_get();
|
||||
}
|
||||
#else
|
||||
rtos::internal::flags_check_capture check;
|
||||
check.flags = &thread_flags;
|
||||
check.options = options;
|
||||
check.flags_wanted = flags;
|
||||
check.result = 0;
|
||||
mbed::internal::do_timed_sleep_relative_or_forever(millisec, rtos::internal::non_rtos_check_flags, &check);
|
||||
flags = check.result;
|
||||
#endif
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static uint32_t flags_wait(uint32_t flags, bool clear, uint32_t options)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return flags_wait_for(flags, osWaitForever, clear, options);
|
||||
#else
|
||||
/* Avoids pulling in timer if not used */
|
||||
if (!clear) {
|
||||
options |= osFlagsNoClear;
|
||||
}
|
||||
rtos::internal::flags_check_capture check;
|
||||
check.flags = &thread_flags;
|
||||
check.options = options;
|
||||
check.flags_wanted = flags;
|
||||
check.result = 0;
|
||||
mbed::internal::do_untimed_sleep(rtos::internal::non_rtos_check_flags, &check);
|
||||
flags = check.result;
|
||||
|
||||
return flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t flags_wait_until(uint32_t flags, uint64_t millisec, bool clear, uint32_t options)
|
||||
{
|
||||
uint64_t now = Kernel::get_ms_count();
|
||||
|
@ -74,7 +158,7 @@ static uint32_t flags_wait_until(uint32_t flags, uint64_t millisec, bool clear,
|
|||
|
||||
uint32_t ThisThread::flags_wait_all(uint32_t flags, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAll);
|
||||
return flags_wait(flags, clear, osFlagsWaitAll);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_all_for(uint32_t flags, uint32_t millisec, bool clear)
|
||||
|
@ -89,7 +173,7 @@ uint32_t ThisThread::flags_wait_all_until(uint32_t flags, uint64_t millisec, boo
|
|||
|
||||
uint32_t ThisThread::flags_wait_any(uint32_t flags, bool clear)
|
||||
{
|
||||
return flags_wait_for(flags, osWaitForever, clear, osFlagsWaitAny);
|
||||
return flags_wait(flags, clear, osFlagsWaitAny);
|
||||
}
|
||||
|
||||
uint32_t ThisThread::flags_wait_any_for(uint32_t flags, uint32_t millisec, bool clear)
|
||||
|
@ -104,12 +188,17 @@ uint32_t ThisThread::flags_wait_any_until(uint32_t flags, uint64_t millisec, boo
|
|||
|
||||
void ThisThread::sleep_for(uint32_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osStatus_t status = osDelay(millisec);
|
||||
MBED_ASSERT(status == osOK);
|
||||
#else
|
||||
thread_sleep_for(millisec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThisThread::sleep_until(uint64_t millisec)
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
// CMSIS-RTOS 2.1.0 had 64-bit time and osDelayUntil, but that's been revoked.
|
||||
// Limit ourselves to manual implementation assuming a >=32-bit osDelay.
|
||||
|
||||
|
@ -126,25 +215,42 @@ void ThisThread::sleep_until(uint64_t millisec)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
thread_sleep_until(millisec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThisThread::yield()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osThreadYield();
|
||||
#else
|
||||
asm("yield");
|
||||
#endif
|
||||
}
|
||||
|
||||
osThreadId_t ThisThread::get_id()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
return osThreadGetId();
|
||||
#else
|
||||
return (osThreadId_t) 1; // dummy non-0 value
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *get_name()
|
||||
{
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
osThreadId_t id = osThreadGetId();
|
||||
if (id == NULL) {
|
||||
return NULL;
|
||||
if (id == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return osThreadGetName(id);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,14 +23,7 @@
|
|||
#define THIS_THREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Mutex.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
|
@ -154,6 +147,7 @@ uint32_t flags_wait_any_until(uint32_t flags, uint64_t millisec, bool clear = tr
|
|||
/** 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 thread_sleep_for.
|
||||
*/
|
||||
void sleep_for(uint32_t millisec);
|
||||
|
||||
|
@ -163,6 +157,7 @@ void sleep_for(uint32_t 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 thread_sleep_until.
|
||||
*/
|
||||
void sleep_until(uint64_t millisec);
|
||||
|
||||
|
@ -174,13 +169,13 @@ void sleep_until(uint64_t millisec);
|
|||
void yield();
|
||||
|
||||
/** Get the thread id of the current running thread.
|
||||
@return thread ID for reference by other functions or NULL in case of error or in ISR context.
|
||||
@return thread ID for reference by other functions or nullptr in case of error or in ISR context.
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
osThreadId_t get_id();
|
||||
|
||||
/** Get the thread name of the current running thread.
|
||||
@return thread name pointer or NULL if thread has no name or in case of error.
|
||||
@return thread name pointer or nullptr if thread has no name or in case of error.
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
const char *get_name();
|
||||
|
@ -188,6 +183,19 @@ const char *get_name();
|
|||
};
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
namespace internal {
|
||||
struct flags_check_capture {
|
||||
uint32_t *flags;
|
||||
uint32_t options;
|
||||
uint32_t flags_wanted;
|
||||
uint32_t result;
|
||||
bool match;
|
||||
};
|
||||
|
||||
bool non_rtos_check_flags(void *handle);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "platform/mbed_assert.h"
|
||||
#include "platform/mbed_error.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
|
||||
#define ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
|
||||
MBED_STATIC_ASSERT(ALIGN_UP(0, 8) == 0, "ALIGN_UP macro error");
|
||||
MBED_STATIC_ASSERT(ALIGN_UP(1, 8) == 8, "ALIGN_UP macro error");
|
||||
|
@ -50,7 +52,7 @@ void Thread::constructor(uint32_t tz_module, osPriority priority,
|
|||
const uint32_t aligned_size = ALIGN_DOWN(stack_size - offset, 8);
|
||||
|
||||
_tid = 0;
|
||||
_dynamic_stack = (stack_mem == NULL);
|
||||
_dynamic_stack = (stack_mem == nullptr);
|
||||
_finished = false;
|
||||
memset(&_attr, 0, sizeof(_attr));
|
||||
_attr.priority = priority;
|
||||
|
@ -94,9 +96,9 @@ osStatus Thread::start(mbed::Callback<void()> task)
|
|||
return osErrorParameter;
|
||||
}
|
||||
|
||||
if (_attr.stack_mem == NULL) {
|
||||
if (_attr.stack_mem == nullptr) {
|
||||
_attr.stack_mem = new uint32_t[_attr.stack_size / sizeof(uint32_t)];
|
||||
MBED_ASSERT(_attr.stack_mem != NULL);
|
||||
MBED_ASSERT(_attr.stack_mem != nullptr);
|
||||
}
|
||||
|
||||
//Fill the stack with a magic word for maximum usage checking
|
||||
|
@ -109,10 +111,10 @@ osStatus Thread::start(mbed::Callback<void()> task)
|
|||
_attr.cb_mem = &_obj_mem;
|
||||
_task = task;
|
||||
_tid = osThreadNew(Thread::_thunk, this, &_attr);
|
||||
if (_tid == NULL) {
|
||||
if (_tid == nullptr) {
|
||||
if (_dynamic_stack) {
|
||||
delete[](uint32_t *)(_attr.stack_mem);
|
||||
_attr.stack_mem = (uint32_t *)NULL;
|
||||
delete[] _attr.stack_mem;
|
||||
_attr.stack_mem = nullptr;
|
||||
}
|
||||
_mutex.unlock();
|
||||
_join_sem.release();
|
||||
|
@ -128,12 +130,12 @@ osStatus Thread::terminate()
|
|||
osStatus_t ret = osOK;
|
||||
_mutex.lock();
|
||||
|
||||
// Set the Thread's tid to NULL and
|
||||
// Set the Thread's tid to nullptr and
|
||||
// release the semaphore before terminating
|
||||
// since this thread could be terminating itself
|
||||
osThreadId_t local_id = _tid;
|
||||
_join_sem.release();
|
||||
_tid = (osThreadId_t)NULL;
|
||||
_tid = nullptr;
|
||||
if (!_finished) {
|
||||
_finished = true;
|
||||
// if local_id == 0 Thread was not started in first place
|
||||
|
@ -154,7 +156,7 @@ osStatus Thread::join()
|
|||
// terminated or has been terminated. Once the mutex has
|
||||
// been locked it is ensured that the thread is deleted.
|
||||
_mutex.lock();
|
||||
MBED_ASSERT(NULL == _tid);
|
||||
MBED_ASSERT(nullptr == _tid);
|
||||
_mutex.unlock();
|
||||
|
||||
// Release sem so any other threads joining this thread wake up
|
||||
|
@ -202,7 +204,7 @@ Thread::State Thread::get_state() const
|
|||
|
||||
_mutex.lock();
|
||||
|
||||
if (_tid != NULL) {
|
||||
if (_tid != nullptr) {
|
||||
#if defined(MBED_OS_BACKEND_RTX5)
|
||||
state = _obj_mem.state;
|
||||
#else
|
||||
|
@ -267,7 +269,7 @@ uint32_t Thread::stack_size() const
|
|||
uint32_t size = 0;
|
||||
_mutex.lock();
|
||||
|
||||
if (_tid != NULL) {
|
||||
if (_tid != nullptr) {
|
||||
size = osThreadGetStackSize(_tid);
|
||||
}
|
||||
|
||||
|
@ -281,7 +283,7 @@ uint32_t Thread::free_stack() const
|
|||
_mutex.lock();
|
||||
|
||||
#if defined(MBED_OS_BACKEND_RTX5)
|
||||
if (_tid != NULL) {
|
||||
if (_tid != nullptr) {
|
||||
mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
|
||||
size = (uint32_t)thread->sp - (uint32_t)thread->stack_mem;
|
||||
}
|
||||
|
@ -297,7 +299,7 @@ uint32_t Thread::used_stack() const
|
|||
_mutex.lock();
|
||||
|
||||
#if defined(MBED_OS_BACKEND_RTX5)
|
||||
if (_tid != NULL) {
|
||||
if (_tid != nullptr) {
|
||||
mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
|
||||
size = ((uint32_t)thread->stack_mem + thread->stack_size) - thread->sp;
|
||||
}
|
||||
|
@ -312,7 +314,7 @@ uint32_t Thread::max_stack() const
|
|||
uint32_t size = 0;
|
||||
_mutex.lock();
|
||||
|
||||
if (_tid != NULL) {
|
||||
if (_tid != nullptr) {
|
||||
#if defined(MBED_OS_BACKEND_RTX5)
|
||||
mbed_rtos_storage_thread_t *thread = (mbed_rtos_storage_thread_t *)_tid;
|
||||
uint32_t high_mark = 0;
|
||||
|
@ -415,8 +417,8 @@ Thread::~Thread()
|
|||
// terminate is thread safe
|
||||
terminate();
|
||||
if (_dynamic_stack) {
|
||||
delete[](uint32_t *)(_attr.stack_mem);
|
||||
_attr.stack_mem = (uint32_t *)NULL;
|
||||
delete[] _attr.stack_mem;
|
||||
_attr.stack_mem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,10 +427,12 @@ void Thread::_thunk(void *thread_ptr)
|
|||
Thread *t = (Thread *)thread_ptr;
|
||||
t->_task();
|
||||
t->_mutex.lock();
|
||||
t->_tid = (osThreadId)NULL;
|
||||
t->_tid = nullptr;
|
||||
t->_finished = true;
|
||||
t->_join_sem.release();
|
||||
// rtos will release the mutex automatically
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,15 +23,17 @@
|
|||
#define THREAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos1_types.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
#include "rtos/mbed_rtos1_types.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "rtos/Semaphore.h"
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY) || defined(UNITTEST)
|
||||
|
||||
namespace rtos {
|
||||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
|
@ -87,8 +89,8 @@ public:
|
|||
/** Allocate a new thread without starting execution
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
|
||||
|
||||
@note Default value of tz_module will be MBED_TZ_DEFAULT_ACCESS
|
||||
@note You cannot call this function from ISR context.
|
||||
|
@ -96,7 +98,7 @@ public:
|
|||
|
||||
Thread(osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL, const char *name = NULL)
|
||||
unsigned char *stack_mem = nullptr, const char *name = nullptr)
|
||||
{
|
||||
constructor(priority, stack_size, stack_mem, name);
|
||||
}
|
||||
|
@ -108,15 +110,15 @@ public:
|
|||
threads not using secure calls at all. See "TrustZone RTOS Context Management" for more details.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
|
||||
|
||||
@note You cannot call this function from ISR context.
|
||||
*/
|
||||
|
||||
Thread(uint32_t tz_module, osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL, const char *name = NULL)
|
||||
unsigned char *stack_mem = nullptr, const char *name = nullptr)
|
||||
{
|
||||
constructor(tz_module, priority, stack_size, stack_mem, name);
|
||||
}
|
||||
|
@ -126,7 +128,7 @@ public:
|
|||
@param task function to be executed by this thread.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@deprecated
|
||||
Thread-spawning constructors hide errors. Replaced by thread.start(task).
|
||||
|
||||
|
@ -147,17 +149,17 @@ public:
|
|||
Thread(mbed::Callback<void()> task,
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL)
|
||||
unsigned char *stack_mem = nullptr)
|
||||
{
|
||||
constructor(task, priority, stack_size, stack_mem);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: nullptr).
|
||||
@param task argument to task.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@deprecated
|
||||
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
|
||||
|
||||
|
@ -179,18 +181,18 @@ public:
|
|||
Thread(T *argument, void (T::*task)(),
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL)
|
||||
unsigned char *stack_mem = nullptr)
|
||||
{
|
||||
constructor(mbed::callback(task, argument),
|
||||
priority, stack_size, stack_mem);
|
||||
}
|
||||
|
||||
/** Create a new thread, and start it executing the specified function.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: nullptr).
|
||||
@param task argument to task.
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@deprecated
|
||||
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
|
||||
|
||||
|
@ -212,7 +214,7 @@ public:
|
|||
Thread(T *argument, void (*task)(T *),
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL)
|
||||
unsigned char *stack_mem = nullptr)
|
||||
{
|
||||
constructor(mbed::callback(task, argument),
|
||||
priority, stack_size, stack_mem);
|
||||
|
@ -221,10 +223,10 @@ public:
|
|||
/** Create a new thread, and start it executing the specified function.
|
||||
Provided for backwards compatibility
|
||||
@param task function to be executed by this thread.
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||
@param argument pointer that is passed to the thread function as start argument. (default: nullptr).
|
||||
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
|
||||
@param stack_mem pointer to the stack area to be used by this thread (default: nullptr).
|
||||
@deprecated
|
||||
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
|
||||
|
||||
|
@ -242,10 +244,10 @@ public:
|
|||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"Thread-spawning constructors hide errors. "
|
||||
"Replaced by thread.start(callback(task, argument)).")
|
||||
Thread(void (*task)(void const *argument), void *argument = NULL,
|
||||
Thread(void (*task)(void const *argument), void *argument = nullptr,
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL)
|
||||
unsigned char *stack_mem = nullptr)
|
||||
{
|
||||
constructor(mbed::callback((void (*)(void *))task, argument),
|
||||
priority, stack_size, stack_mem);
|
||||
|
@ -387,7 +389,7 @@ public:
|
|||
uint32_t max_stack() const;
|
||||
|
||||
/** Get thread name
|
||||
@return thread name or NULL if the name was not set.
|
||||
@return thread name or nullptr if the name was not set.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
*/
|
||||
|
@ -473,7 +475,7 @@ public:
|
|||
static osStatus yield();
|
||||
|
||||
/** Get the thread id of the current running thread.
|
||||
@return thread ID for reference by other functions or NULL in case of error.
|
||||
@return thread ID for reference by other functions or nullptr in case of error.
|
||||
|
||||
@note You may call this function from ISR context.
|
||||
@deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::get_id.
|
||||
|
@ -517,18 +519,18 @@ private:
|
|||
// delegated constructors
|
||||
void constructor(osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL,
|
||||
const char *name = NULL);
|
||||
unsigned char *stack_mem = nullptr,
|
||||
const char *name = nullptr);
|
||||
void constructor(mbed::Callback<void()> task,
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL,
|
||||
const char *name = NULL);
|
||||
unsigned char *stack_mem = nullptr,
|
||||
const char *name = nullptr);
|
||||
void constructor(uint32_t tz_module,
|
||||
osPriority priority = osPriorityNormal,
|
||||
uint32_t stack_size = OS_STACK_SIZE,
|
||||
unsigned char *stack_mem = NULL,
|
||||
const char *name = NULL);
|
||||
unsigned char *stack_mem = nullptr,
|
||||
const char *name = nullptr);
|
||||
static void _thunk(void *thread_ptr);
|
||||
|
||||
mbed::Callback<void()> _task;
|
||||
|
@ -545,4 +547,4 @@ private:
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,57 +1,6 @@
|
|||
{
|
||||
"name": "rtos",
|
||||
"config": {
|
||||
"present": 1,
|
||||
"main-thread-stack-size": {
|
||||
"help": "The size of the main thread's stack",
|
||||
"value": 4096
|
||||
},
|
||||
"timer-thread-stack-size": {
|
||||
"help": "The size of the timer thread's stack",
|
||||
"value": 768
|
||||
},
|
||||
"idle-thread-stack-size": {
|
||||
"help": "The size of the idle thread's stack",
|
||||
"value": 512
|
||||
},
|
||||
"thread-stack-size": {
|
||||
"help": "The default stack size of new threads",
|
||||
"value": 4096
|
||||
},
|
||||
"idle-thread-stack-size-tickless-extra": {
|
||||
"help": "Additional size to add to the idle thread when a specific target or application implementation requires it or in case tickless is enabled and LPTICKER_DELAY_TICKS is used",
|
||||
"value": 256
|
||||
},
|
||||
"idle-thread-stack-size-debug-extra": {
|
||||
"help": "Additional size to add to the idle thread when code compilation optimisation is disabled",
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
"macros": ["_RTE_"],
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"target.boot-stack-size": "0x400"
|
||||
},
|
||||
"STM": {
|
||||
"idle-thread-stack-size-debug-extra": 128
|
||||
},
|
||||
"STM32L1": {
|
||||
"idle-thread-stack-size-debug-extra": 512
|
||||
},
|
||||
"MCU_NRF51": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF52840": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF52832": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"MCU_NRF51_UNIFIED": {
|
||||
"target.boot-stack-size": "0x800"
|
||||
},
|
||||
"NUVOTON": {
|
||||
"idle-thread-stack-size-debug-extra": 512
|
||||
}
|
||||
}
|
||||
"name": "rtos-api",
|
||||
"config": {
|
||||
"present": 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* 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_RTOS_RTX1_TYPES_H
|
||||
#define MBED_RTOS_RTX1_TYPES_H
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(UNITTEST)
|
||||
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#else
|
||||
|
||||
typedef int32_t osStatus;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
/* 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_RTOS_STORAGE_H
|
||||
#define MBED_RTOS_STORAGE_H
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(UNITTEST)
|
||||
|
||||
#include "mbed_rtx_storage.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
|
@ -0,0 +1,76 @@
|
|||
/* mbed Microcontroller Library
|
||||
* 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 RTOS_TYPES_H_
|
||||
#define RTOS_TYPES_H_
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY) || defined(UNITTEST)
|
||||
#include "cmsis_os2.h"
|
||||
#else
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Minimal definitions for bare metal form of RTOS */
|
||||
|
||||
// Timeout value.
|
||||
#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.
|
||||
|
||||
// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
|
||||
#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default).
|
||||
#define osFlagsWaitAll 0x00000001U ///< Wait for all flags.
|
||||
#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for.
|
||||
|
||||
// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx).
|
||||
#define osFlagsError 0x80000000U ///< Error indicator.
|
||||
#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1).
|
||||
#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2).
|
||||
#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3).
|
||||
#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4).
|
||||
#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6).
|
||||
|
||||
// Status code values returned by CMSIS-RTOS functions.
|
||||
typedef enum {
|
||||
osOK = 0, ///< Operation completed successfully.
|
||||
osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits.
|
||||
osErrorTimeout = -2, ///< Operation not completed within the timeout period.
|
||||
osErrorResource = -3, ///< Resource not available.
|
||||
osErrorParameter = -4, ///< Parameter error.
|
||||
osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
|
||||
osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
|
||||
osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
|
||||
} osStatus_t;
|
||||
|
||||
|
||||
// \details Thread ID identifies the thread.
|
||||
typedef void *osThreadId_t;
|
||||
|
||||
// Set the specified Thread Flags of a thread.
|
||||
// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
|
||||
// \param[in] flags specifies the flags of the thread that shall be set.
|
||||
// \return thread flags after setting or error code if highest bit set.
|
||||
uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* RTOS_TYPES_H_ */
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef RTOS_H
|
||||
#define RTOS_H
|
||||
|
||||
#include "mbed_rtos_storage.h"
|
||||
#include "rtos/mbed_rtos_storage.h"
|
||||
#include "rtos/Kernel.h"
|
||||
#include "rtos/Thread.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef RTOS_HANDLERS_H
|
||||
#define RTOS_HANDLERS_H
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "rtos/mbed_rtos_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "cellular/onboard_modem_api.h"
|
||||
#include "ublox_low_level_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if MODEM_ON_BOARD
|
||||
|
@ -29,7 +29,7 @@ static void press_power_button(int time_ms)
|
|||
gpio_t gpio;
|
||||
|
||||
gpio_init_out_ex(&gpio, MDMPWRON, 0);
|
||||
wait_ms(time_ms);
|
||||
thread_sleep_for(time_ms);
|
||||
gpio_write(&gpio, 1);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void onboard_modem_power_up()
|
|||
/* keep the power line low for 150 milisecond */
|
||||
press_power_button(150);
|
||||
/* give modem a little time to respond */
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
}
|
||||
|
||||
void onboard_modem_power_down()
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdbool.h>
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "gpio_api.h"
|
||||
#include "ublox_low_level_api.h"
|
||||
|
||||
|
@ -39,12 +40,10 @@ void ublox_mdm_init(void)
|
|||
// led should be off
|
||||
gpio_init_out_ex(&gpio, LED, 0);
|
||||
|
||||
// Can't use wait_ms() as RTOS isn't initialised yet
|
||||
//wait_ms(50); // when USB cable is inserted the interface chip issues
|
||||
// Can't use thread_sleep_for() as RTOS isn't initialised yet
|
||||
//thread_sleep_for(50); // when USB cable is inserted the interface chip issues
|
||||
// Here's the code from the non-RTOS version
|
||||
us_ticker_init();
|
||||
uint32_t start = us_ticker_read();
|
||||
while ((us_ticker_read() - start) < 50000);
|
||||
wait_us(50000);
|
||||
}
|
||||
|
||||
// For forwards compatibility
|
||||
|
@ -61,7 +60,7 @@ void ublox_mdm_powerOn(int usb)
|
|||
if (!modemOn) { // enable modem
|
||||
modemOn = true;
|
||||
gpio_init_out_ex(&gpio, MDMEN, 1); // LDOEN: 1=on
|
||||
wait_ms(1); // wait until supply switched off
|
||||
thread_sleep_for(1); // wait until supply switched off
|
||||
// now we can safely enable the level shifters
|
||||
gpio_init_out_ex(&gpio, MDMLVLOE, 0); // LVLEN: 0=enabled (uart/gpio)
|
||||
if (gpsOn) {
|
||||
|
@ -97,7 +96,7 @@ void ublox_gps_powerOn(void)
|
|||
gpsOn = true;
|
||||
// switch on power supply
|
||||
gpio_init_out_ex(&gpio, GPSEN, 1); // LDOEN: 1=on
|
||||
wait_ms(1); // wait until supply switched off
|
||||
thread_sleep_for(1); // wait until supply switched off
|
||||
if (modemOn) {
|
||||
gpio_init_out_ex(&gpio, MDMILVLOE, 1); // ILVLEN: 1=enabled (i2c)
|
||||
}
|
||||
|
|
|
@ -191,5 +191,10 @@ uint32_t OS_Tick_GetOverflow (void)
|
|||
return (IRQ_GetPending(OSTM_IRQn));
|
||||
}
|
||||
|
||||
// Get Cortex-A9 OS Timer interrupt number
|
||||
IRQn_ID_t mbed_get_a9_tick_irqn(){
|
||||
return OSTM_IRQn;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <stdio.h>
|
||||
#include "mbed_assert.h"
|
||||
#include "mbed_events.h"
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
#include "rtw_emac.h"
|
||||
#include "EMACMemoryManager.h"
|
||||
|
@ -123,7 +122,7 @@ bool RTW_EMAC::link_out(emac_mem_buf_t *buf)
|
|||
bool RTW_EMAC::power_up()
|
||||
{
|
||||
wifi_on(RTW_MODE_STA);
|
||||
wait_ms(1000);
|
||||
rtos::ThisThread::sleep_for(1000);
|
||||
wlan_emac_link_change(true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "cellular/onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if MODEM_ON_BOARD
|
||||
|
@ -29,7 +29,7 @@ static void press_power_button(int time_ms)
|
|||
|
||||
gpio_init_out_ex(&gpio, MDMPWRON, 1);
|
||||
gpio_write(&gpio, 0);
|
||||
wait_ms(time_ms);
|
||||
thread_sleep_for(time_ms);
|
||||
gpio_write(&gpio, 1);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ void onboard_modem_power_up()
|
|||
/* keep the power line low for 200 milisecond */
|
||||
press_power_button(200);
|
||||
/* give modem a little time to respond */
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
}
|
||||
|
||||
void onboard_modem_power_down()
|
||||
|
@ -59,7 +59,7 @@ void onboard_modem_power_down()
|
|||
* If 3G_ON_OFF pin is kept low for more than a second, a controlled disconnect and shutdown takes
|
||||
* place, Due to the network disconnect, shut-off can take up to 30 seconds. However, we wait for 10
|
||||
* seconds only */
|
||||
wait_ms(10 * 1000);
|
||||
thread_sleep_for(10 * 1000);
|
||||
}
|
||||
#endif //MODEM_ON_BOARD
|
||||
#endif //MBED_CONF_NSAPI_PRESENT
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "cellular/onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if MODEM_ON_BOARD
|
||||
|
@ -29,7 +29,7 @@ static void press_power_button(int time_ms)
|
|||
|
||||
gpio_init_out_ex(&gpio, MDMPWRON, 1);
|
||||
gpio_write(&gpio, 0);
|
||||
wait_ms(time_ms);
|
||||
thread_sleep_for(time_ms);
|
||||
gpio_write(&gpio, 1);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ void onboard_modem_power_up()
|
|||
/* keep the power line low for 200 milisecond */
|
||||
press_power_button(200);
|
||||
/* give modem a little time to respond */
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
}
|
||||
|
||||
void onboard_modem_power_down()
|
||||
|
@ -59,7 +59,7 @@ void onboard_modem_power_down()
|
|||
* If 3G_ON_OFF pin is kept low for more than a second, a controlled disconnect and shutdown takes
|
||||
* place, Due to the network disconnect, shut-off can take up to 30 seconds. However, we wait for 10
|
||||
* seconds only */
|
||||
wait_ms(10 * 1000);
|
||||
thread_sleep_for(10 * 1000);
|
||||
}
|
||||
#endif //MODEM_ON_BOARD
|
||||
#endif //MBED_CONF_NSAPI_PRESENT
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if MODEM_ON_BOARD
|
||||
|
@ -71,7 +72,7 @@ void onboard_modem_power_up()
|
|||
#endif
|
||||
|
||||
/* give modem a little time to respond */
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
}
|
||||
|
||||
void onboard_modem_power_down()
|
||||
|
|
|
@ -1081,7 +1081,7 @@ void OdinWiFiInterface::handle_user_scan(user_scan_s *user_scan)
|
|||
cbRTSL_Status status = cbSTATUS_ERROR;
|
||||
for(int i = 0; (i < 10) && (status != cbSTATUS_OK); i++) {
|
||||
if(i > 0) {
|
||||
wait_ms(500);
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
}
|
||||
|
||||
cbMAIN_driverLock();
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "cellular/onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#define WAIT_AFTER_POWR_CHANGED (1000) // [msec.]
|
||||
|
@ -32,7 +32,7 @@ static void press_power_button(int time_ms)
|
|||
gpio_t gpio;
|
||||
|
||||
gpio_init_out_ex(&gpio, PWRKEY, 1);
|
||||
wait_ms(time_ms);
|
||||
thread_sleep_for(time_ms);
|
||||
gpio_write(&gpio, 0);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void onboard_modem_init()
|
|||
// Main UART Interface
|
||||
gpio_init_out_ex(&gpio, MDMDTR, 0);
|
||||
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
}
|
||||
|
||||
void onboard_modem_deinit()
|
||||
|
@ -59,7 +59,7 @@ void onboard_modem_deinit()
|
|||
|
||||
// Power supply OFF
|
||||
gpio_init_out_ex(&gpio, M_POWR, 0);
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
}
|
||||
|
||||
void onboard_modem_power_up()
|
||||
|
@ -68,10 +68,10 @@ void onboard_modem_power_up()
|
|||
|
||||
// Power supply ON
|
||||
gpio_init_out_ex(&gpio, M_POWR, 1);
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
|
||||
// Turn on
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
press_power_button(200);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ void onboard_modem_power_down()
|
|||
|
||||
// Power supply OFF
|
||||
gpio_init_out_ex(&gpio, M_POWR, 0);
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
}
|
||||
#endif //MODEM_ON_BOARD
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "cellular/onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#define WAIT_AFTER_POWR_CHANGED (1000) // [msec.]
|
||||
|
@ -32,7 +32,7 @@ static void press_power_button(int time_ms)
|
|||
gpio_t gpio;
|
||||
|
||||
gpio_init_out_ex(&gpio, PWRKEY, 1);
|
||||
wait_ms(time_ms);
|
||||
thread_sleep_for(time_ms);
|
||||
gpio_write(&gpio, 0);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void onboard_modem_init()
|
|||
// Main UART Interface
|
||||
gpio_init_out_ex(&gpio, MDMDTR, 0);
|
||||
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
}
|
||||
|
||||
void onboard_modem_deinit()
|
||||
|
@ -64,10 +64,10 @@ void onboard_modem_power_up()
|
|||
|
||||
// Power supply ON
|
||||
gpio_init_out_ex(&gpio, M_POWR, 1);
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
|
||||
// Turn on
|
||||
wait_ms(100);
|
||||
thread_sleep_for(100);
|
||||
press_power_button(200);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ void onboard_modem_power_down()
|
|||
|
||||
// Power supply OFF
|
||||
gpio_init_out_ex(&gpio, M_POWR, 0);
|
||||
wait_ms(WAIT_AFTER_POWR_CHANGED);
|
||||
thread_sleep_for(WAIT_AFTER_POWR_CHANGED);
|
||||
}
|
||||
#endif //MODEM_ON_BOARD
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "onboard_modem_api.h"
|
||||
#include "gpio_api.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_thread.h"
|
||||
#include "PinNames.h"
|
||||
|
||||
#if MODEM_ON_BOARD
|
||||
|
@ -69,7 +69,7 @@ void onboard_modem_power_up()
|
|||
while(i < 3)
|
||||
{
|
||||
press_power_button(150000);
|
||||
wait_ms(250);
|
||||
thread_sleep_for(250);
|
||||
|
||||
if(gpio_read(&gpio))
|
||||
{
|
||||
|
|
|
@ -17,9 +17,8 @@
|
|||
|
||||
#include "stdint.h"
|
||||
#include "USBMouse.h"
|
||||
#include "PlatformMutex.h"
|
||||
#include "ThisThread.h"
|
||||
#include "usb_phy_api.h"
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
|
||||
USBMouse::USBMouse(bool connect_blocking, MOUSE_TYPE mouse_type, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
|
||||
|
@ -157,7 +156,7 @@ bool USBMouse::double_click()
|
|||
_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
wait(0.1);
|
||||
rtos::ThisThread::sleep_for(100);
|
||||
bool ret = click(MOUSE_LEFT);
|
||||
|
||||
_mutex.unlock();
|
||||
|
@ -172,7 +171,7 @@ bool USBMouse::click(uint8_t button)
|
|||
_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
wait(0.01);
|
||||
rtos::ThisThread::sleep_for(10);
|
||||
bool ret = update(0, 0, 0, 0);
|
||||
|
||||
_mutex.unlock();
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "stdint.h"
|
||||
#include "USBMouseKeyboard.h"
|
||||
#include "usb_phy_api.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "ThisThread.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned char usage;
|
||||
|
@ -709,7 +709,7 @@ bool USBMouseKeyboard::doubleClick()
|
|||
_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
wait(0.1);
|
||||
rtos::ThisThread::sleep_for(100);
|
||||
bool ret = click(MOUSE_LEFT);
|
||||
|
||||
_mutex.unlock();
|
||||
|
@ -724,7 +724,7 @@ bool USBMouseKeyboard::click(uint8_t button)
|
|||
_mutex.unlock();
|
||||
return false;
|
||||
}
|
||||
wait(0.01);
|
||||
rtos::ThisThread::sleep_for(10);
|
||||
bool ret = update(0, 0, 0, 0);
|
||||
|
||||
_mutex.unlock();
|
||||
|
|
Loading…
Reference in New Issue