mirror of https://github.com/ARMmbed/mbed-os.git
Fix and update tests to use Chronos APIs
parent
b17355f588
commit
5601a207cc
|
@ -28,22 +28,24 @@
|
|||
#else
|
||||
|
||||
using utest::v1::Case;
|
||||
using std::milli;
|
||||
using std::micro;
|
||||
using namespace std::chrono;
|
||||
|
||||
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
|
||||
#define TEST_STACK_SIZE 512
|
||||
#else
|
||||
#define TEST_STACK_SIZE 256
|
||||
#endif
|
||||
#define ONE_MILLI_SEC 1000
|
||||
|
||||
volatile uint32_t elapsed_time_ms = 0;
|
||||
static duration<uint32_t, milli> elapsed_time_ms;
|
||||
static const int test_timeout = 40;
|
||||
|
||||
|
||||
void update_tick_thread(Mutex *mutex)
|
||||
{
|
||||
while (true) {
|
||||
ThisThread::sleep_for(1);
|
||||
ThisThread::sleep_for(1ms);
|
||||
mutex->lock();
|
||||
++elapsed_time_ms;
|
||||
mutex->unlock();
|
||||
|
@ -69,7 +71,7 @@ void test(void)
|
|||
char _value[128] = { };
|
||||
int expected_key = 1;
|
||||
Mutex mutex;
|
||||
uint32_t elapsed_time;
|
||||
duration<uint32_t, micro> elapsed_time;
|
||||
|
||||
Thread tick_thread(osPriorityHigh, TEST_STACK_SIZE);
|
||||
tick_thread.start(callback(update_tick_thread, &mutex));
|
||||
|
@ -86,7 +88,7 @@ void test(void)
|
|||
elapsed_time = elapsed_time_ms;
|
||||
mutex.unlock();
|
||||
// send base_time
|
||||
greentea_send_kv(_key, elapsed_time * ONE_MILLI_SEC);
|
||||
greentea_send_kv(_key, elapsed_time.count());
|
||||
|
||||
// wait for 2nd signal from host
|
||||
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
|
||||
|
@ -95,7 +97,7 @@ void test(void)
|
|||
elapsed_time = elapsed_time_ms;
|
||||
mutex.unlock();
|
||||
// send final_time
|
||||
greentea_send_kv(_key, elapsed_time * ONE_MILLI_SEC);
|
||||
greentea_send_kv(_key, elapsed_time.count());
|
||||
|
||||
//get the results from host
|
||||
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
|
||||
|
|
|
@ -29,9 +29,10 @@
|
|||
#include "rtos.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define TEST_STACK_SIZE 512
|
||||
#define TEST_DELAY 10
|
||||
#define TEST_DELAY 10ms
|
||||
|
||||
static int change_counter = 0;
|
||||
static Mutex mutex;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "utest/utest.h"
|
||||
|
||||
using utest::v1::Case;
|
||||
using namespace std::chrono;
|
||||
|
||||
#if !DEVICE_USTICKER
|
||||
#error [NOT_SUPPORTED] UsTicker need to be enabled for this test.
|
||||
|
@ -44,14 +45,14 @@ using utest::v1::Case;
|
|||
#define PROHIBITED_FLAG 0x80000000 /* 10000000000000000000000000000000 */
|
||||
#define NO_FLAGS 0x0
|
||||
|
||||
void send_thread(EventFlags *ef, uint32_t flags, uint32_t wait_ms)
|
||||
void send_thread(EventFlags *ef, uint32_t flags, milliseconds wait)
|
||||
{
|
||||
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
const uint32_t flag = flags & (1 << i);
|
||||
if (flag) {
|
||||
ef->set(flag);
|
||||
if (wait_ms != 0) {
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
if (wait != 0ms) {
|
||||
ThisThread::sleep_for(wait);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,21 +61,19 @@ void send_thread(EventFlags *ef, uint32_t flags, uint32_t wait_ms)
|
|||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
Semaphore sync_sem(0, 1);
|
||||
|
||||
template<uint32_t flags, uint32_t wait_ms>
|
||||
void send_thread_sync(EventFlags *ef)
|
||||
void send_thread_sync(EventFlags *ef, uint32_t flags, milliseconds wait)
|
||||
{
|
||||
for (uint32_t i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
const uint32_t flag = flags & (1 << i);
|
||||
if (flag) {
|
||||
sync_sem.acquire();
|
||||
ef->set(flag);
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
ThisThread::sleep_for(wait);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t flags>
|
||||
void wait_thread_all(EventFlags *ef)
|
||||
void wait_thread_all(EventFlags *ef, uint32_t flags)
|
||||
{
|
||||
uint32_t ret, flags_after_clear;
|
||||
ret = ef->wait_all(flags);
|
||||
|
@ -218,9 +217,9 @@ void test_multi_thread_all(void)
|
|||
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 2); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 3); });
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 2ms); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 3ms); });
|
||||
|
||||
uint32_t ret = ef.wait_all(FLAG01 | FLAG02 | FLAG03);
|
||||
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, ret);
|
||||
|
@ -239,9 +238,9 @@ void test_multi_thread_any(void)
|
|||
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 1); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 1); });
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 1ms); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 1ms); });
|
||||
|
||||
for (int i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
uint32_t flag = 1 << i;
|
||||
|
@ -265,16 +264,16 @@ void test_multi_thread_any_timeout(void)
|
|||
EventFlags ef;
|
||||
uint32_t ret;
|
||||
Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread.start(callback(send_thread_sync < FLAG01 | FLAG02 | FLAG03, 1 >, &ef));
|
||||
thread.start([&] { send_thread_sync(&ef, FLAG01 | FLAG02 | FLAG03, 1ms); });
|
||||
|
||||
for (int i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
uint32_t flag = 1 << i;
|
||||
|
||||
ret = ef.wait_any(flag, 10);
|
||||
ret = ef.wait_any_for(flag, 10ms);
|
||||
TEST_ASSERT_EQUAL(osFlagsErrorTimeout, ret);
|
||||
|
||||
sync_sem.release();
|
||||
ret = ef.wait_any(flag, 10);
|
||||
ret = ef.wait_any_for(flag, 10ms);
|
||||
TEST_ASSERT_EQUAL(flag, ret);
|
||||
}
|
||||
ret = ef.get();
|
||||
|
@ -294,13 +293,13 @@ void test_multi_thread_any_no_clear(void)
|
|||
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 1); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 1); });
|
||||
thread1.start([&] { send_thread(&ef, FLAG01, 1ms); });
|
||||
thread2.start([&] { send_thread(&ef, FLAG02, 1ms); });
|
||||
thread3.start([&] { send_thread(&ef, FLAG03, 1ms); });
|
||||
|
||||
for (int i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
uint32_t flag = 1 << i;
|
||||
ret = ef.wait_any(flag, osWaitForever, false);
|
||||
ret = ef.wait_any_for(flag, Kernel::wait_for_u32_forever, false);
|
||||
TEST_ASSERT(flag | ret);
|
||||
ret = ef.clear(flag);
|
||||
TEST_ASSERT(ret < osFlagsError);
|
||||
|
@ -322,9 +321,9 @@ void test_multi_thread_all_many_wait(void)
|
|||
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
|
||||
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
|
||||
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
|
||||
thread1.start([&] { wait_thread_all(&ef, FLAG01); });
|
||||
thread2.start([&] { wait_thread_all(&ef, FLAG02); });
|
||||
thread3.start([&] { wait_thread_all(&ef, FLAG03); });
|
||||
|
||||
ef.set(FLAG01 | FLAG02 | FLAG03);
|
||||
thread1.join();
|
||||
|
@ -337,9 +336,9 @@ void test_multi_thread_all_many_wait(void)
|
|||
Thread thread1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread thread3(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
thread1.start(callback(wait_thread_all<FLAG01>, &ef));
|
||||
thread2.start(callback(wait_thread_all<FLAG02>, &ef));
|
||||
thread3.start(callback(wait_thread_all<FLAG03>, &ef));
|
||||
thread1.start([&] { wait_thread_all(&ef, FLAG01); });
|
||||
thread2.start([&] { wait_thread_all(&ef, FLAG02); });
|
||||
thread3.start([&] { wait_thread_all(&ef, FLAG03); });
|
||||
|
||||
ef.set(FLAG01);
|
||||
thread1.join();
|
||||
|
@ -362,10 +361,10 @@ void test_multi_eventflags_all(void)
|
|||
{
|
||||
EventFlags ef;
|
||||
Ticker t1, t2, t3;
|
||||
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
|
||||
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
|
||||
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
|
||||
uint32_t ret = ef.wait_all(FLAG01 | FLAG02 | FLAG03, 20, false);
|
||||
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
|
||||
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
|
||||
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
|
||||
uint32_t ret = ef.wait_all_for(FLAG01 | FLAG02 | FLAG03, 20ms, false);
|
||||
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, ret);
|
||||
}
|
||||
|
||||
|
@ -380,9 +379,9 @@ void test_multi_eventflags_any(void)
|
|||
EventFlags ef;
|
||||
uint32_t ret;
|
||||
Ticker t1, t2, t3;
|
||||
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
|
||||
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
|
||||
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
|
||||
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
|
||||
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
|
||||
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
|
||||
|
||||
for (int i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
uint32_t flag = 1 << i;
|
||||
|
@ -404,9 +403,9 @@ void test_multi_eventflags_any_no_clear(void)
|
|||
EventFlags ef;
|
||||
uint32_t ret;
|
||||
Ticker t1, t2, t3;
|
||||
t1.attach_us([&] { send_thread(&ef, FLAG01, 0); }, 3000);
|
||||
t2.attach_us([&] { send_thread(&ef, FLAG02, 0); }, 4000);
|
||||
t3.attach_us([&] { send_thread(&ef, FLAG03, 0); }, 5000);
|
||||
t1.attach([&] { send_thread(&ef, FLAG01, 0ms); }, 3ms);
|
||||
t2.attach([&] { send_thread(&ef, FLAG02, 0ms); }, 4ms);
|
||||
t3.attach([&] { send_thread(&ef, FLAG03, 0ms); }, 5ms);
|
||||
|
||||
for (int i = 0; i <= MAX_FLAG_POS; i++) {
|
||||
uint32_t flag = 1 << i;
|
||||
|
|
|
@ -21,18 +21,17 @@
|
|||
#include "rtos/Kernel.h"
|
||||
#include "mbed.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using utest::v1::Case;
|
||||
|
||||
#define TEST_REPEAT_COUNT 1000
|
||||
#define NUM_WAIT_TICKS 1000
|
||||
#define NUM_WAIT_TICKS rtos::Kernel::Clock::duration(1s)
|
||||
|
||||
// all in [us]
|
||||
#define ONE_SECOND 1000000
|
||||
#define SMALL_DELTA 1500 // 0.15%
|
||||
#define BIG_DELTA 15000 // 1.5%
|
||||
#define ONE_SECOND Timer::duration(1s)
|
||||
#define SMALL_DELTA Timer::duration(1500us) // 0.15%
|
||||
#define BIG_DELTA Timer::duration(15000us) // 1.5%
|
||||
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
/** Test if kernel ticker frequency is 1kHz
|
||||
|
||||
Given a RTOS kernel ticker
|
||||
|
@ -41,25 +40,27 @@ using utest::v1::Case;
|
|||
*/
|
||||
void test_frequency()
|
||||
{
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
uint32_t freq = osKernelGetTickFreq();
|
||||
TEST_ASSERT_EQUAL_UINT32_MESSAGE(1000, freq, "Expected SysTick frequency is 1kHz");
|
||||
}
|
||||
#endif
|
||||
TEST_ASSERT_TRUE_MESSAGE((std::ratio_equal<rtos::Kernel::Clock::period, std::milli>::value), "Expected Kernel::Clock frequency is 1kHz");
|
||||
}
|
||||
|
||||
/** Test if kernel ticker increments by one
|
||||
|
||||
Given a RTOS kernel ticker
|
||||
When perform subsequent calls of @a rtos::Kernel::get_ms_count
|
||||
When perform subsequent calls of @a rtos::Kernel::Clock::now
|
||||
Then subsequent reads should not differ by more than one
|
||||
*/
|
||||
void test_increment(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < TEST_REPEAT_COUNT; i++) {
|
||||
const uint64_t start = rtos::Kernel::get_ms_count();
|
||||
auto start = rtos::Kernel::Clock::now();
|
||||
while (true) {
|
||||
uint64_t diff = rtos::Kernel::get_ms_count() - start;
|
||||
if (diff != 0) {
|
||||
TEST_ASSERT_EQUAL_UINT64(1, diff);
|
||||
rtos::Kernel::Clock::duration diff = rtos::Kernel::Clock::now() - start;
|
||||
if (diff.count() != 0) {
|
||||
TEST_ASSERT_EQUAL_INT64(1, diff.count());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -69,43 +70,41 @@ void test_increment(void)
|
|||
/** Test if kernel ticker interval is 1ms
|
||||
|
||||
Given a RTOS kernel ticker
|
||||
When perform subsequent calls of @a rtos::Kernel::get_ms_count
|
||||
When perform subsequent calls of @a rtos::Kernel::Clock::now
|
||||
Then the ticker interval should be 1ms
|
||||
*/
|
||||
void test_interval()
|
||||
{
|
||||
uint64_t start, stop;
|
||||
Kernel::Clock::time_point start, stop;
|
||||
Timer timer;
|
||||
|
||||
start = rtos::Kernel::get_ms_count();
|
||||
start = rtos::Kernel::Clock::now();
|
||||
// wait for tick
|
||||
do {
|
||||
stop = rtos::Kernel::get_ms_count();
|
||||
} while ((stop - start) == 0);
|
||||
stop = rtos::Kernel::Clock::now();
|
||||
} while (stop == start);
|
||||
timer.start();
|
||||
start = stop;
|
||||
|
||||
// wait for NUM_WAIT_TICKS ticks
|
||||
do {
|
||||
stop = rtos::Kernel::get_ms_count();
|
||||
stop = rtos::Kernel::Clock::now();
|
||||
} while ((stop - start) != NUM_WAIT_TICKS);
|
||||
timer.stop();
|
||||
TEST_ASSERT_EQUAL_UINT64(NUM_WAIT_TICKS, (stop - start));
|
||||
TEST_ASSERT_EQUAL_INT64(NUM_WAIT_TICKS.count(), (stop - start).count());
|
||||
|
||||
#if defined(NO_SYSTICK) || defined(MBED_TICKLESS)
|
||||
// On targets with NO_SYSTICK/MBED_TICKLESS enabled, systick is emulated by lp_ticker what makes it less accurate
|
||||
// for more details https://os.mbed.com/docs/latest/reference/tickless.html
|
||||
TEST_ASSERT_UINT64_WITHIN(BIG_DELTA, ONE_SECOND, timer.read_high_resolution_us());
|
||||
TEST_ASSERT_INT64_WITHIN(BIG_DELTA.count(), ONE_SECOND.count(), timer.read_duration().count());
|
||||
#else
|
||||
TEST_ASSERT_UINT64_WITHIN(SMALL_DELTA, ONE_SECOND, timer.read_high_resolution_us());
|
||||
TEST_ASSERT_INT64_WITHIN(SMALL_DELTA.count(), ONE_SECOND.count(), timer.read_duration().count());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test cases
|
||||
Case cases[] = {
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
Case("Test kernel ticker frequency", test_frequency),
|
||||
#endif
|
||||
Case("Test if kernel ticker increments by one", test_increment),
|
||||
Case("Test if kernel ticker interval is 1ms", test_interval)
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "rtos.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
using namespace std::chrono;
|
||||
|
||||
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
|
||||
#define TEST_STACK_SIZE 768
|
||||
|
@ -36,8 +37,8 @@ using namespace utest::v1;
|
|||
#define TEST_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
#define TEST_LONG_DELAY 20
|
||||
#define TEST_DELAY 10
|
||||
#define TEST_LONG_DELAY 20ms
|
||||
#define TEST_DELAY 10ms
|
||||
#define SIGNALS_TO_EMIT 100
|
||||
|
||||
Mutex stdio_mutex;
|
||||
|
@ -89,9 +90,9 @@ void test_thread(int const *thread_delay)
|
|||
*/
|
||||
void test_multiple_threads(void)
|
||||
{
|
||||
const int t1_delay = TEST_DELAY * 1;
|
||||
const int t2_delay = TEST_DELAY * 2;
|
||||
const int t3_delay = TEST_DELAY * 3;
|
||||
const Kernel::Clock::duration t1_delay = TEST_DELAY * 1;
|
||||
const Kernel::Clock::duration t2_delay = TEST_DELAY * 2;
|
||||
const Kernel::Clock::duration t3_delay = TEST_DELAY * 3;
|
||||
|
||||
Thread t2(osPriorityNormal, TEST_STACK_SIZE);
|
||||
Thread t3(osPriorityNormal, TEST_STACK_SIZE);
|
||||
|
|
|
@ -29,27 +29,32 @@
|
|||
#include "rtos.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
using namespace std::chrono;
|
||||
|
||||
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
|
||||
do { \
|
||||
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
|
||||
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
|
||||
} while (0)
|
||||
|
||||
#define THREAD_STACK_SIZE 512
|
||||
#define TEST_UINT_MSG 0xDEADBEEF
|
||||
#define TEST_UINT_MSG2 0xE1EE7
|
||||
#define TEST_TIMEOUT 50
|
||||
#define TEST_TIMEOUT 50ms
|
||||
|
||||
template <uint32_t ms>
|
||||
void thread_put_uint_msg(Queue<uint32_t, 1> *q)
|
||||
{
|
||||
ThisThread::sleep_for(ms);
|
||||
ThisThread::sleep_for(TEST_TIMEOUT);
|
||||
osStatus stat = q->put((uint32_t *) TEST_UINT_MSG);
|
||||
TEST_ASSERT_EQUAL(osOK, stat);
|
||||
}
|
||||
|
||||
template <uint32_t ms, uint32_t val>
|
||||
void thread_get_uint_msg(Queue<uint32_t, 1> *q)
|
||||
{
|
||||
ThisThread::sleep_for(ms);
|
||||
ThisThread::sleep_for(TEST_TIMEOUT);
|
||||
osEvent evt = q->get();
|
||||
TEST_ASSERT_EQUAL(osEventMessage, evt.status);
|
||||
TEST_ASSERT_EQUAL(val, evt.value.v);
|
||||
TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
|
||||
}
|
||||
|
||||
/** Test pass uint msg
|
||||
|
@ -127,7 +132,7 @@ void test_get_empty_no_timeout()
|
|||
{
|
||||
Queue<uint32_t, 1> q;
|
||||
|
||||
osEvent evt = q.get(0);
|
||||
osEvent evt = q.get(0ms);
|
||||
TEST_ASSERT_EQUAL(osOK, evt.status);
|
||||
}
|
||||
|
||||
|
@ -143,9 +148,9 @@ void test_get_empty_timeout()
|
|||
Timer timer;
|
||||
timer.start();
|
||||
|
||||
osEvent evt = q.get(50);
|
||||
osEvent evt = q.get(50ms);
|
||||
TEST_ASSERT_EQUAL(osEventTimeout, evt.status);
|
||||
TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(5ms, 50ms, timer.elapsed_time());
|
||||
}
|
||||
|
||||
/** Test get empty wait forever
|
||||
|
@ -161,7 +166,7 @@ void test_get_empty_wait_forever()
|
|||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Queue<uint32_t, 1> q;
|
||||
|
||||
t.start(callback(thread_put_uint_msg<TEST_TIMEOUT>, &q));
|
||||
t.start(callback(thread_put_uint_msg, &q));
|
||||
|
||||
Timer timer;
|
||||
timer.start();
|
||||
|
@ -169,7 +174,7 @@ void test_get_empty_wait_forever()
|
|||
osEvent evt = q.get();
|
||||
TEST_ASSERT_EQUAL(osEventMessage, evt.status);
|
||||
TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v);
|
||||
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
|
||||
}
|
||||
|
||||
/** Test put full no timeout
|
||||
|
@ -207,13 +212,13 @@ void test_put_full_timeout()
|
|||
|
||||
stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT);
|
||||
TEST_ASSERT_EQUAL(osErrorTimeout, stat);
|
||||
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
|
||||
}
|
||||
|
||||
/** Test put full wait forever
|
||||
*
|
||||
* Given two threads A & B and a queue with one slot for uint32_t data
|
||||
* When thread A puts a message to the queue and tries to put second one with @a osWaitForever timeout
|
||||
* When thread A puts a message to the queue and tries to put second one with @a Kernel::wait_for_u32_forever timeout
|
||||
* Then thread waits for a slot to become empty in the queue
|
||||
* When thread B takes one message out of the queue
|
||||
* Then thread A successfully inserts message into the queue
|
||||
|
@ -223,16 +228,16 @@ void test_put_full_waitforever()
|
|||
Thread t(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Queue<uint32_t, 1> q;
|
||||
|
||||
t.start(callback(thread_get_uint_msg<TEST_TIMEOUT, TEST_UINT_MSG>, &q));
|
||||
t.start(callback(thread_get_uint_msg, &q));
|
||||
|
||||
osStatus stat = q.put((uint32_t *) TEST_UINT_MSG);
|
||||
TEST_ASSERT_EQUAL(osOK, stat);
|
||||
|
||||
Timer timer;
|
||||
timer.start();
|
||||
stat = q.put((uint32_t *) TEST_UINT_MSG, osWaitForever);
|
||||
stat = q.put((uint32_t *) TEST_UINT_MSG, Kernel::wait_for_u32_forever);
|
||||
TEST_ASSERT_EQUAL(osOK, stat);
|
||||
TEST_ASSERT_UINT32_WITHIN(TEST_TIMEOUT * 100, TEST_TIMEOUT * 1000, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time());
|
||||
|
||||
t.join();
|
||||
}
|
||||
|
|
|
@ -25,17 +25,24 @@
|
|||
#include "rtos.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
using namespace std::chrono;
|
||||
|
||||
struct test_data {
|
||||
Semaphore *sem;
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
#define TEST_ASSERT_DURATION_WITHIN(delta, expected, actual) \
|
||||
do { \
|
||||
using ct = std::common_type_t<decltype(delta), decltype(expected), decltype(actual)>; \
|
||||
TEST_ASSERT_INT_WITHIN(ct(delta).count(), ct(expected).count(), ct(actual).count()); \
|
||||
} while (0)
|
||||
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
#define THREAD_DELAY 30
|
||||
#define THREAD_DELAY 30ms
|
||||
#define SEMAPHORE_SLOTS 2
|
||||
#define SEM_CHANGES 100
|
||||
#define SHORT_WAIT 5
|
||||
#define SHORT_WAIT 5ms
|
||||
|
||||
#define THREAD_STACK_SIZE 320 /* larger stack cause out of heap memory on some 16kB RAM boards in multi thread test*/
|
||||
|
||||
|
@ -45,9 +52,9 @@ volatile int change_counter = 0;
|
|||
volatile int sem_counter = 0;
|
||||
volatile bool sem_defect = false;
|
||||
|
||||
void test_thread(int const *delay)
|
||||
void test_thread(rtos::Kernel::Clock::duration const *delay)
|
||||
{
|
||||
const int thread_delay = *delay;
|
||||
const auto thread_delay = *delay;
|
||||
while (true) {
|
||||
two_slots.acquire();
|
||||
sem_counter++;
|
||||
|
@ -70,9 +77,9 @@ void test_thread(int const *delay)
|
|||
*/
|
||||
void test_multi()
|
||||
{
|
||||
const int t1_delay = THREAD_DELAY * 1;
|
||||
const int t2_delay = THREAD_DELAY * 2;
|
||||
const int t3_delay = THREAD_DELAY * 3;
|
||||
const rtos::Kernel::Clock::duration t1_delay = THREAD_DELAY * 1;
|
||||
const rtos::Kernel::Clock::duration t2_delay = THREAD_DELAY * 2;
|
||||
const rtos::Kernel::Clock::duration t3_delay = THREAD_DELAY * 3;
|
||||
|
||||
Thread t1(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
Thread t2(osPriorityNormal, THREAD_STACK_SIZE);
|
||||
|
@ -137,7 +144,7 @@ void test_single_thread()
|
|||
|
||||
void timeout_thread(Semaphore *sem)
|
||||
{
|
||||
bool acquired = sem->try_acquire_for(30);
|
||||
bool acquired = sem->try_acquire_for(30ms);
|
||||
TEST_ASSERT_FALSE(acquired);
|
||||
}
|
||||
|
||||
|
@ -162,7 +169,7 @@ void test_timeout()
|
|||
TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
|
||||
|
||||
t.join();
|
||||
TEST_ASSERT_UINT32_WITHIN(5000, 30000, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(5ms, 30ms, timer.elapsed_time());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -190,7 +197,7 @@ void test_semaphore_acquire()
|
|||
data.sem = &sem;
|
||||
data.data = 0;
|
||||
Ticker t1;
|
||||
t1.attach_us(callback(test_ticker_release, &data), 3000);
|
||||
t1.attach(callback(test_ticker_release, &data), 3ms);
|
||||
sem.acquire();
|
||||
t1.detach();
|
||||
|
||||
|
@ -213,8 +220,8 @@ void test_semaphore_try_acquire()
|
|||
{
|
||||
Semaphore sem(0);
|
||||
Ticker t1;
|
||||
t1.attach_us(callback(test_ticker_try_acquire, &sem), 3000);
|
||||
ThisThread::sleep_for(4);
|
||||
t1.attach(callback(test_ticker_try_acquire, &sem), 3ms);
|
||||
ThisThread::sleep_for(4ms);
|
||||
t1.detach();
|
||||
}
|
||||
|
||||
|
@ -229,7 +236,7 @@ void test_semaphore_try_timeout()
|
|||
{
|
||||
Semaphore sem(0);
|
||||
bool res;
|
||||
res = sem.try_acquire_for(3);
|
||||
res = sem.try_acquire_for(3ms);
|
||||
TEST_ASSERT_FALSE(res);
|
||||
}
|
||||
|
||||
|
@ -254,8 +261,8 @@ void test_semaphore_try_acquire_timeout()
|
|||
Semaphore sem(0);
|
||||
bool res;
|
||||
Ticker t1;
|
||||
t1.attach_us(callback(test_ticker_semaphore_release, &sem), 3000);
|
||||
res = sem.try_acquire_for(10);
|
||||
t1.attach(callback(test_ticker_semaphore_release, &sem), 3ms);
|
||||
res = sem.try_acquire_for(10ms);
|
||||
t1.detach();
|
||||
TEST_ASSERT_TRUE(res);
|
||||
}
|
||||
|
@ -283,7 +290,7 @@ void test_no_timeout()
|
|||
bool acquired = sem.try_acquire();
|
||||
TEST_ASSERT_EQUAL(T > 0, acquired);
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(5000, 0, timer.read_us());
|
||||
TEST_ASSERT_DURATION_WITHIN(5ms, 0ms, timer.elapsed_time());
|
||||
}
|
||||
|
||||
/** Test multiple tokens wait
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016, 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 MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD
|
||||
#define MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD
|
||||
|
||||
#include <rtos.h>
|
||||
|
||||
/**
|
||||
* RAII mutex locker.
|
||||
* The mutex pass in the constructor will be locked for the lifetime of
|
||||
* the LockGuard instance.
|
||||
*/
|
||||
class LockGuard {
|
||||
public:
|
||||
/**
|
||||
* Construct a LockGuard instance and ackire ownership of mutex in input.
|
||||
* @param mutex The mutex to ackire ownership of.
|
||||
*/
|
||||
LockGuard(rtos::Mutex &mutex) : _mutex(mutex)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destruct the lock and release the inner mutex.
|
||||
*/
|
||||
~LockGuard()
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
LockGuard(const LockGuard &);
|
||||
LockGuard &operator=(const LockGuard &);
|
||||
rtos::Mutex &_mutex;
|
||||
};
|
||||
#endif /* MBEDMICRO_RTOS_MBED_THREADS_LOCK_GUARD */
|
|
@ -19,7 +19,9 @@
|
|||
#define MBEDMICRO_RTOS_MBED_THREADS_SYNCHRONIZED_INTEGRAL
|
||||
|
||||
#include <rtos.h>
|
||||
#include "LockGuard.h"
|
||||
#include <mstd_mutex>
|
||||
|
||||
using mstd::lock_guard;
|
||||
|
||||
/**
|
||||
* Thread safe wrapper for integral types.
|
||||
|
@ -33,35 +35,35 @@ public:
|
|||
// preincrement operator
|
||||
T operator++()
|
||||
{
|
||||
LockGuard lock(_mutex);
|
||||
lock_guard lock(_mutex);
|
||||
return ++_value;
|
||||
}
|
||||
|
||||
// predecrement operator
|
||||
T operator--()
|
||||
{
|
||||
LockGuard lock(_mutex);
|
||||
lock_guard lock(_mutex);
|
||||
return --_value;
|
||||
}
|
||||
|
||||
// post increment operator
|
||||
T operator++(int)
|
||||
{
|
||||
LockGuard lock(_mutex);
|
||||
lock_guard lock(_mutex);
|
||||
return _value++;
|
||||
}
|
||||
|
||||
// post decrement operator
|
||||
T operator--(int)
|
||||
{
|
||||
LockGuard lock(_mutex);
|
||||
lock_guard lock(_mutex);
|
||||
return _value--;
|
||||
}
|
||||
|
||||
// conversion operator, used also for <,>,<=,>=,== and !=
|
||||
operator T() const
|
||||
{
|
||||
LockGuard lock(_mutex);
|
||||
lock_guard lock(_mutex);
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "utest.h"
|
||||
#include "rtos.h"
|
||||
#include "SynchronizedIntegral.h"
|
||||
#include "LockGuard.h"
|
||||
#include <mstd_mutex>
|
||||
|
||||
#define THREAD_STACK_SIZE 512
|
||||
#if defined(__CORTEX_A9) || defined(__CORTEX_M23) || defined(__CORTEX_M33) || defined(TARGET_ARM_FM) || defined(TARGET_CY8CKIT_062_WIFI_BT_PSA)
|
||||
|
@ -41,6 +41,7 @@
|
|||
|
||||
|
||||
using namespace utest::v1;
|
||||
using mstd::lock_guard;
|
||||
|
||||
// The counter type used accross all the tests
|
||||
// It is internall ysynchronized so read
|
||||
|
@ -92,7 +93,7 @@ void increment_with_murder(counter_t *counter)
|
|||
{
|
||||
// take ownership of the counter mutex so it prevent the child to
|
||||
// modify counter.
|
||||
LockGuard lock(counter->internal_mutex());
|
||||
lock_guard lock(counter->internal_mutex());
|
||||
Thread *child = new (std::nothrow) Thread(osPriorityNormal, CHILD_THREAD_STACK_SIZE);
|
||||
char *dummy = new (std::nothrow) char[CHILD_THREAD_STACK_SIZE];
|
||||
delete[] dummy;
|
||||
|
@ -293,7 +294,7 @@ void flags_wait()
|
|||
|
||||
void flags_wait_tout()
|
||||
{
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x2, 50);
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x2, 50ms);
|
||||
TEST_ASSERT_EQUAL(0x1, flags);
|
||||
}
|
||||
|
||||
|
@ -311,7 +312,7 @@ void flags_wait_multibit_any()
|
|||
|
||||
void flags_wait_multibit_tout()
|
||||
{
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1 | 0x2, 50);
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1 | 0x2, 50ms);
|
||||
TEST_ASSERT_NOT_EQUAL(0x3, flags);
|
||||
}
|
||||
|
||||
|
@ -375,7 +376,7 @@ void flags_clear()
|
|||
TEST_ASSERT_EQUAL(0x1, sig);
|
||||
|
||||
/* Flags cleared we should get timeout */
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1, 0);
|
||||
uint32_t flags = ThisThread::flags_wait_all_for(0x1, 0s);
|
||||
TEST_ASSERT_EQUAL(0, flags);
|
||||
}
|
||||
|
||||
|
@ -473,7 +474,7 @@ void test_thread_wait()
|
|||
Timer timer;
|
||||
timer.start();
|
||||
|
||||
ThisThread::sleep_for(150);
|
||||
ThisThread::sleep_for(150ms);
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(50000, 150000, timer.read_us());
|
||||
}
|
||||
|
@ -527,7 +528,7 @@ void test_deleted()
|
|||
|
||||
void test_delay_thread()
|
||||
{
|
||||
ThisThread::sleep_for(50);
|
||||
ThisThread::sleep_for(50ms);
|
||||
}
|
||||
|
||||
/** Testing thread states: wait delay
|
||||
|
|
Loading…
Reference in New Issue