1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/portability/cmsis_os2.h>
10 #include <zephyr/portability/cmsis_types.h>
11
12 #define WAIT_TICKS 5
13 #define TIMEOUT_TICKS (10 + WAIT_TICKS)
14 #define STACKSZ CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE
15
thread_sema(void * arg)16 void thread_sema(void *arg)
17 {
18 osStatus_t status;
19
20 /* Try taking semaphore immediately when it is not available */
21 status = osSemaphoreAcquire((osSemaphoreId_t)arg, 0);
22 zassert_true(status == osErrorResource, "Semaphore acquired unexpectedly!");
23
24 /* Try taking semaphore after a TIMEOUT, but before release */
25 status = osSemaphoreAcquire((osSemaphoreId_t)arg, WAIT_TICKS);
26 zassert_true(status == osErrorTimeout, "Semaphore acquired unexpectedly!");
27
28 /* This delay ensures that the semaphore gets released by the other
29 * thread in the meantime
30 */
31 osDelay(TIMEOUT_TICKS);
32
33 /* Now that the semaphore is free, it should be possible to acquire
34 * and release it.
35 */
36 status = osSemaphoreAcquire((osSemaphoreId_t)arg, 0);
37 zassert_true(status == osOK, "Semaphore could not be acquired");
38
39 zassert_true(osSemaphoreRelease((osSemaphoreId_t)arg) == osOK, "Semaphore release failure");
40
41 /* Try releasing when no semaphore is obtained */
42 zassert_true(osSemaphoreRelease((osSemaphoreId_t)arg) == osErrorResource,
43 "Semaphore released unexpectedly!");
44 }
45
46 static K_THREAD_STACK_DEFINE(test_stack, STACKSZ);
47 static osThreadAttr_t thread_attr = {.name = "Sema_check",
48 .attr_bits = osThreadDetached,
49 .cb_mem = NULL,
50 .cb_size = 0,
51 .stack_mem = &test_stack,
52 .stack_size = STACKSZ,
53 .priority = osPriorityNormal,
54 .tz_module = 0,
55 .reserved = 0};
56
57 const osSemaphoreAttr_t sema_attr = {"mySemaphore", 0, NULL, 0U};
58
ZTEST(cmsis_semaphore,test_semaphore)59 ZTEST(cmsis_semaphore, test_semaphore)
60 {
61 osThreadId_t id;
62 osStatus_t status;
63 osSemaphoreId_t semaphore_id;
64 osSemaphoreId_t dummy_sem_id = NULL;
65 const char *name;
66
67 semaphore_id = osSemaphoreNew(1, 1, &sema_attr);
68 zassert_true(semaphore_id != NULL, "semaphore creation failed");
69
70 name = osSemaphoreGetName(semaphore_id);
71 zassert_str_equal(sema_attr.name, name, "Error getting Semaphore name");
72
73 id = osThreadNew(thread_sema, semaphore_id, &thread_attr);
74 zassert_true(id != NULL, "Thread creation failed");
75
76 zassert_true(osSemaphoreGetCount(semaphore_id) == 1);
77
78 /* Acquire invalid semaphore */
79 zassert_equal(osSemaphoreAcquire(dummy_sem_id, osWaitForever), osErrorParameter,
80 "Semaphore wait worked unexpectedly");
81
82 status = osSemaphoreAcquire(semaphore_id, osWaitForever);
83 zassert_true(status == osOK, "Semaphore wait failure");
84
85 zassert_true(osSemaphoreGetCount(semaphore_id) == 0);
86
87 /* wait for spawn thread to take action */
88 osDelay(TIMEOUT_TICKS);
89
90 /* Release invalid semaphore */
91 zassert_equal(osSemaphoreRelease(dummy_sem_id), osErrorParameter,
92 "Semaphore release worked unexpectedly");
93
94 /* Release the semaphore to be used by the other thread */
95 status = osSemaphoreRelease(semaphore_id);
96 zassert_true(status == osOK, "Semaphore release failure");
97
98 osDelay(TIMEOUT_TICKS);
99
100 /* Delete invalid semaphore */
101 zassert_equal(osSemaphoreDelete(dummy_sem_id), osErrorParameter,
102 "Semaphore delete worked unexpectedly");
103
104 status = osSemaphoreDelete(semaphore_id);
105 zassert_true(status == osOK, "semaphore delete failure");
106 }
107
108 static struct cmsis_rtos_semaphore_cb semaphore_cb2;
109 static const osSemaphoreAttr_t semaphore_attrs2 = {
110 .name = "Semaphore2",
111 .attr_bits = 0,
112 .cb_mem = &semaphore_cb2,
113 .cb_size = sizeof(semaphore_cb2),
114 };
ZTEST(cmsis_semaphore,test_semaphore_static_allocation)115 ZTEST(cmsis_semaphore, test_semaphore_static_allocation)
116 {
117 osSemaphoreId_t id;
118
119 id = osSemaphoreNew(1, 1, &semaphore_attrs2);
120 zassert_not_null(id, "Failed creating semaphores using static cb");
121
122 zassert_true(osSemaphoreDelete(id) == osOK, "semaphore delete failure");
123 }
124 ZTEST_SUITE(cmsis_semaphore, NULL, NULL, NULL, NULL, NULL);
125