Morse Micro IoT SDK  2.13.1
test_os.c
1/*
2 * Copyright 2023 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include "porting_assistant.h"
8
9TEST_STEP(test_step_os_malloc, "Memory allocation")
10{
11 void *buf = mmosal_malloc(1560);
12 if (buf == NULL)
13 {
14 TEST_LOG_APPEND(
15 "Failed to allocate 1560 bytes. Check that your heap is configured correctly\n\n");
16 return TEST_FAILED;
17 }
19 return TEST_PASSED;
20}
21
22TEST_STEP(test_step_os_realloc, "Memory reallocation")
23{
24 enum constants
25 {
26 FIRST_ALLOCATION_SIZE = 100,
27 REALLOCATION_SIZE = 200,
28 };
29
30 uint8_t *buf = (uint8_t *)mmosal_malloc(FIRST_ALLOCATION_SIZE);
31 if (buf == NULL)
32 {
33 TEST_LOG_APPEND(
34 "Failed to allocate %d bytes. Check that your heap is configured correctly\n\n",
35 FIRST_ALLOCATION_SIZE);
36 return TEST_FAILED_NON_CRITICAL;
37 }
38 memset(buf, 0xc0, FIRST_ALLOCATION_SIZE);
39
40 uint8_t *buf1 = (uint8_t *)mmosal_realloc(buf, REALLOCATION_SIZE);
41 if (buf1 == NULL)
42 {
43 TEST_LOG_APPEND("Failed to reallocate %d bytes. Check that your heap supports realloc\n\n",
44 REALLOCATION_SIZE);
45 return TEST_FAILED_NON_CRITICAL;
46 }
47
48 /* Verify the reallocated memory contains the contents of the original block. */
49 unsigned ii;
50 for (ii = 0; ii < FIRST_ALLOCATION_SIZE; ii++)
51 {
52 if (buf1[ii] != 0xc0)
53 {
54 TEST_LOG_APPEND("Reallocated block contents mismatch at offset %u\n\n", ii);
55 return TEST_FAILED_NON_CRITICAL;
56 }
57 }
58
59 mmosal_free(buf1);
60 return TEST_PASSED;
61}
62
63static void test_func()
64{
65 // Do some work
66 return;
67}
68
69TEST_STEP(test_step_os_task_creation, "Task creation")
70{
71 struct mmosal_task *task_handle =
72 mmosal_task_create(test_func, NULL, MMOSAL_TASK_PRI_NORM, 64, "Test Task");
73 if (task_handle == NULL)
74 {
75 TEST_LOG_APPEND("mmosal_task_create() returned NULL; expected a task handle.\n\n");
76 return TEST_FAILED;
77 }
78
79 return TEST_PASSED;
80}
81
82TEST_STEP(test_step_os_active_context, "Check app run from OS thread")
83{
84 struct mmosal_task *task_handle = mmosal_task_get_active();
85
86 if (task_handle == NULL)
87 {
88 TEST_LOG_APPEND("Test failed: Porting Assistant relies on OS features such as task "
89 "pre-emption for the remaining tests.\n\n");
90
91 TEST_LOG_APPEND(
92 "Please ensure Porting Assistant's app_init() is launched as a task, and\n");
93 TEST_LOG_APPEND("that your port starts its task scheduler.\n\n");
94
95 TEST_LOG_APPEND("For example, on a FreeRTOS port this would use xTaskCreate() and "
96 "vTaskStartScheduler().\n\n");
97
98 TEST_LOG_APPEND(
99 "See mmosal_main() and mmosal_task_create() from the provided EKH05 port as\n");
100 TEST_LOG_APPEND("a reference (review mmosal_shim_freertos.c).\n\n");
101 return TEST_FAILED;
102 }
103
104 TEST_LOG_APPEND("Test passed, running in %s\n", mmosal_task_name());
105
106 return TEST_PASSED;
107}
108
109TEST_STEP(test_step_os_time, "Passage of time")
110{
111 uint32_t start_time = mmosal_get_time_ms();
113 uint32_t end_time = mmosal_get_time_ms();
114
115 int32_t delta = (int32_t)(end_time - start_time);
116 if (delta < 49 || delta > 51)
117 {
118 TEST_LOG_APPEND("Time delta (%ld ms) did not match sleep time (50 ms)\n\n", delta);
119 return TEST_FAILED;
120 }
121
122 return TEST_PASSED;
123}
124
127enum task_state
128{
129 TASK_NOT_STARTED,
130 TASK_STARTED,
131 TASK_TERMINATING,
132 TASK_ERROR_GET_ACTIVE_INVALID,
133};
134
136static volatile enum task_state task_state = TASK_NOT_STARTED;
138static struct mmosal_task *volatile task_handle;
139
141static void new_task_main(void *arg)
142{
143 (void)arg;
144
145 task_state = TASK_STARTED;
146
147 /* Sleep for 10 ms; this should yield the task. */
149
150 /* Verify mmosal_task_get_active() returns the correct task handle. */
151 if (mmosal_task_get_active() != task_handle)
152 {
153 task_state = TASK_ERROR_GET_ACTIVE_INVALID;
154 return;
155 }
156
157 task_state = TASK_TERMINATING;
158
159 /* Delete self */
160 mmosal_task_delete(NULL);
161}
162
163TEST_STEP(test_step_os_task_preemption, "Task preemption")
164{
165 task_handle = mmosal_task_create(new_task_main, NULL, MMOSAL_TASK_PRI_HIGH, 512, "Test Task");
166 if (task_handle == NULL)
167 {
168 TEST_LOG_APPEND("mmosal_task_create() returned NULL; expected a task handle.\n\n");
169 return TEST_FAILED_NON_CRITICAL;
170 }
171
172 /*
173 * The newly created task should be higher priority. Therefore the following code should
174 * not run until after the task yields.
175 */
176 if (task_state != TASK_STARTED)
177 {
178 TEST_LOG_APPEND("The task created with mmosal_task_create() did not run.\n\n");
179 return TEST_FAILED_NON_CRITICAL;
180 }
181
182 /* Allow some time for the task to wake up. */
184
185 switch (task_state)
186 {
187 case TASK_TERMINATING:
188 break;
189
190 case TASK_ERROR_GET_ACTIVE_INVALID:
191 TEST_LOG_APPEND("mmosal_task_get_active() did not return the correct task handle.\n\n");
192 return TEST_FAILED_NON_CRITICAL;
193
194 default:
195 TEST_LOG_APPEND("Task in unexpected state %d.\n\n", task_state);
196 return TEST_FAILED_NON_CRITICAL;
197 }
198
199 return TEST_PASSED;
200}
#define mmosal_malloc(size)
Allocate memory of the given size and return a pointer to it (malloc).
Definition: mmosal.h:170
#define mmosal_realloc(ptr, size)
Equivalent of standard library realloc().
Definition: mmosal.h:190
void mmosal_free(void *p)
Free the given memory allocation.
struct mmosal_task * mmosal_task_create(mmosal_task_fn_t task_fn, void *argument, enum mmosal_task_priority priority, unsigned stack_size_u32, const char *name)
Create a new task.
struct mmosal_task * mmosal_task_get_active(void)
Get the handle of the active task.
const char * mmosal_task_name(void)
Get the name of the running task.
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
void mmosal_task_delete(struct mmosal_task *task)
Delete the given task.
@ MMOSAL_TASK_PRI_HIGH
High priority.
Definition: mmosal.h:260
@ MMOSAL_TASK_PRI_NORM
Normal priority.
Definition: mmosal.h:258
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
static unsigned char buf[1024]
Statically allocated buffer for MQTT.
Definition: mqttdemo.c:153
const struct test_step test_step_os_malloc
Test definition.
const struct test_step test_step_os_active_context
Test definition.
const struct test_step test_step_os_task_preemption
Test definition.
const struct test_step test_step_os_realloc
Test definition.
const struct test_step test_step_os_time
Test definition.
const struct test_step test_step_os_task_creation
Test definition.