/* the task spins fibers that get lifo data in time, except the last one */ static int test_multiple_fibers_get_data(struct timeout_order_data *test_data, int test_data_size) { struct timeout_order_data *data; int ii; for (ii = 0; ii < test_data_size-1; ii++) { task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE, test_fiber_pend_and_get_data, (int)&test_data[ii], 0, FIBER_PRIORITY, 0); } task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE, test_fiber_pend_and_timeout, (int)&test_data[ii], 0, FIBER_PRIORITY, 0); for (ii = 0; ii < test_data_size-1; ii++) { nano_task_lifo_put(test_data[ii].lifo, get_scratch_packet()); data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED); if (data->q_order == ii) { TC_PRINT(" got fiber (q order: %d, t/o: %d, lifo %p) as expected\n", data->q_order, data->timeout, data->lifo); } else { TC_ERROR(" *** fiber %d woke up, expected %d\n", data->q_order, ii); return TC_FAIL; } } data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED); if (data->q_order == ii) { TC_PRINT(" got fiber (q order: %d, t/o: %d, lifo %p) as expected\n", data->q_order, data->timeout, data->lifo); } else { TC_ERROR(" *** fiber %d woke up, expected %d\n", data->timeout_order, ii); return TC_FAIL; } return TC_PASS; }
void RegressionTaskEntry(void) { int tcRC; nano_sem_init(&test_nano_timers_sem); PRINT_DATA("Starting timer tests\n"); PRINT_LINE; task_fiber_start(test_nano_timers_stack, 512, test_nano_timers, 0, 0, 5, 0); /* Test the task_timer_alloc() API */ TC_PRINT("Test the allocation of timers\n"); tcRC = testLowTimerGet(); if (tcRC != TC_PASS) { goto exitRtn; } TC_PRINT("Test the one shot feature of a timer\n"); tcRC = testLowTimerOneShot(); if (tcRC != TC_PASS) { goto exitRtn; } TC_PRINT("Test that a timer does not start\n"); tcRC = testLowTimerDoesNotStart(); if (tcRC != TC_PASS) { goto exitRtn; } TC_PRINT("Test the periodic feature of a timer\n"); tcRC = testLowTimerPeriodicity(); if (tcRC != TC_PASS) { goto exitRtn; } TC_PRINT("Test the stopping of a timer\n"); tcRC = testLowTimerStop(); if (tcRC != TC_PASS) { goto exitRtn; } TC_PRINT("Verifying the nanokernel timer fired\n"); if (!nano_task_sem_take(&test_nano_timers_sem)) { tcRC = TC_FAIL; goto exitRtn; } TC_PRINT("Verifying the nanokernel timeouts worked\n"); tcRC = task_sem_take_wait_timeout(test_nano_timeouts_sem, SECONDS(5)); tcRC = tcRC == RC_OK ? TC_PASS : TC_FAIL; exitRtn: TC_END_RESULT(tcRC); TC_END_REPORT(tcRC); }
/* the task spins fibers that get the sem in time, except the last one */ static int test_multiple_fibers_get_sem(struct timeout_order_data *test_data, int test_data_size) { struct timeout_order_data *data; int ii; for (ii = 0; ii < test_data_size-1; ii++) { task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE, test_fiber_pend_and_get_sem, (int)&test_data[ii], 0, FIBER_PRIORITY, 0); } task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE, test_fiber_pend_and_timeout, (int)&test_data[ii], 0, FIBER_PRIORITY, 0); for (ii = 0; ii < test_data_size-1; ii++) { nano_task_sem_give(test_data[ii].sem); data = nano_task_fifo_get_wait(&timeout_order_fifo); if (data->q_order == ii) { TC_PRINT(" got fiber (q order: %d, t/o: %d, sem: %p) as expected\n", data->q_order, data->timeout, data->sem); } else { TC_ERROR(" *** fiber %d woke up, expected %d\n", data->q_order, ii); return TC_FAIL; } } data = nano_task_fifo_get_wait(&timeout_order_fifo); if (data->q_order == ii) { TC_PRINT(" got fiber (q order: %d, t/o: %d, sem: %p) as expected\n", data->q_order, data->timeout, data->sem); } else { TC_ERROR(" *** fiber %d woke up, expected %d\n", data->timeout_order, ii); return TC_FAIL; } return TC_PASS; }
/** * * @brief The test main function * * @return 0 on success */ int nanoIntLatency(void) { PRINT_FORMAT(" 1- Measure time to switch from fiber to ISR execution"); TICK_SYNCH(); task_fiber_start(&fiberStack[0], STACKSIZE, (nano_fiber_entry_t) fiberInt, 0, 0, 6, 0); PRINT_FORMAT(" switching time is %lu tcs = %lu nsec", timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp)); return 0; }
/** * * @brief The test main function * * @return 0 on success */ int nanoIntToFiber(void) { PRINT_FORMAT(" 2- Measure time to switch from ISR back to interrupted" " fiber"); TICK_SYNCH(); task_fiber_start(&fiberStack[0], STACKSIZE, (nano_fiber_entry_t) fiberInt, 0, 0, 6, 0); if (flagVar == 1) { PRINT_FORMAT(" switching time is %lu tcs = %lu nsec", timestamp, SYS_CLOCK_HW_CYCLES_TO_NS(timestamp)); } return 0; }
void shell_init(const char *str, const struct shell_cmd *cmds) { nano_fifo_init(&cmds_queue); nano_fifo_init(&avail_queue); commands = cmds; line_queue_init(); prompt = str ? str : ""; task_fiber_start(stack, STACKSIZE, shell, 0, 0, 7, 0); /* Register serial console handler */ uart_register_input(&avail_queue, &cmds_queue, completion); }
void main(void) { int rv; /* return value from tests */ TC_START("Test Nanokernel Semaphores"); initNanoObjects(); rv = testSemTaskNoWait(); if (rv != TC_PASS) { goto doneTests; } rv = testSemIsrNoWait(); if (rv != TC_PASS) { goto doneTests; } semTestState = STS_INIT; /* * Start the fiber. The fiber will be given a higher priority than the * main task. */ task_fiber_start(fiberStack, FIBER_STACKSIZE, fiberEntry, 0, 0, FIBER_PRIORITY, 0); rv = testSemWait(); if (rv != TC_PASS) { goto doneTests; } rv = test_multiple_waiters(); if (rv != TC_PASS) { goto doneTests; } rv = test_timeout(); if (rv != TC_PASS) { goto doneTests; } doneTests: TC_END_RESULT(rv); TC_END_REPORT(rv); }
void tester_init(void) { int i; nano_fifo_init(&cmds_queue); nano_fifo_init(&avail_queue); for (i = 0; i < CMD_QUEUED; i++) { nano_fifo_put(&avail_queue, &cmd_buf[i * BTP_MTU]); } task_fiber_start(stack, STACKSIZE, cmd_handler, 0, 0, 7, 0); uart_pipe_register(nano_fifo_get(&avail_queue, TICKS_NONE), BTP_MTU, recv_cb); printk("BT tester initialized\n"); }
void main(void) { net_init(); init_server(); ipsum_len = strlen(lorem_ipsum); if (!get_context(&unicast, &multicast)) { PRINT("%s: Cannot get network context\n", __func__); return; } #ifdef CONFIG_MICROKERNEL receiving(); #else task_fiber_start(&stack_receiving[0], STACKSIZE, (nano_fiber_entry_t)receiving, 0, 0, 7, 0); #endif }
void main(void) { #ifdef CONFIG_OBJECTS_PRINTK printk("Using printk\n"); #endif #if CONFIG_STATIC_ISR IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0); #endif #ifdef CONFIG_OBJECTS_FIBER /* start a trivial fiber */ task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE, (int) func_array, 10, 0); #endif #ifdef CONFIG_OBJECTS_WHILELOOP while (1) { i++; } #endif }
static int do_test_multiple_waiters(void) { int ii; /* pend all fibers one the same semaphore */ for (ii = 0; ii < NUM_WAITERS; ii++) { task_fiber_start(fiber_multi_waiters_stacks[ii], FIBER_STACKSIZE, fiber_multi_waiters, ii, 0, FIBER_PRIORITY, 0); } /* wake up all the fibers: the task is preempted each time */ for (ii = 0; ii < NUM_WAITERS; ii++) { nano_task_sem_give(&multi_waiters); } /* reply_multi_waiters will have been given once for each fiber */ for (ii = 0; ii < NUM_WAITERS; ii++) { if (!nano_task_sem_take(&reply_multi_waiters)) { TC_ERROR(" *** Cannot take sem supposedly given by waiters.\n"); return TC_FAIL; } } TC_PRINT("Task took multi-waiter reply semaphore %d times, as expected.\n", NUM_WAITERS); if (nano_task_sem_take(&multi_waiters)) { TC_ERROR(" *** multi_waiters should have been empty.\n"); return TC_FAIL; } if (nano_task_sem_take(&reply_multi_waiters)) { TC_ERROR(" *** reply_multi_waiters should have been empty.\n"); return TC_FAIL; } return TC_PASS; }
int main(void) { int i; PRINTF(DEMO_DESCRIPTION, "fibers", "nanokernel"); for (i = 0; i < N_PHILOSOPHERS; i++) { nano_sem_init(&forks[i]); nano_task_sem_give(&forks[i]); } /* create philosopher fibers */ for (i = 0; i < N_PHILOSOPHERS; i++) { task_fiber_start(&philStack[i][0], STSIZE, (nano_fiber_entry_t) philEntry, 0, 0, 6, 0); } /* wait forever */ while (1) { extern void nano_cpu_idle(void); nano_cpu_idle(); } }
void main(void) { struct nano_timer timer; uint32_t data[2] = {0, 0}; task_fiber_start(&fiberStack[0], STACKSIZE, (nano_fiber_entry_t) fiberEntry, 0, 0, 7, 0); nano_sem_init(&nanoSemTask); nano_timer_init(&timer, data); while (1) { /* say "hello" */ PRINT("%s: Hello Screen!\n", __FUNCTION__); /* wait a while, then let fiber have a turn */ nano_task_timer_start(&timer, SLEEPTICKS); nano_task_timer_wait(&timer); nano_task_sem_give(&nanoSemFiber); /* now wait for fiber to let us have a turn */ nano_task_sem_take_wait(&nanoSemTask); } }
void main(void) { int rv = TC_PASS; nano_fifo_init(&fifo); errno = errno_values[N_FIBERS]; printk("task, errno before starting fibers: %x\n", errno); for (int ii = 0; ii < N_FIBERS; ii++) { result[ii].pass = TC_FAIL; } for (int ii = 0; ii < N_FIBERS; ii++) { task_fiber_start(stacks[ii], STACK_SIZE, errno_fiber, ii, errno_values[ii], ii + 5, 0); } for (int ii = 0; ii < N_FIBERS; ii++) { struct result *p = nano_task_fifo_get(&fifo, 10); if (!p || !p->pass) { rv = TC_FAIL; } } printk("task, errno after running fibers: %x\n", errno); if (errno != errno_values[N_FIBERS]) { rv = TC_FAIL; } TC_END_RESULT(rv); TC_END_REPORT(rv); }
/* the timeout test entry point */ static int test_timeout(void) { int64_t orig_ticks; int32_t timeout; int rv; int test_data_size; struct reply_packet reply_packet; nano_sem_init(&sem_timeout[0]); nano_sem_init(&sem_timeout[1]); nano_fifo_init(&timeout_order_fifo); /* test nano_task_sem_take_wait_timeout() with timeout */ timeout = 10; orig_ticks = nano_tick_get(); rv = nano_task_sem_take_wait_timeout(&sem_timeout[0], timeout); if (rv) { TC_ERROR(" *** timeout of %d did not time out.\n", timeout); return TC_FAIL; } if ((nano_tick_get() - orig_ticks) < timeout) { TC_ERROR(" *** task did not wait long enough on timeout of %d.\n", timeout); return TC_FAIL; } /* test nano_task_sem_take_wait_timeout with timeout of 0 */ rv = nano_task_sem_take_wait_timeout(&sem_timeout[0], 0); if (rv) { TC_ERROR(" *** timeout of 0 did not time out.\n"); return TC_FAIL; } /* test nano_task_sem_take_wait_timeout with timeout > 0 */ TC_PRINT("test nano_task_sem_take_wait_timeout with timeout > 0\n"); timeout = 3; orig_ticks = nano_tick_get(); rv = nano_task_sem_take_wait_timeout(&sem_timeout[0], timeout); if (rv) { TC_ERROR(" *** timeout of %d did not time out.\n", timeout); return TC_FAIL; } if (!is_timeout_in_range(orig_ticks, timeout)) { return TC_FAIL; } TC_PRINT("nano_task_sem_take_wait_timeout timed out as expected\n"); /* * test nano_task_sem_take_wait_timeout with a timeout and fiber that gives * the semaphore on time */ timeout = 5; orig_ticks = nano_tick_get(); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_give_timeout, (int)&sem_timeout[0], timeout, FIBER_PRIORITY, 0); rv = nano_task_sem_take_wait_timeout(&sem_timeout[0], (int)(timeout + 5)); if (!rv) { TC_ERROR(" *** timed out even if semaphore was given in time.\n"); return TC_FAIL; } if (!is_timeout_in_range(orig_ticks, timeout)) { return TC_FAIL; } TC_PRINT("nano_task_sem_take_wait_timeout got sem in time, as expected\n"); /* * test nano_task_sem_take_wait_timeout with TICKS_NONE and the * semaphore unavailable. */ if (nano_task_sem_take_wait_timeout(&sem_timeout[0], TICKS_NONE)) { TC_ERROR("task with TICKS_NONE got sem, but shouldn't have\n"); return TC_FAIL; } TC_PRINT("task with TICKS_NONE did not get sem, as expected\n"); /* * test nano_task_sem_take_wait_timeout with TICKS_NONE and the * semaphore available. */ nano_task_sem_give(&sem_timeout[0]); if (!nano_task_sem_take_wait_timeout(&sem_timeout[0], TICKS_NONE)) { TC_ERROR("task with TICKS_NONE did not get available sem\n"); return TC_FAIL; } TC_PRINT("task with TICKS_NONE got available sem, as expected\n"); /* * test nano_task_sem_take_wait_timeout with TICKS_UNLIMITED and the * semaphore available. */ TC_PRINT("Trying to take available sem with TICKS_UNLIMITED:\n" " will hang the test if it fails.\n"); nano_task_sem_give(&sem_timeout[0]); if (!nano_task_sem_take_wait_timeout(&sem_timeout[0], TICKS_UNLIMITED)) { TC_ERROR(" *** This will never be hit!!! .\n"); return TC_FAIL; } TC_PRINT("task with TICKS_UNLIMITED got available sem, as expected\n"); /* test fiber with timeout of TICKS_NONE not getting empty semaphore */ task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0); if (!nano_task_fifo_get(&timeout_order_fifo)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 0) { TC_ERROR(" *** fiber should not have obtained the semaphore.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_NONE did not get sem, as expected\n"); /* test fiber with timeout of TICKS_NONE getting full semaphore */ nano_task_sem_give(&sem_timeout[0]); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0); if (!nano_task_fifo_get(&timeout_order_fifo)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 1) { TC_ERROR(" *** fiber should have obtained the semaphore.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_NONE got available sem, as expected\n"); /* test fiber with timeout of TICKS_UNLIMITED getting full semaphore */ nano_task_sem_give(&sem_timeout[0]); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0); if (!nano_task_fifo_get(&timeout_order_fifo)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 1) { TC_ERROR(" *** fiber should have obtained the semaphore.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_UNLIMITED got available sem, as expected\n"); /* test multiple fibers pending on the same sem with different timeouts */ test_data_size = ARRAY_SIZE(timeout_order_data); TC_PRINT("testing timeouts of %d fibers on same sem\n", test_data_size); rv = test_multiple_fibers_pending(timeout_order_data, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not time out in the right order\n"); return TC_FAIL; } /* test multiple fibers pending on different sems with different timeouts */ test_data_size = ARRAY_SIZE(timeout_order_data_mult_sem); TC_PRINT("testing timeouts of %d fibers on different sems\n", test_data_size); rv = test_multiple_fibers_pending(timeout_order_data_mult_sem, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not time out in the right order\n"); return TC_FAIL; } /* * test multiple fibers pending on same sem with different timeouts, but * getting the semaphore in time, except the last one. */ test_data_size = ARRAY_SIZE(timeout_order_data); TC_PRINT("testing %d fibers timing out, but obtaining the sem in time\n" "(except the last one, which times out)\n", test_data_size); rv = test_multiple_fibers_get_sem(timeout_order_data, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not get the sem in the right order\n"); return TC_FAIL; } return TC_PASS; }
void main(void) { int count = 0; /* counter */ uint32_t data; /* data used to put and get from the stack queue */ int rc; /* return code */ TC_START("Test Nanokernel STACK"); /* Initialize data */ initData(); /* Initialize the queues and semaphore */ initNanoObjects(); /* Start fiber3 */ task_fiber_start(&fiberStack3[0], STACKSIZE, (nano_fiber_entry_t) fiber3, 0, 0, 7, 0); /* * While fiber3 blocks (for one second), wait for an item to be pushed * onto the stack so that it can be popped. This will put the nanokernel * into an idle state. */ rc = nano_task_stack_pop(&nanoStackObj, &data, TICKS_UNLIMITED); if ((rc == 0) || (data != myData[0])) { TC_ERROR("nano_task_stack_pop(TICKS_UNLIMITED) expected 0x%x, but got 0x%x\n", myData[0], data); retCode = TC_FAIL; goto exit; } /* Put data */ TC_PRINT("Test Task STACK Push\n"); TC_PRINT("\nTASK STACK Put Order: "); for (int i=0; i<NUM_STACK_ELEMENT; i++) { nano_task_stack_push(&nanoStackObj, myData[i]); TC_PRINT(" %d,", myData[i]); } TC_PRINT("\n"); PRINT_LINE; /* Start fiber */ task_fiber_start(&fiberStack1[0], STACKSIZE, (nano_fiber_entry_t) fiber1, 0, 0, 7, 0); if (retCode == TC_FAIL) { goto exit; } /* * Wait for fiber1 to complete execution. (Using a semaphore gives * the fiber the freedom to do blocking-type operations if it wants to.) * */ nano_task_sem_take(&nanoSemObj, TICKS_UNLIMITED); TC_PRINT("Test Task STACK Pop\n"); /* Get all data */ while (nano_task_stack_pop(&nanoStackObj, &data, TICKS_NONE) != 0) { TC_PRINT("TASK STACK Pop: count = %d, data is %d\n", count, data); if ((count >= NUM_STACK_ELEMENT) || (data != myData[count])) { TCERR1(count); retCode = TC_FAIL; goto exit; } count++; } /* Test Task Stack Pop Wait interfaces*/ testTaskStackPopW(); if (retCode == TC_FAIL) { goto exit; } PRINT_LINE; /* Test ISR interfaces */ testIsrStackFromTask(); PRINT_LINE; exit: TC_END_RESULT(retCode); TC_END_REPORT(retCode); }
int stack_test(void) { uint32_t t; int i = 0; int return_value = 0; /* test get wait & put fiber functions */ fprintf(output_file, sz_test_case_fmt, "Stack #1"); fprintf(output_file, sz_description, "\n\tnano_stack_init" "\n\tnano_fiber_stack_pop_wait" "\n\tnano_fiber_stack_push"); printf(sz_test_start_fmt); stack_test_init(); t = BENCH_START(); task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); task_fiber_start(fiber_stack2, STACK_SIZE, stack_fiber2, (int) &i, NUMBER_OF_LOOPS, 3, 0); t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i, t); /* test get/yield & put fiber functions */ fprintf(output_file, sz_test_case_fmt, "Stack #2"); fprintf(output_file, sz_description, "\n\tnano_stack_init" "\n\tnano_fiber_stack_pop_wait" "\n\tnano_fiber_stack_pop" "\n\tnano_fiber_stack_push" "\n\tfiber_yield"); printf(sz_test_start_fmt); stack_test_init(); t = BENCH_START(); i = 0; task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); task_fiber_start(fiber_stack2, STACK_SIZE, stack_fiber3, (int) &i, NUMBER_OF_LOOPS, 3, 0); t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i, t); /* test get wait & put fiber/task functions */ fprintf(output_file, sz_test_case_fmt, "Stack #3"); fprintf(output_file, sz_description, "\n\tnano_stack_init" "\n\tnano_fiber_stack_pop_wait" "\n\tnano_fiber_stack_push" "\n\tnano_task_stack_pop_wait" "\n\tnano_task_stack_push"); printf(sz_test_start_fmt); stack_test_init(); t = BENCH_START(); task_fiber_start(fiber_stack1, STACK_SIZE, stack_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) { uint32_t data; data = 2 * i; nano_task_stack_push(&nano_stack_1, data); data = 2 * i + 1; nano_task_stack_push(&nano_stack_1, data); data = nano_task_stack_pop_wait(&nano_stack_2); if (data != 2 * i + 1) { break; } data = nano_task_stack_pop_wait(&nano_stack_2); if (data != 2 * i) { break; } } t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i * 2, t); return return_value; }
/** * * @brief The main test entry * * @return 1 if success and 0 on failure */ int lifo_test(void) { uint32_t t; int i = 0; int return_value = 0; int element[2]; int j; nano_fifo_init(&nanoFifo_sync); /* test get wait & put fiber functions */ fprintf(output_file, sz_test_case_fmt, "LIFO #1"); fprintf(output_file, sz_description, "\n\tnano_lifo_init" "\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)" "\n\tnano_fiber_lifo_put"); printf(sz_test_start_fmt); lifo_test_init(); t = BENCH_START(); task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); task_fiber_start(fiber_stack2, STACK_SIZE, lifo_fiber2, (int) &i, NUMBER_OF_LOOPS, 3, 0); t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i, t); /* fibers have done their job, they can stop now safely: */ for (j = 0; j < 2; j++) { nano_task_fifo_put(&nanoFifo_sync, (void *) element); } /* test get/yield & put fiber functions */ fprintf(output_file, sz_test_case_fmt, "LIFO #2"); fprintf(output_file, sz_description, "\n\tnano_lifo_init" "\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)" "\n\tnano_fiber_lifo_get(TICKS_NONE)" "\n\tnano_fiber_lifo_put" "\n\tfiber_yield"); printf(sz_test_start_fmt); lifo_test_init(); t = BENCH_START(); i = 0; task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); task_fiber_start(fiber_stack2, STACK_SIZE, lifo_fiber3, (int) &i, NUMBER_OF_LOOPS, 3, 0); t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i, t); /* fibers have done their job, they can stop now safely: */ for (j = 0; j < 2; j++) { nano_task_fifo_put(&nanoFifo_sync, (void *) element); } /* test get wait & put fiber/task functions */ fprintf(output_file, sz_test_case_fmt, "LIFO #3"); fprintf(output_file, sz_description, "\n\tnano_lifo_init" "\n\tnano_fiber_lifo_get(TICKS_UNLIMITED)" "\n\tnano_fiber_lifo_put" "\n\tnano_task_lifo_get(TICKS_UNLIMITED)" "\n\tnano_task_lifo_put"); printf(sz_test_start_fmt); lifo_test_init(); t = BENCH_START(); task_fiber_start(fiber_stack1, STACK_SIZE, lifo_fiber1, 0, NUMBER_OF_LOOPS, 3, 0); for (i = 0; i < NUMBER_OF_LOOPS / 2; i++) { int element[2]; int *pelement; element[1] = 2 * i; nano_task_lifo_put(&nanoLifo1, element); element[1] = 2 * i + 1; nano_task_lifo_put(&nanoLifo1, element); pelement = (int *)nano_task_lifo_get(&nanoLifo2, TICKS_UNLIMITED); if (pelement[1] != 2 * i + 1) { break; } pelement = (int *)nano_task_lifo_get(&nanoLifo2, TICKS_UNLIMITED); if (pelement[1] != 2 * i) { break; } } t = TIME_STAMP_DELTA_GET(t); return_value += check_result(i * 2, t); /* fibers have done their job, they can stop now safely: */ for (j = 0; j < 2; j++) { nano_task_fifo_put(&nanoFifo_sync, (void *) element); } return return_value; }
void main(void) { int rv; /* return value from tests */ TC_START("Test Nanokernel CPU and thread routines"); TC_PRINT("Initializing nanokernel objects\n"); rv = initNanoObjects(); if (rv != TC_PASS) { goto doneTests; } TC_PRINT("Testing nano_cpu_idle()\n"); rv = nano_cpu_idleTest(); if (rv != TC_PASS) { goto doneTests; } TC_PRINT("Testing interrupt locking and unlocking\n"); rv = nanoCpuDisableInterruptsTest(irq_lockWrapper, irq_unlockWrapper, -1); if (rv != TC_PASS) { goto doneTests; } /* * The Cortex-M3/M4 use the SYSTICK exception for the system timer, which is * not considered an IRQ by the irq_enable/Disable APIs. */ #if !defined(CONFIG_CPU_CORTEX_M3_M4) /* Disable interrupts coming from the timer. */ TC_PRINT("Testing irq_disable() and irq_enable()\n"); rv = nanoCpuDisableInterruptsTest(irq_disableWrapper, irq_enableWrapper, TICK_IRQ); if (rv != TC_PASS) { goto doneTests; } #endif rv = nanoCtxTaskTest(); if (rv != TC_PASS) { goto doneTests; } TC_PRINT("Spawning a fiber from a task\n"); fiberEvidence = 0; task_fiber_start(fiberStack1, FIBER_STACKSIZE, fiberEntry, (int) sys_thread_self_get(), 0, FIBER_PRIORITY, 0); if (fiberEvidence != 1) { rv = TC_FAIL; TC_ERROR(" - fiber did not execute as expected!\n"); goto doneTests; } /* * The fiber ran, now wake it so it can test sys_thread_self_get and * sys_execution_context_type_get. */ TC_PRINT("Fiber to test sys_thread_self_get() and sys_execution_context_type_get\n"); nano_task_sem_give(&wakeFiber); if (fiberDetectedError != 0) { rv = TC_FAIL; TC_ERROR(" - failure detected in fiber; fiberDetectedError = %d\n", fiberDetectedError); goto doneTests; } TC_PRINT("Fiber to test fiber_yield()\n"); nano_task_sem_give(&wakeFiber); if (fiberDetectedError != 0) { rv = TC_FAIL; TC_ERROR(" - failure detected in fiber; fiberDetectedError = %d\n", fiberDetectedError); goto doneTests; } nano_task_sem_give(&wakeFiber); rv = test_timeout(); if (rv != TC_PASS) { goto doneTests; } /* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */ #if !defined(CONFIG_CPU_CORTEX_M3_M4) /* * Test divide by zero exception handler. * * WARNING: This code has been very carefully crafted so that it does * what it is supposed to. Both "error" and "excHandlerExecuted" must be * volatile to prevent the compiler from issuing a "divide by zero" * warning (since otherwise in knows "excHandlerExecuted" is zero), * and to ensure the compiler issues the two byte "idiv" instruction * that the exception handler is designed to deal with. */ volatile int error; /* used to create a divide by zero error */ TC_PRINT("Verifying exception handler installed\n"); excHandlerExecuted = 0; error = error / excHandlerExecuted; TC_PRINT("excHandlerExecuted: %d\n", excHandlerExecuted); rv = (excHandlerExecuted == 1) ? TC_PASS : TC_FAIL; #endif doneTests: TC_END_RESULT(rv); TC_END_REPORT(rv); }
/* the timeout test entry point */ static int test_timeout(void) { int64_t orig_ticks; int32_t timeout; int rv; void *packet, *scratch_packet; int test_data_size; int ii; struct reply_packet reply_packet; nano_lifo_init(&lifo_timeout[0]); nano_lifo_init(&lifo_timeout[1]); nano_fifo_init(&timeout_order_fifo); nano_fifo_init(&scratch_q_packets_fifo); for (ii = 0; ii < NUM_SCRATCH_Q_PACKETS; ii++) { scratch_q_packets[ii].data_if_needed = (void *)ii; nano_task_fifo_put(&scratch_q_packets_fifo, &scratch_q_packets[ii]); } /* test nano_task_lifo_get() with timeout */ timeout = 10; orig_ticks = sys_tick_get(); packet = nano_task_lifo_get(&lifo_timeout[0], timeout); if (packet) { TC_ERROR(" *** timeout of %d did not time out.\n", timeout); return TC_FAIL; } if ((sys_tick_get() - orig_ticks) < timeout) { TC_ERROR(" *** task did not wait long enough on timeout of %d.\n", timeout); return TC_FAIL; } /* test nano_task_lifo_get() with timeout of 0 */ packet = nano_task_lifo_get(&lifo_timeout[0], 0); if (packet) { TC_ERROR(" *** timeout of 0 did not time out.\n"); return TC_FAIL; } /* test nano_task_lifo_get() with timeout > 0 */ TC_PRINT("test nano_task_lifo_get() with timeout > 0\n"); timeout = 3; orig_ticks = sys_tick_get(); packet = nano_task_lifo_get(&lifo_timeout[0], timeout); if (packet) { TC_ERROR(" *** timeout of %d did not time out.\n", timeout); return TC_FAIL; } if (!is_timeout_in_range(orig_ticks, timeout)) { return TC_FAIL; } TC_PRINT("nano_task_lifo_get() timed out as expected\n"); /* * test nano_task_lifo_get() with a timeout and fiber that puts * data on the lifo on time */ timeout = 5; orig_ticks = sys_tick_get(); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_put_timeout, (int)&lifo_timeout[0], timeout, FIBER_PRIORITY, 0); packet = nano_task_lifo_get(&lifo_timeout[0], (int)(timeout + 5)); if (!packet) { TC_ERROR(" *** data put in time did not return valid pointer.\n"); return TC_FAIL; } put_scratch_packet(packet); if (!is_timeout_in_range(orig_ticks, timeout)) { return TC_FAIL; } TC_PRINT("nano_task_lifo_get() got lifo in time, as expected\n"); /* * test nano_task_lifo_get() with TICKS_NONE and no data * unavailable. */ if (nano_task_lifo_get(&lifo_timeout[0], TICKS_NONE)) { TC_ERROR("task with TICKS_NONE got data, but shouldn't have\n"); return TC_FAIL; } TC_PRINT("task with TICKS_NONE did not get data, as expected\n"); /* * test nano_task_lifo_get() with TICKS_NONE and some data * available. */ scratch_packet = get_scratch_packet(); nano_task_lifo_put(&lifo_timeout[0], scratch_packet); if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_NONE)) { TC_ERROR("task with TICKS_NONE did not get available data\n"); return TC_FAIL; } put_scratch_packet(scratch_packet); TC_PRINT("task with TICKS_NONE got available data, as expected\n"); /* * test nano_task_lifo_get() with TICKS_UNLIMITED and the * data available. */ TC_PRINT("Trying to take available data with TICKS_UNLIMITED:\n" " will hang the test if it fails.\n"); scratch_packet = get_scratch_packet(); nano_task_lifo_put(&lifo_timeout[0], scratch_packet); if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_UNLIMITED)) { TC_ERROR(" *** This will never be hit!!! .\n"); return TC_FAIL; } put_scratch_packet(scratch_packet); TC_PRINT("task with TICKS_UNLIMITED got available data, as expected\n"); /* test fiber with timeout of TICKS_NONE not getting data on empty lifo */ task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0); if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 0) { TC_ERROR(" *** fiber should not have obtained the data.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_NONE did not get data, as expected\n"); /* test fiber with timeout of TICKS_NONE getting data when available */ scratch_packet = get_scratch_packet(); nano_task_lifo_put(&lifo_timeout[0], scratch_packet); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0); put_scratch_packet(scratch_packet); if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 1) { TC_ERROR(" *** fiber should have obtained the data.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_NONE got available data, as expected\n"); /* test fiber with TICKS_UNLIMITED timeout getting data when availalble */ scratch_packet = get_scratch_packet(); nano_task_lifo_put(&lifo_timeout[0], scratch_packet); task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_ticks_special_values, (int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0); put_scratch_packet(scratch_packet); if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) { TC_ERROR(" *** fiber should have run and filled the fifo.\n"); return TC_FAIL; } if (reply_packet.reply != 1) { TC_ERROR(" *** fiber should have obtained the data.\n"); return TC_FAIL; } TC_PRINT("fiber with TICKS_UNLIMITED got available data, as expected\n"); /* test multiple fibers pending on the same lifo with different timeouts */ test_data_size = ARRAY_SIZE(timeout_order_data); TC_PRINT("testing timeouts of %d fibers on same lifo\n", test_data_size); rv = test_multiple_fibers_pending(timeout_order_data, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not time out in the right order\n"); return TC_FAIL; } /* test mult. fibers pending on different lifos with different timeouts */ test_data_size = ARRAY_SIZE(timeout_order_data_mult_lifo); TC_PRINT("testing timeouts of %d fibers on different lifos\n", test_data_size); rv = test_multiple_fibers_pending(timeout_order_data_mult_lifo, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not time out in the right order\n"); return TC_FAIL; } /* * test multiple fibers pending on same lifo with different timeouts, but * getting the data in time, except the last one. */ test_data_size = ARRAY_SIZE(timeout_order_data); TC_PRINT("testing %d fibers timing out, but obtaining the data in time\n" "(except the last one, which times out)\n", test_data_size); rv = test_multiple_fibers_get_data(timeout_order_data, test_data_size); if (rv != TC_PASS) { TC_ERROR(" *** fibers did not get the data in the right order\n"); return TC_FAIL; } return TC_PASS; }
void main(void) { void *pData; /* pointer to FIFO object get from the queue */ int count = 0; /* counter */ TC_START("Test Nanokernel FIFO"); /* Initialize the FIFO queues and semaphore */ initNanoObjects(); /* Create and start the three (3) fibers. */ task_fiber_start(&fiberStack1[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber1, 0, 0, 7, 0); task_fiber_start(&fiberStack2[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber2, 0, 0, 7, 0); task_fiber_start(&fiberStack3[0], FIBER_STACKSIZE, (nano_fiber_entry_t) fiber3, 0, 0, 7, 0); /* * The three fibers have each blocked on a different semaphore. Giving * the semaphore nanoSemObjX will unblock fiberX (where X = {1, 2, 3}). * * Activate fibers #1 and #2. They will each block on nanoFifoObj. */ nano_task_sem_give(&nanoSemObj1); nano_task_sem_give(&nanoSemObj2); /* Put two items into <nanoFifoObj> to unblock fibers #1 and #2. */ nano_task_fifo_put(&nanoFifoObj, pPutList1[0]); /* Wake fiber1 */ nano_task_fifo_put(&nanoFifoObj, pPutList1[1]); /* Wake fiber2 */ /* Activate fiber #3 */ nano_task_sem_give(&nanoSemObj3); /* * All three fibers should be blocked on their semaphores. Put data into * <nanoFifoObj2>. Fiber #3 will read it after it is reactivated. */ nano_task_fifo_put(&nanoFifoObj2, pPutList2[0]); nano_task_sem_give(&nanoSemObj3); /* Reactivate fiber #3 */ for (int i = 0; i < 4; i++) { pData = nano_task_fifo_get(&nanoFifoObj2, TICKS_UNLIMITED); if (pData != pPutList2[i]) { TC_ERROR("nano_task_fifo_get() expected 0x%x, got 0x%x\n", pPutList2[i], pData); goto exit; } } /* Add items to <nanoFifoObj> for fiber #2 */ for (int i = 0; i < 4; i++) { nano_task_fifo_put(&nanoFifoObj, pPutList1[i]); } nano_task_sem_give(&nanoSemObj2); /* Activate fiber #2 */ /* Wait for fibers to finish */ nano_task_sem_take(&nanoSemObjTask, TICKS_UNLIMITED); if (retCode == TC_FAIL) { goto exit; } /* * Entries in the FIFO queue have to be unique. * Put data to queue. */ TC_PRINT("Test Task FIFO Put\n"); TC_PRINT("\nTASK FIFO Put Order: "); for (int i = 0; i < NUM_FIFO_ELEMENT; i++) { nano_task_fifo_put(&nanoFifoObj, pPutList1[i]); TC_PRINT(" %p,", pPutList1[i]); } TC_PRINT("\n"); PRINT_LINE; nano_task_sem_give(&nanoSemObj1); /* Activate fiber1 */ if (retCode == TC_FAIL) { goto exit; } /* * Wait for fiber1 to complete execution. (Using a semaphore gives * the fiber the freedom to do blocking-type operations if it wants to.) */ nano_task_sem_take(&nanoSemObjTask, TICKS_UNLIMITED); TC_PRINT("Test Task FIFO Get\n"); /* Get all FIFOs */ while ((pData = nano_task_fifo_get(&nanoFifoObj, TICKS_NONE)) != NULL) { TC_PRINT("TASK FIFO Get: count = %d, ptr is %p\n", count, pData); if ((count >= NUM_FIFO_ELEMENT) || (pData != pPutList2[count])) { TCERR1(count); retCode = TC_FAIL; goto exit; } count++; } /* Test FIFO Get Wait interfaces*/ testTaskFifoGetW(); PRINT_LINE; testIsrFifoFromTask(); PRINT_LINE; /* test timeouts */ if (test_fifo_timeout() != TC_PASS) { retCode = TC_FAIL; goto exit; } PRINT_LINE; exit: TC_END_RESULT(retCode); TC_END_REPORT(retCode); }
void testFiberInit(void) { nano_sem_init(&fiberSem); task_fiber_start(fiberStack, FIBER_STACK_SIZE, (nano_fiber_entry_t)testFiberEntry, 0, 0, FIBER_PRIORITY, 0); }
static int test_timeout(void) { int32_t timeout; int rv; int ii; struct timeout_order_data *data; /* * sys_thread_busy_wait() is currently unsupported for ARM */ #ifndef CONFIG_ARM /* test sys_thread_busy_wait() */ TC_PRINT("Testing sys_thread_busy_wait()\n"); timeout = 2; task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_busy_wait, (int)timeout, 0, FIBER_PRIORITY, 0); rv = nano_task_sem_take(&reply_timeout, timeout + 2); if (!rv) { rv = TC_FAIL; TC_ERROR(" *** task timed out waiting for sys_thread_busy_wait()\n"); return TC_FAIL; } #endif /* CONFIG_ARM */ /* test fiber_sleep() */ TC_PRINT("Testing fiber_sleep()\n"); timeout = 5; task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE, test_fiber_sleep, (int)timeout, 0, FIBER_PRIORITY, 0); rv = nano_task_sem_take(&reply_timeout, timeout + 5); if (!rv) { rv = TC_FAIL; TC_ERROR(" *** task timed out waiting for fiber on fiber_sleep().\n"); return TC_FAIL; } /* test fiber_delayed_start() without cancellation */ TC_PRINT("Testing fiber_delayed_start() without cancellation\n"); for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) { (void)task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE, delayed_fiber, ii, 0, 5, 0, timeout_order_data[ii].timeout); } for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) { data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS); if (!data) { TC_ERROR(" *** timeout while waiting for delayed fiber\n"); return TC_FAIL; } if (data->timeout_order != ii) { TC_ERROR(" *** wrong delayed fiber ran (got %d, expected %d)\n", data->timeout_order, ii); return TC_FAIL; } TC_PRINT(" got fiber (q order: %d, t/o: %d) as expected\n", data->q_order, data->timeout); } /* ensure no more fibers fire */ data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS); if (data) { TC_ERROR(" *** got something on the fifo, but shouldn't have...\n"); return TC_FAIL; } /* test fiber_delayed_start() with cancellation */ TC_PRINT("Testing fiber_delayed_start() with cancellations\n"); int cancellations[] = {0, 3, 4, 6}; int num_cancellations = ARRAY_SIZE(cancellations); int next_cancellation = 0; void *delayed_fibers[NUM_TIMEOUT_FIBERS]; for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) { delayed_fibers[ii] = task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE, delayed_fiber, ii, 0, 5, 0, timeout_order_data[ii].timeout); } for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) { int jj; if (ii == cancellations[next_cancellation]) { TC_PRINT(" cancelling [q order: %d, t/o: %d, t/o order: %d]\n", timeout_order_data[ii].q_order, timeout_order_data[ii].timeout, ii); for (jj = 0; jj < NUM_TIMEOUT_FIBERS; jj++) { if (timeout_order_data[jj].timeout_order == ii) { break; } } task_fiber_delayed_start_cancel(delayed_fibers[jj]); ++next_cancellation; continue; } data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TEN_INTERVALS); if (!data) { TC_ERROR(" *** timeout while waiting for delayed fiber\n"); return TC_FAIL; } if (data->timeout_order != ii) { TC_ERROR(" *** wrong delayed fiber ran (got %d, expected %d)\n", data->timeout_order, ii); return TC_FAIL; } TC_PRINT(" got (q order: %d, t/o: %d, t/o order %d) as expected\n", data->q_order, data->timeout); } if (num_cancellations != next_cancellation) { TC_ERROR(" *** wrong number of cancellations (expected %d, got %d\n", num_cancellations, next_cancellation); return TC_FAIL; } /* ensure no more fibers fire */ data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS); if (data) { TC_ERROR(" *** got something on the fifo, but shouldn't have...\n"); return TC_FAIL; } return TC_PASS; }