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