Software APIs
example_concurrency_test.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 /**
6  * This example serves as a starting point for writing software top-level
7  * concurrency tests that use the OpenTitan Test Framework (OTTF), and run at
8  * the flash boot stage. This example is intended to be copied and modified
9  * according to the instructions below.
10  *
11  * This example demonstrates a concurrency test that spawns three FreeRTOS
12  * tasks, in addition to the `test_main` task. Each task is defined using a
13  * separate function that never returns, and deletes itself after executing its
14  * code. Since the priorities of each task are the same, yet higher than the
15  * priority of the "test_main" task, calling `ottf_task_yield()` will switch
16  * control flow between these tasks, until each task deletes itself. Then, the
17  * `test_main` task will continue executing, returning `true` when the overall
18  * test passes, triggering the OTTF to signal test execution has completed.
19  *
20  * Additionally, an example assertion failure is commented out below in `task_3`
21  * to demonstrate how the test will terminate execution immediately upon
22  * encountering said behavior in any task. The test runner (opentitantool) on
23  * Verilator and FPGA platforms is monitoring the UART for a failure message
24  * that gets printed immediately upon an assertion failure. It terminates the
25  * test immediately upon seeing said message. Similarly, in DV, the testbench is
26  * monitoring a specific memory location that gets written to on an assertion
27  * failure.
28  */
29 
31 #include "sw/device/lib/testing/test_framework/check.h"
32 #include "sw/device/lib/testing/test_framework/ottf_macros.h"
34 
35 OTTF_DEFINE_TEST_CONFIG(.enable_concurrency = true);
36 
37 static void task_1(void *task_parameters) {
38  // ***************************************************************************
39  // Place test code below.
40  // ***************************************************************************
41  LOG_INFO("Executing %s ...", ottf_task_get_self_name());
43  LOG_INFO("Continuing to execute %s ...", ottf_task_get_self_name());
44 
45  // ***************************************************************************
46  // Delete the current task and never return.
47  // ***************************************************************************
48  OTTF_TASK_DELETE_SELF_OR_DIE;
49 }
50 
51 static void task_2(void *task_parameters) {
52  // ***************************************************************************
53  // Place test code below.
54  // ***************************************************************************
55  LOG_INFO("Executing %s ...", ottf_task_get_self_name());
56 
57  // ***************************************************************************
58  // Delete the current task and never return.
59  // ***************************************************************************
60  OTTF_TASK_DELETE_SELF_OR_DIE;
61 }
62 
63 static void task_3(void *task_parameters) {
64  // ***************************************************************************
65  // Place test code below.
66  // ***************************************************************************
67  LOG_INFO("Executing %s ...", ottf_task_get_self_name());
68 
69  // ***************************************************************************
70  // Uncomment to see the effects of a failed assertion. Delete this when
71  // implementing a test.
72  // ***************************************************************************
73  // CHECK(false, "A failed assertion causes immediate test termination.");
74 
75  // ***************************************************************************
76  // Delete the current task and never return.
77  // ***************************************************************************
78  OTTF_TASK_DELETE_SELF_OR_DIE;
79 }
80 
81 bool test_main(void) {
82  // ***************************************************************************
83  // Create the FreeRTOS tasks that will comprise this test. Ensure the priority
84  // levels of each task are higher than the priority of the current "test_main"
85  // task, which is 0.
86  // ***************************************************************************
87  LOG_INFO("Starting to execute %s ...", ottf_task_get_self_name());
88  CHECK(ottf_task_create(task_1, "task_1", kOttfFreeRtosMinStackSize, 1));
89  CHECK(ottf_task_create(task_2, "task_2", kOttfFreeRtosMinStackSize, 1));
90  CHECK(ottf_task_create(task_3, "task_3", kOttfFreeRtosMinStackSize, 1));
91 
92  // ***************************************************************************
93  // Yield control flow to the highest priority task in the run queue. Since the
94  // tasks created above all have a higher priority level than the current
95  // "test_main" task, execution will not be returned to the current task until
96  // the above tasks have been deleted.
97  // ***************************************************************************
98  LOG_INFO("Yielding execution to another task.");
100 
101  // ***************************************************************************
102  // Return true if the test succeeds. Return false if it should fail.
103  // ***************************************************************************
104  return true;
105 }