diff --git a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp index 93719f4309..1c22f61ba5 100644 --- a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp @@ -83,9 +83,8 @@ void receive_thread(Mail *m, uint8_t thread_id, milliseconds ThisThread::sleep_for(wait); for (uint32_t i = 0; i < queue_size; i++) { - osEvent evt = m->get(); - if (evt.status == osEventMail) { - mail_t *mail = (mail_t *)evt.value.p; + mail_t *mail = m->try_get_for(Kernel::wait_for_u32_forever); + if (mail) { const uint8_t id = mail->thread_id; // verify thread id @@ -121,9 +120,8 @@ void test_single_thread_order(void) for (uint32_t i = 0; i < QUEUE_SIZE; i++) { // mail receive (main thread) - osEvent evt = mail_box.get(); - if (evt.status == osEventMail) { - mail_t *mail = (mail_t *)evt.value.p; + mail_t *mail = mail_box.try_get_for(Kernel::wait_for_u32_forever); + if (mail) { const uint8_t id = mail->thread_id; // verify thread id @@ -163,9 +161,8 @@ void test_multi_thread_order(void) for (uint32_t i = 0; i < QUEUE_SIZE; i++) { // mail receive (main thread) - osEvent evt = mail_box.get(); - if (evt.status == osEventMail) { - mail_t *mail = (mail_t *)evt.value.p; + mail_t *mail = mail_box.try_get_for(Kernel::wait_for_u32_forever); + if (mail) { const uint8_t id = mail->thread_id; // verify thread id @@ -279,8 +276,8 @@ void test_free_null() /** Test get from empty mailbox with timeout set Given an empty mailbox - When @a get is called on the mailbox with timeout of 50 - Then mailbox returns status of osOK, but no data after specified amount of time + When @a try_get_for is called on the mailbox with timeout of 50ms + Then mailbox returns no data */ void test_get_empty_timeout() { @@ -288,23 +285,23 @@ void test_get_empty_timeout() Timer timer; timer.start(); - osEvent evt = mail_box.get(50ms); + uint32_t *mail = mail_box.try_get_for(50ms); TEST_ASSERT_DURATION_WITHIN(5ms, 50ms, timer.elapsed_time()); - TEST_ASSERT_EQUAL(osEventTimeout, evt.status); + TEST_ASSERT_NULL(mail); } /** Test get from empty mailbox with 0 timeout Given an empty mailbox - When @a get is called on the mailbox with timeout of 0 - Then mailbox returns status of osOK, but no data + When @a try_get is called on the mailbox + Then mailbox returns no data */ void test_get_empty_no_timeout() { Mail mail_box; - osEvent evt = mail_box.get(0ms); - TEST_ASSERT_EQUAL(osOK, evt.status); + uint32_t *mail = mail_box.try_get(); + TEST_ASSERT_NULL(mail); } /** Test mail order @@ -317,7 +314,6 @@ void test_get_empty_no_timeout() void test_order(void) { osStatus status; - osEvent evt; Mail mail_box; const int32_t TEST_VAL1 = 123; const int32_t TEST_VAL2 = 456; @@ -326,27 +322,21 @@ void test_order(void) TEST_ASSERT_NOT_EQUAL(NULL, mail1); *mail1 = TEST_VAL1; - status = mail_box.put(mail1); - TEST_ASSERT_EQUAL(osOK, status); + mail_box.put(mail1); int32_t *mail2 = mail_box.try_alloc(); TEST_ASSERT_NOT_EQUAL(NULL, mail2); *mail2 = TEST_VAL2; - status = mail_box.put(mail2); - TEST_ASSERT_EQUAL(osOK, status); + mail_box.put(mail2); - evt = mail_box.get(); - TEST_ASSERT_EQUAL(evt.status, osEventMail); - - mail1 = (int32_t *)evt.value.p; + mail1 = mail_box.try_get_for(Kernel::wait_for_u32_forever); + TEST_ASSERT_NOT_NULL(mail1); TEST_ASSERT_EQUAL(TEST_VAL1, *mail1); - evt = mail_box.get(); - TEST_ASSERT_EQUAL(evt.status, osEventMail); - - mail2 = (int32_t *)evt.value.p; + mail2 = mail_box.try_get_for(Kernel::wait_for_u32_forever); + TEST_ASSERT_NOT_NULL(mail2); TEST_ASSERT_EQUAL(TEST_VAL2, *mail2); @@ -369,7 +359,6 @@ void test_max_size() { osStatus status; Mail mail_box; - const uint32_t TEST_VAL = 123; // 1 OK uint32_t *mail1 = mail_box.try_alloc(); @@ -422,13 +411,10 @@ void test_data_type(void) TEST_ASSERT_NOT_EQUAL(NULL, mail); *mail = TEST_VAL; - status = mail_box.put(mail); - TEST_ASSERT_EQUAL(osOK, status); + mail_box.put(mail); - osEvent evt = mail_box.get(); - TEST_ASSERT_EQUAL(evt.status, osEventMail); - - mail = (T *)evt.value.p; + mail = mail_box.try_get_for(Kernel::wait_for_u32_forever); + TEST_ASSERT_NOT_NULL(mail); TEST_ASSERT_EQUAL(TEST_VAL, *mail); diff --git a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp index 51ae05dadf..822fa48a73 100644 --- a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp @@ -38,44 +38,47 @@ using namespace std::chrono; } while (0) #define THREAD_STACK_SIZE 512 -#define TEST_UINT_MSG 0xDEADBEEF -#define TEST_UINT_MSG2 0xE1EE7 #define TEST_TIMEOUT 50ms +static uint32_t msg; +static uint32_t msg2; + void thread_put_uint_msg(Queue *q) { ThisThread::sleep_for(TEST_TIMEOUT); - osStatus stat = q->put((uint32_t *) TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q->try_put(&msg); + TEST_ASSERT_TRUE(stat); } void thread_get_uint_msg(Queue *q) { ThisThread::sleep_for(TEST_TIMEOUT); - osEvent evt = q->get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + uint32_t *v; + bool stat = q->try_get_for(Kernel::wait_for_u32_forever, &v); + TEST_ASSERT_TRUE(stat) + TEST_ASSERT_EQUAL(&msg, v); } -/** Test pass uint msg +/** Test pass msg Given a queue for uint32_t messages with one slot When a uin32_t value is inserted into the queue and a message is extracted from the queue Then the extracted message is the same as previously inserted message */ -void test_pass_uint() +void test_pass() { Queue q; - osStatus stat = q.put((uint32_t *)TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put(&msg); + TEST_ASSERT_TRUE(stat) - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + uint32_t *v; + stat = q.try_get_for(Kernel::wait_for_u32_forever, &v); + TEST_ASSERT_TRUE(stat) + TEST_ASSERT_EQUAL(&msg, v); } -/** Test pass uint msg twice +/** Test pass msg twice Given a queue for uint32_t messages with one slot When a uin32_t value is inserted into the queue @@ -84,56 +87,38 @@ void test_pass_uint() Then the extracted message is the same as previously inserted message for both iterations */ -void test_pass_uint_twice() +void test_pass_twice() { Queue q; - osStatus stat = q.put((uint32_t *)TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put(&msg); + TEST_ASSERT_TRUE(stat); - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + uint32_t *v; + stat = q.try_get_for(Kernel::wait_for_u32_forever, &v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg, v); - stat = q.put((uint32_t *)TEST_UINT_MSG2); - TEST_ASSERT_EQUAL(osOK, stat); + stat = q.try_put(&msg2); + TEST_ASSERT_TRUE(stat); - evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); -} - -/** Test pass ptr msg - - Given a queue for pointers to uint32_t messages with one slot - When a pointer to an uint32_t is inserted into the queue - and a message is extracted from the queue - Then the extracted message is the same as previously inserted message - */ -void test_pass_ptr() -{ - Queue q; - uint32_t msg = TEST_UINT_MSG; - - osStatus stat = q.put(&msg); - TEST_ASSERT_EQUAL(osOK, stat); - - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(&msg, evt.value.p); + stat = q.try_get_for(Kernel::wait_for_u32_forever, &v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg2, v); } /** Test get from empty queue Given an empty queue for uint32_t values When @a get is called on the queue with timeout of 0 - Then queue returns status of osOK, but no data + Then queue returns status of false */ void test_get_empty_no_timeout() { Queue q; - osEvent evt = q.get(0ms); - TEST_ASSERT_EQUAL(osOK, evt.status); + uint32_t *v; + bool stat = q.try_get(&v); + TEST_ASSERT_FALSE(stat); } /** Test get from empty queue with timeout @@ -148,8 +133,9 @@ void test_get_empty_timeout() Timer timer; timer.start(); - osEvent evt = q.get(50ms); - TEST_ASSERT_EQUAL(osEventTimeout, evt.status); + uint32_t *v; + bool stat = q.try_get_for(50ms, &v); + TEST_ASSERT_FALSE(stat); TEST_ASSERT_DURATION_WITHIN(5ms, 50ms, timer.elapsed_time()); } @@ -171,9 +157,10 @@ void test_get_empty_wait_forever() Timer timer; timer.start(); - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + uint32_t *v; + bool stat = q.try_get_for(Kernel::wait_for_u32_forever, &v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg, v); TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time()); } @@ -181,37 +168,37 @@ void test_get_empty_wait_forever() * * Given a queue with one slot for uint32_t data * When a thread tries to insert two messages - * Then first operation succeeds and second fails with @a osErrorResource + * Then first operation succeeds and second fails */ void test_put_full_no_timeout() { Queue q; - osStatus stat = q.put((uint32_t *) TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put(&msg); + TEST_ASSERT_TRUE(stat); - stat = q.put((uint32_t *) TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osErrorResource, stat); + stat = q.try_put(&msg); + TEST_ASSERT_FALSE(stat); } /** Test put full timeout * * Given a queue with one slot for uint32_t data * When a thread tries to insert two messages with @ TEST_TIMEOUT timeout - * Then first operation succeeds and second fails with @a osErrorTimeout + * Then first operation succeeds and second fails */ void test_put_full_timeout() { Queue q; - osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put_for(TEST_TIMEOUT, &msg); + TEST_ASSERT_TRUE(stat); Timer timer; timer.start(); - stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); - TEST_ASSERT_EQUAL(osErrorTimeout, stat); + stat = q.try_put_for(TEST_TIMEOUT, &msg); + TEST_ASSERT_FALSE(stat); TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time()); } @@ -230,13 +217,13 @@ void test_put_full_waitforever() t.start(callback(thread_get_uint_msg, &q)); - osStatus stat = q.put((uint32_t *) TEST_UINT_MSG); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put(&msg); + TEST_ASSERT_TRUE(stat); Timer timer; timer.start(); - stat = q.put((uint32_t *) TEST_UINT_MSG, Kernel::wait_for_u32_forever); - TEST_ASSERT_EQUAL(osOK, stat); + stat = q.try_put_for(Kernel::wait_for_u32_forever, &msg); + TEST_ASSERT_TRUE(stat); TEST_ASSERT_DURATION_WITHIN(TEST_TIMEOUT / 10, TEST_TIMEOUT, timer.elapsed_time()); t.join(); @@ -252,19 +239,20 @@ void test_msg_order() { Queue q; - osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put_for(TEST_TIMEOUT, &msg); + TEST_ASSERT_TRUE(stat); - stat = q.put((uint32_t *) TEST_UINT_MSG2, TEST_TIMEOUT); - TEST_ASSERT_EQUAL(osOK, stat); + stat = q.try_put_for(TEST_TIMEOUT, &msg2); + TEST_ASSERT_TRUE(stat); - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + uint32_t *v; + stat = q.try_get(&v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg, v); - evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); + stat = q.try_get(&v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg2, v); } /** Test message priority @@ -277,19 +265,20 @@ void test_msg_prio() { Queue q; - osStatus stat = q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 0); - TEST_ASSERT_EQUAL(osOK, stat); + bool stat = q.try_put_for(TEST_TIMEOUT, &msg, 0); + TEST_ASSERT_TRUE(stat); - stat = q.put((uint32_t *) TEST_UINT_MSG2, TEST_TIMEOUT, 1); - TEST_ASSERT_EQUAL(osOK, stat); + stat = q.try_put_for(TEST_TIMEOUT, &msg2, 1); + TEST_ASSERT_TRUE(stat); - osEvent evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG2, evt.value.v); + uint32_t *v; + stat = q.try_get(&v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg2, v); - evt = q.get(); - TEST_ASSERT_EQUAL(osEventMessage, evt.status); - TEST_ASSERT_EQUAL(TEST_UINT_MSG, evt.value.v); + stat = q.try_get(&v); + TEST_ASSERT_TRUE(stat); + TEST_ASSERT_EQUAL(&msg, v); } /** Test queue empty @@ -302,11 +291,11 @@ void test_queue_empty() { Queue q; - TEST_ASSERT_EQUAL(true, q.empty()); + TEST_ASSERT_TRUE(q.empty()); - q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 1); + q.try_put_for(TEST_TIMEOUT, &msg, 1); - TEST_ASSERT_EQUAL(false, q.empty()); + TEST_ASSERT_FALSE(q.empty()); } /** Test queue empty @@ -319,11 +308,11 @@ void test_queue_full() { Queue q; - TEST_ASSERT_EQUAL(false, q.full()); + TEST_ASSERT_FALSE(q.full()); - q.put((uint32_t *) TEST_UINT_MSG, TEST_TIMEOUT, 1); + q.try_put_for(TEST_TIMEOUT, &msg, 1); - TEST_ASSERT_EQUAL(true, q.full()); + TEST_ASSERT_TRUE(q.full()); } utest::v1::status_t test_setup(const size_t number_of_cases) @@ -333,9 +322,8 @@ utest::v1::status_t test_setup(const size_t number_of_cases) } Case cases[] = { - Case("Test pass uint msg", test_pass_uint), - Case("Test pass uint msg twice", test_pass_uint_twice), - Case("Test pass ptr msg", test_pass_ptr), + Case("Test pass msg", test_pass), + Case("Test pass msg twice", test_pass_twice), Case("Test get from empty queue no timeout", test_get_empty_no_timeout), Case("Test get from empty queue timeout", test_get_empty_timeout), Case("Test get empty wait forever", test_get_empty_wait_forever), diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index b637ecc0d8..a96bf04f43 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -705,12 +705,12 @@ void test_msg_get() TEST_ASSERT_EQUAL(Thread::WaitingMessageGet, t.get_state()); - queue.put((int32_t *)0xE1EE7); + queue.try_put((int32_t *)0xE1EE7); } void test_msg_put_thread(Queue *queue) { - queue->put((int32_t *)0xDEADBEEF, Kernel::wait_for_u32_forever); + queue->try_put_for(Kernel::wait_for_u32_forever, (int32_t *)0xDEADBEEF); } @@ -729,7 +729,7 @@ void test_msg_put() Thread t(osPriorityNormal, THREAD_STACK_SIZE); Queue queue; - queue.put((int32_t *)0xE1EE7); + queue.try_put((int32_t *)0xE1EE7); t.start(callback(test_msg_put_thread, &queue)); diff --git a/rtos/Mail.h b/rtos/Mail.h index feca403fdb..7929a17c7b 100644 --- a/rtos/Mail.h +++ b/rtos/Mail.h @@ -33,6 +33,7 @@ #include "rtos/mbed_rtos1_types.h" #include "platform/mbed_toolchain.h" +#include "platform/mbed_assert.h" #include "platform/NonCopyable.h" #ifndef MBED_NO_GLOBAL_USING_DIRECTIVE @@ -289,31 +290,19 @@ public: * @param mptr Memory block previously allocated with Mail::alloc or Mail::calloc. * * @return Status code that indicates the execution status of the function (osOK on success). + * See note. * * @note You may call this function from ISR context. + * @note As the mail should have already been allocated, and the memory pool is the same size + * as the queue, the put operation should always succeed, despite being implemented with + * Queue::try_put - there is room in the queue for every mail from the pool. Therefore + * use of the return value is deprecated, and the function will return void in future. */ osStatus put(T *mptr) { - return _queue.put(mptr); - } - - /** Get a mail from the queue. - * - * @param millisec Timeout value. - * - * @return Event that contains mail information or error code. - * @retval osEventMessage Message received. - * @retval osOK No mail is available (and no timeout was specified). - * @retval osEventTimeout No mail has arrived during the given timeout period. - * @retval osErrorParameter A parameter is invalid or outside of a permitted range. - * - * @note You may call this function from ISR context if the millisec parameter is set to 0. - * @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. - */ - MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.") - osEvent get(uint32_t millisec) - { - return get(std::chrono::duration(millisec)); + bool ok = _queue.try_put(mptr); + MBED_ASSERT(ok); + return ok ? osOK : osErrorResource; } /** Get a mail from the queue. @@ -328,16 +317,46 @@ public: * @a osErrorParameter A parameter is invalid or outside of a permitted range. * * @note You may call this function from ISR context if the millisec parameter is set to 0. + * @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call. */ - osEvent get(Kernel::Clock::duration_u32 rel_time = Kernel::wait_for_u32_forever) + MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_get and try_get_for. In future get will be an untimed blocking call.") + osEvent get(uint32_t millisec = osWaitForever) { - osEvent evt = _queue.get(rel_time); + osEvent evt = _queue.get(millisec); if (evt.status == osEventMessage) { evt.status = osEventMail; } return evt; } + /** Get a mail from the queue. + * + * @return Pointer to received mail, or nullptr if none was received. + * + * @note You may call this function from ISR context. + */ + T *try_get() + { + T *mptr = nullptr; + _queue.try_get(&mptr); + return mptr; + } + + /** Get a mail from the queue. + * + * @param rel_time Timeout value or Kernel::wait_for_u32_forever. + * + * @return Pointer to received mail, or nullptr if none was received. + * + * @note You may call this function from ISR context if the millisec parameter is set to 0. + */ + T *try_get_for(Kernel::Clock::duration_u32 rel_time) + { + T *mptr = nullptr; + _queue.try_get_for(rel_time, &mptr); + return mptr; + } + /** Free a memory block from a mail. * * @param mptr Pointer to the memory block that was obtained with Mail::get. diff --git a/rtos/Queue.h b/rtos/Queue.h index a3a5198320..203d122727 100644 --- a/rtos/Queue.h +++ b/rtos/Queue.h @@ -122,6 +122,27 @@ public: return osMessageQueueGetCount(_id); } + /** Inserts the given element to the end of the queue. + * + * This function puts the message pointed to by `data` into the queue. The + * parameter `prio` is used to sort the message according to their priority + * (higher numbers indicate higher priority) on insertion. + * + * The function does not block, and returns immediately if the queue is full. + * + * @param data Pointer to the element to insert into the queue. + * @param prio Priority of the operation or 0 in case of default. + * (default: 0) + * + * @return true if the element was inserted, false otherwise. + * + * @note You may call this function from ISR context. + */ + bool try_put(T *data, uint8_t prio = 0) + { + return try_put_for(Kernel::Clock::duration_u32::zero(), data, prio); + } + /** Inserts the given element to the end of the queue. * * This function puts the message pointed to by `data` into the queue. The @@ -133,34 +154,27 @@ public: * queue. * * The parameter `rel_time` can have the following values: - * - When the duration is 0 (the default), the function returns instantly. + * - When the duration is 0, the function returns instantly. You could use + * `try_put` instead. * - When the duration is Kernel::wait_for_u32_forever, the function waits for an * infinite time. * - For all other values, the function waits for the given duration. * + * @param rel_time Timeout for the operation to be executed. * @param data Pointer to the element to insert into the queue. - * @param rel_time Timeout for the operation to be executed, or 0 in case - * of no timeout. (default: 0) * @param prio Priority of the operation or 0 in case of default. * (default: 0) * - * @return Status code that indicates the execution status of the function: - * @a osOK The message has been successfully inserted - * into the queue. - * @a osErrorTimeout The message could not be inserted into the - * queue in the given time. - * @a osErrorResource The message could not be inserted because - * the queue is full. - * @a osErrorParameter Internal error or nonzero timeout specified - * in an ISR. + * @return true if the element was inserted, false otherwise. * * @note You may call this function from ISR context if the rel_time * parameter is set to 0. * */ - osStatus put(T *data, Kernel::Clock::duration_u32 rel_time = Kernel::Clock::duration_u32::zero(), uint8_t prio = 0) + bool try_put_for(Kernel::Clock::duration_u32 rel_time, T *data, uint8_t prio = 0) { - return osMessageQueuePut(_id, &data, prio, rel_time.count()); + osStatus status = osMessageQueuePut(_id, &data, prio, rel_time.count()); + return status == osOK; } /** Inserts the given element to the end of the queue. @@ -198,25 +212,43 @@ public: * * @note You may call this function from ISR context if the millisec * parameter is set to 0. - * @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. + * @deprecated Replaced with try_put and try_put_for. In future put will be an untimed blocking call. */ - MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.") - osStatus put(T *data, uint32_t millisec, uint8_t prio = 0) + MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_put and try_put_for. In future put will be an untimed blocking call.") + osStatus put(T *data, uint32_t millisec = 0, uint8_t prio = 0) { - return put(data, std::chrono::duration(millisec), prio); + return osMessageQueuePut(_id, &data, prio, millisec); + } + + /** Get a message from the queue. + * + * This function retrieves a message from the queue. The message is stored + * in the location pointed to be the parameter `data_out`. + * + * The function does not block, and returns immediately if the queue is empty. + * + * @param[out] data_out Pointer to location to write the element retrieved from the queue. + * + * @return true if an element was received and written to data_out. + * + * @note You may call this function from ISR context. + */ + bool try_get(T **data_out) + { + return try_get_for(Kernel::Clock::duration_u32::zero(), data_out); } /** Get a message or wait for a message from the queue. * * This function retrieves a message from the queue. The message is stored - * in the value field of the returned `osEvent` object. + * in the location pointed to be the parameter `data_out`. * * The timeout specified by the parameter `rel_time` specifies how long the * function waits to retrieve the message from the queue. * * The timeout parameter can have the following values: * - When the timeout is 0, the function returns instantly. - * - When the timeout is Kernel::wait_for_u32_forever (default), the function waits + * - When the timeout is Kernel::wait_for_u32_forever, the function waits * infinite time until the message is retrieved. * - When the timeout is any other value, the function waits for the * specified time before returning a timeout error. @@ -226,46 +258,17 @@ public: * (FIFO) order. * * @param rel_time Timeout value. - * (default: Kernel::wait_for_u32_forever). + * @param[out] data_out Pointer to location to write the element retrieved from the queue. * - * @return Event information that includes the message in event. Message - * value and the status code in event.status: - * @a osEventMessage Message successfully received. - * @a osOK No message is available in the queue, and no - * timeout was specified. - * @a osEventTimeout No message was received before a timeout - * event occurred. - * @a osErrorParameter A parameter is invalid or outside of a - * permitted range. + * @return true if an element was received and written to data_out. * * @note You may call this function from ISR context if the rel_time * parameter is set to 0. */ - osEvent get(Kernel::Clock::duration_u32 rel_time = Kernel::wait_for_u32_forever) + bool try_get_for(Kernel::Clock::duration_u32 rel_time, T **data_out) { - osEvent event; - T *data = nullptr; - osStatus_t res = osMessageQueueGet(_id, &data, nullptr, rel_time.count()); - - switch (res) { - case osOK: - event.status = (osStatus)osEventMessage; - event.value.p = data; - break; - case osErrorResource: - event.status = osOK; - break; - case osErrorTimeout: - event.status = (osStatus)osEventTimeout; - break; - case osErrorParameter: - default: - event.status = osErrorParameter; - break; - } - event.def.message_id = _id; - - return event; + osStatus status = osMessageQueueGet(_id, data_out, nullptr, rel_time.count()); + return status == osOK; } /** Get a message or wait for a message from the queue. @@ -301,12 +304,34 @@ public: * * @note You may call this function from ISR context if the millisec * parameter is set to 0. - * @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. + * @deprecated Replaced with try_get and try_get_for. In future get will be an untimed blocking call. */ - MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.") - osEvent get(uint32_t millisec) + MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Replaced with try_get and try_get_for. In future get will be an untimed blocking call.") + osEvent get(uint32_t millisec = osWaitForever) { - return get(std::chrono::duration(millisec)); + osEvent event; + T *data = nullptr; + osStatus_t res = osMessageQueueGet(_id, &data, nullptr, millisec); + + switch (res) { + case osOK: + event.status = (osStatus)osEventMessage; + event.value.p = data; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = (osStatus)osEventTimeout; + break; + case osErrorParameter: + default: + event.status = osErrorParameter; + break; + } + event.def.message_id = _id; + + return event; } private: osMessageQueueId_t _id;