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 MAX_BLOCKS    10
13 #define TIMEOUT_TICKS 10
14 
15 struct mem_block {
16 	int member1;
17 	int member2;
18 };
19 
20 static char __aligned(sizeof(void *)) sample_mem[sizeof(struct mem_block) * MAX_BLOCKS];
21 static const osMemoryPoolAttr_t mp_attrs = {
22 	.name = "TestMempool",
23 	.attr_bits = 0,
24 	.cb_mem = NULL,
25 	.cb_size = 0,
26 	.mp_mem = sample_mem,
27 	.mp_size = sizeof(struct mem_block) * MAX_BLOCKS,
28 };
29 
mempool_common_tests(osMemoryPoolId_t mp_id,const char * expected_name)30 static void mempool_common_tests(osMemoryPoolId_t mp_id, const char *expected_name)
31 {
32 	int i;
33 	osMemoryPoolId_t dummy_id = NULL;
34 	const char *name;
35 	struct mem_block *addr_list[MAX_BLOCKS + 1];
36 	osStatus_t status;
37 
38 	zassert_true(osMemoryPoolGetName(dummy_id) == NULL,
39 		     "Something's wrong with osMemoryPoolGetName!");
40 
41 	name = osMemoryPoolGetName(mp_id);
42 	zassert_str_equal(expected_name, name, "Error getting mempool name");
43 
44 	zassert_equal(osMemoryPoolGetCapacity(dummy_id), 0,
45 		      "Something's wrong with osMemoryPoolGetCapacity!");
46 
47 	zassert_equal(osMemoryPoolGetCapacity(mp_id), MAX_BLOCKS,
48 		      "Something's wrong with osMemoryPoolGetCapacity!");
49 
50 	zassert_equal(osMemoryPoolGetBlockSize(dummy_id), 0,
51 		      "Something's wrong with osMemoryPoolGetBlockSize!");
52 
53 	zassert_equal(osMemoryPoolGetBlockSize(mp_id), sizeof(struct mem_block),
54 		      "Something's wrong with osMemoryPoolGetBlockSize!");
55 
56 	/* The memory pool should be completely available at this point */
57 	zassert_equal(osMemoryPoolGetCount(mp_id), 0,
58 		      "Something's wrong with osMemoryPoolGetCount!");
59 	zassert_equal(osMemoryPoolGetSpace(mp_id), MAX_BLOCKS,
60 		      "Something's wrong with osMemoryPoolGetSpace!");
61 
62 	for (i = 0; i < MAX_BLOCKS; i++) {
63 		addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id, osWaitForever);
64 		zassert_true(addr_list[i] != NULL, "mempool allocation failed");
65 	}
66 
67 	/* The memory pool should be completely in use at this point */
68 	zassert_equal(osMemoryPoolGetCount(mp_id), MAX_BLOCKS,
69 		      "Something's wrong with osMemoryPoolGetCount!");
70 	zassert_equal(osMemoryPoolGetSpace(mp_id), 0,
71 		      "Something's wrong with osMemoryPoolGetSpace!");
72 
73 	/* All blocks in mempool are allocated, any more allocation
74 	 * without free should fail
75 	 */
76 	addr_list[i] = (struct mem_block *)osMemoryPoolAlloc(mp_id, TIMEOUT_TICKS);
77 	zassert_true(addr_list[i] == NULL, "allocation happened."
78 					   " Something's wrong!");
79 
80 	zassert_equal(osMemoryPoolFree(dummy_id, addr_list[0]), osErrorParameter,
81 		      "mempool free worked unexpectedly!");
82 
83 	for (i = 0; i < MAX_BLOCKS; i++) {
84 		status = osMemoryPoolFree(mp_id, addr_list[i]);
85 		zassert_true(status == osOK, "mempool free failed");
86 	}
87 
88 	zassert_equal(osMemoryPoolDelete(dummy_id), osErrorParameter,
89 		      "mempool delete worked unexpectedly!");
90 
91 	status = osMemoryPoolDelete(mp_id);
92 	zassert_true(status == osOK, "mempool delete failure");
93 }
94 
95 /**
96  * @brief Test dynamic memory pool allocation and free
97  *
98  * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
99  */
ZTEST(cmsis_mempool,test_mempool_dynamic)100 ZTEST(cmsis_mempool, test_mempool_dynamic)
101 {
102 	osMemoryPoolId_t mp_id;
103 
104 	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block), NULL);
105 	zassert_true(mp_id != NULL, "mempool creation failed");
106 
107 	mempool_common_tests(mp_id, "ZephyrMemPool");
108 }
109 
110 /**
111  * @brief Test memory pool allocation and free
112  *
113  * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
114  */
ZTEST(cmsis_mempool,test_mempool)115 ZTEST(cmsis_mempool, test_mempool)
116 {
117 	osMemoryPoolId_t mp_id;
118 
119 	/* Create memory pool with invalid block size */
120 	mp_id = osMemoryPoolNew(MAX_BLOCKS + 1, sizeof(struct mem_block), &mp_attrs);
121 	zassert_true(mp_id == NULL, "osMemoryPoolNew worked unexpectedly!");
122 
123 	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block), &mp_attrs);
124 	zassert_true(mp_id != NULL, "mempool creation failed");
125 
126 	mempool_common_tests(mp_id, mp_attrs.name);
127 }
128 
129 static struct cmsis_rtos_mempool_cb mempool_cb2;
130 static const osMemoryPoolAttr_t mp_attrs2 = {
131 	.name = "TestMempool2",
132 	.attr_bits = 0,
133 	.cb_mem = &mempool_cb2,
134 	.cb_size = sizeof(mempool_cb2),
135 	.mp_mem = sample_mem,
136 	.mp_size = sizeof(struct mem_block) * MAX_BLOCKS,
137 };
138 /**
139  * @brief Test memory pool allocation and free
140  *
141  * @see osMemoryPoolNew(), osMemoryPoolAlloc(), osMemoryPoolFree(),
142  */
ZTEST(cmsis_mempool,test_mempool_static_allocation)143 ZTEST(cmsis_mempool, test_mempool_static_allocation)
144 {
145 	osMemoryPoolId_t mp_id;
146 
147 	mp_id = osMemoryPoolNew(MAX_BLOCKS, sizeof(struct mem_block), &mp_attrs2);
148 	zassert_true(mp_id != NULL, "mempool creation failed");
149 
150 	mempool_common_tests(mp_id, mp_attrs2.name);
151 }
152 ZTEST_SUITE(cmsis_mempool, NULL, NULL, NULL, NULL, NULL);
153