blob: 9fc62e5807d2b8491ac4c252a4773f61b1292908 [file] [log] [blame]
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/kernel.h>
#include <cmsis_os.h>
struct sample_data {
int data1;
unsigned char data2;
unsigned int data3;
};
#define MAIL1_DATA1 75663
#define MAIL1_DATA2 156
#define MAIL1_DATA3 1000001
#define MAIL2_DATA1 93567
#define MAIL2_DATA2 255
#define MAIL2_DATA3 1234567
#define TIMEOUT 500
#define Q_LEN 5
osMailQDef(mail, Q_LEN, struct sample_data);
osMailQId mail_id;
void send_thread(void const *argument)
{
int i;
struct sample_data *tx_ptr;
struct sample_data zeroblock;
osStatus status;
/* This is used for comparison later in the function */
memset(&zeroblock, 0, sizeof(struct sample_data));
status = osMailPut(mail_id, NULL);
zassert_true(status == osErrorValue,
"Something's wrong with osMailPut. It is passing for NULL mail!");
/* Wait for mail_recv to complete initial checks */
osDelay(TIMEOUT);
/* Prepare and send 1st mail */
tx_ptr = osMailAlloc(mail_id, osWaitForever);
zassert_true(tx_ptr != NULL, "Mail1 alloc failed");
tx_ptr->data1 = MAIL1_DATA1;
tx_ptr->data2 = MAIL1_DATA2;
tx_ptr->data3 = MAIL1_DATA3;
status = osMailPut(mail_id, tx_ptr);
zassert_true(status == osOK, "osMailPut failure for mail1");
/* Fill the queue with blocks of mails */
for (i = 0; i < Q_LEN; i++) {
/* Alternately use osMailAlloc and osMailCAlloc to ensure
* both the APIs are tested.
*/
if (i & 1) {
tx_ptr = osMailCAlloc(mail_id, osWaitForever);
} else {
tx_ptr = osMailAlloc(mail_id, osWaitForever);
}
zassert_true(tx_ptr != NULL, "Mail alloc failed");
tx_ptr->data1 = i;
tx_ptr->data2 = i+1;
tx_ptr->data3 = i+2;
status = osMailPut(mail_id, tx_ptr);
zassert_true(status == osOK,
"osMailPut failure for mail!");
}
/* Try allocating mail to a full queue immediately
* before it is emptied out and assert failure
*/
tx_ptr = osMailAlloc(mail_id, 0);
zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
tx_ptr = osMailCAlloc(mail_id, 0);
zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");
/* Try allocating mail to a full queue within a duration
* less than TIMEOUT, before the queue is emptied out
*/
tx_ptr = osMailAlloc(mail_id, TIMEOUT/3);
zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
tx_ptr = osMailCAlloc(mail_id, TIMEOUT/3);
zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");
/* Send another mail after the queue is emptied */
tx_ptr = osMailCAlloc(mail_id, TIMEOUT*2);
zassert_true(tx_ptr != NULL, "Mail alloc failed");
zassert_equal(memcmp(tx_ptr, &zeroblock, sizeof(struct sample_data)), 0,
"osMailCAlloc returned memory not initialized to 0");
tx_ptr->data1 = MAIL2_DATA1;
tx_ptr->data2 = MAIL2_DATA2;
tx_ptr->data3 = MAIL2_DATA3;
status = osMailPut(mail_id, tx_ptr);
zassert_true(status == osOK, "osMailPut failure for mail");
}
void mail_recv(void)
{
int i;
struct sample_data *rx_ptr;
osEvent evt;
osStatus status;
/* Try getting mail immediately before the queue is populated */
evt = osMailGet(mail_id, 0);
zassert_true(evt.status == osOK,
"Something's wrong with osMailGet!");
/* Try receiving mail within a duration of TIMEOUT */
evt = osMailGet(mail_id, TIMEOUT);
zassert_true(evt.status == osEventTimeout,
"Something's wrong with osMailGet!");
/* Receive 1st mail */
evt = osMailGet(mail_id, osWaitForever);
zassert_true(evt.status == osEventMail, "osMailGet failure");
rx_ptr = evt.value.p;
zassert_equal(rx_ptr->data1, MAIL1_DATA1);
zassert_equal(rx_ptr->data2, MAIL1_DATA2);
zassert_equal(rx_ptr->data3, MAIL1_DATA3);
status = osMailFree(mail_id, rx_ptr);
zassert_true(status == osOK, "osMailFree failure");
/* Wait for queue to get filled */
osDelay(TIMEOUT);
/* Empty the queue */
for (i = 0; i < Q_LEN; i++) {
evt = osMailGet(mail_id, osWaitForever);
zassert_true(evt.status == osEventMail, "osMailGet failure");
rx_ptr = evt.value.p;
zassert_equal(rx_ptr->data1, i);
zassert_equal(rx_ptr->data2, i + 1);
zassert_equal(rx_ptr->data3, i + 2);
status = osMailFree(mail_id, rx_ptr);
zassert_true(status == osOK, "osMailFree failure");
}
/* Receive the next mail */
evt = osMailGet(mail_id, osWaitForever);
zassert_true(evt.status == osEventMail, "osMailGet failure");
rx_ptr = evt.value.p;
zassert_equal(rx_ptr->data1, MAIL2_DATA1);
zassert_equal(rx_ptr->data2, MAIL2_DATA2);
zassert_equal(rx_ptr->data3, MAIL2_DATA3);
status = osMailFree(mail_id, rx_ptr);
zassert_true(status == osOK, "osMailFree failure");
}
osThreadDef(send_thread, osPriorityNormal, 1, 0);
ZTEST(cmsis_mailq, test_mailq)
{
osThreadId tid;
mail_id = osMailCreate(osMailQ(mail), NULL);
zassert_true(mail_id != NULL, "Mail creation failed");
tid = osThreadCreate(osThread(send_thread), NULL);
zassert_true(tid != NULL, "Thread creation failed");
mail_recv();
}
ZTEST_SUITE(cmsis_mailq, NULL, NULL, NULL, NULL, NULL);