Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ /* * @file * @brief Use fifo API's in different scenarios * * This module tests following three basic scenarios: * * Scenario #1 * Test Thread enters items into a fifo, starts the Child Thread * and waits for a semaphore. Child thread extracts all items from * the fifo and enters some items back into the fifo. Child Thread * gives the semaphore for Test Thread to continue. Once the control * is returned back to Test Thread, it extracts all items from the fifo. * * Scenario #2 * Test Thread enters an item into fifo2, starts a Child Thread and * extract an item from fifo1 once the item is there. The Child Thread * will extract an item from fifo2 once the item is there and enter * an item to fifo1. The flow of control goes from Test Thread to * Child Thread and so forth. * * Scenario #3 * Tests the ISR interfaces. Test thread puts items into fifo2 and gives * control to the Child thread. Child thread gets items from fifo2 and then * puts items into fifo1. Child thread gives back control to the Test thread * and Test thread gets the items from fifo1. * All the Push and Pop operations happen in ISR Context. */ #include <zephyr/ztest.h> #include <zephyr/irq_offload.h> #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) #define LIST_LEN 4 struct fdata_t { sys_snode_t snode; uint32_t data; }; static K_FIFO_DEFINE(fifo1); static K_FIFO_DEFINE(fifo2); /* Data to put into FIFO */ static struct fdata_t data1[LIST_LEN]; static struct fdata_t data2[LIST_LEN]; static struct fdata_t data_isr[LIST_LEN]; static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); static struct k_thread tdata; static struct k_sem end_sema; /*entry of contexts*/ static void tIsr_entry_put(const void *p) { uint32_t i; /* Put items into fifo */ for (i = 0U; i < LIST_LEN; i++) { k_fifo_put((struct k_fifo *)p, (void *)&data_isr[i]); } zassert_false(k_fifo_is_empty((struct k_fifo *)p)); } static void tIsr_entry_get(const void *p) { void *rx_data; uint32_t i; /* Get items from fifo */ for (i = 0U; i < LIST_LEN; i++) { rx_data = k_fifo_get((struct k_fifo *)p, K_NO_WAIT); zassert_equal(rx_data, (void *)&data_isr[i]); } zassert_true(k_fifo_is_empty((struct k_fifo *)p)); } static void thread_entry_fn_single(void *p1, void *p2, void *p3) { void *rx_data; uint32_t i; /* Get items from fifo */ for (i = 0U; i < LIST_LEN; i++) { rx_data = k_fifo_get((struct k_fifo *)p1, K_NO_WAIT); zassert_equal(rx_data, (void *)&data1[i]); } /* Put items into fifo */ for (i = 0U; i < LIST_LEN; i++) { k_fifo_put((struct k_fifo *)p1, (void *)&data2[i]); } /* Give control back to Test thread */ k_sem_give(&end_sema); } static void thread_entry_fn_dual(void *p1, void *p2, void *p3) { void *rx_data; uint32_t i; for (i = 0U; i < LIST_LEN; i++) { /* Get items from fifo2 */ rx_data = k_fifo_get((struct k_fifo *)p2, K_FOREVER); zassert_equal(rx_data, (void *)&data2[i]); /* Put items into fifo1 */ k_fifo_put((struct k_fifo *)p1, (void *)&data1[i]); } } static void thread_entry_fn_isr(void *p1, void *p2, void *p3) { /* Get items from fifo2 */ irq_offload(tIsr_entry_get, (const void *)p2); /* Put items into fifo1 */ irq_offload(tIsr_entry_put, (const void *)p1); /* Give control back to Test thread */ k_sem_give(&end_sema); } /** * @addtogroup kernel_fifo_tests * @{ */ /** * @brief Tests single fifo get and put operation in thread context * @details Test Thread enters items into a fifo, starts the Child Thread * and waits for a semaphore. Child thread extracts all items from * the fifo and enters some items back into the fifo. Child Thread * gives the semaphore for Test Thread to continue. Once the control * is returned back to Test Thread, it extracts all items from the fifo. * @see k_fifo_get(), k_fifo_is_empty(), k_fifo_put(), #K_FIFO_DEFINE(x) */ ZTEST(fifo_usage, test_single_fifo_play) { void *rx_data; uint32_t i; /* Init kernel objects */ k_sem_init(&end_sema, 0, 1); /* Put items into fifo */ for (i = 0U; i < LIST_LEN; i++) { k_fifo_put(&fifo1, (void *)&data1[i]); } k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_fn_single, &fifo1, NULL, NULL, K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT); /* Let the child thread run */ k_sem_take(&end_sema, K_FOREVER); /* Get items from fifo */ for (i = 0U; i < LIST_LEN; i++) { rx_data = k_fifo_get(&fifo1, K_NO_WAIT); zassert_equal(rx_data, (void *)&data2[i]); } /* Clear the spawn thread to avoid side effect */ k_thread_abort(tid); } /** * @brief Tests dual fifo get and put operation in thread context * @details test Thread enters an item into fifo2, starts a Child Thread and * extract an item from fifo1 once the item is there. The Child Thread * will extract an item from fifo2 once the item is there and enter * an item to fifo1. The flow of control goes from Test Thread to * Child Thread and so forth. * @see k_fifo_get(), k_fifo_is_empty(), k_fifo_put(), #K_FIFO_DEFINE(x) */ ZTEST(fifo_usage, test_dual_fifo_play) { void *rx_data; uint32_t i; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_fn_dual, &fifo1, &fifo2, NULL, K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT); for (i = 0U; i < LIST_LEN; i++) { /* Put item into fifo */ k_fifo_put(&fifo2, (void *)&data2[i]); /* Get item from fifo */ rx_data = k_fifo_get(&fifo1, K_FOREVER); zassert_equal(rx_data, (void *)&data1[i]); } /* Clear the spawn thread to avoid side effect */ k_thread_abort(tid); } /** * @brief Tests fifo put and get operation in interrupt context * @details Tests the ISR interfaces. Test thread puts items into fifo2 * and gives control to the Child thread. Child thread gets items from * fifo2 and then puts items into fifo1. Child thread gives back control * to the Test thread and Test thread gets the items from fifo1. * All the Push and Pop operations happen in ISR Context. * @see k_fifo_get(), k_fifo_is_empty(), k_fifo_put(), #K_FIFO_DEFINE(x) */ ZTEST(fifo_usage, test_isr_fifo_play) { /* Init kernel objects */ k_sem_init(&end_sema, 0, 1); k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_fn_isr, &fifo1, &fifo2, NULL, K_PRIO_PREEMPT(0), K_INHERIT_PERMS, K_NO_WAIT); /* Put item into fifo */ irq_offload(tIsr_entry_put, (const void *)&fifo2); /* Let the child thread run */ k_sem_take(&end_sema, K_FOREVER); /* Get item from fifo */ irq_offload(tIsr_entry_get, (const void *)&fifo1); /* Clear the spawn thread to avoid side effect */ k_thread_abort(tid); } /** * @} */ ZTEST_SUITE(fifo_usage, NULL, NULL, ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); |