BA / Mbed OS BaBoRo1
Committer:
borlanic
Date:
Thu Mar 29 07:02:09 2018 +0000
Revision:
0:380207fcb5c1
Encoder, IMU --> OK; Controller --> in bearbeitung

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:380207fcb5c1 1 /* mbed Microcontroller Library
borlanic 0:380207fcb5c1 2 * Copyright (c) 2017 ARM Limited
borlanic 0:380207fcb5c1 3 *
borlanic 0:380207fcb5c1 4 * Licensed under the Apache License, Version 2.0 (the "License");
borlanic 0:380207fcb5c1 5 * you may not use this file except in compliance with the License.
borlanic 0:380207fcb5c1 6 * You may obtain a copy of the License at
borlanic 0:380207fcb5c1 7 *
borlanic 0:380207fcb5c1 8 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:380207fcb5c1 9 *
borlanic 0:380207fcb5c1 10 * Unless required by applicable law or agreed to in writing, software
borlanic 0:380207fcb5c1 11 * distributed under the License is distributed on an "AS IS" BASIS,
borlanic 0:380207fcb5c1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:380207fcb5c1 13 * See the License for the specific language governing permissions and
borlanic 0:380207fcb5c1 14 * limitations under the License.
borlanic 0:380207fcb5c1 15 */
borlanic 0:380207fcb5c1 16 #include "mbed.h"
borlanic 0:380207fcb5c1 17 #include "greentea-client/test_env.h"
borlanic 0:380207fcb5c1 18 #include "utest/utest.h"
borlanic 0:380207fcb5c1 19 #include "unity/unity.h"
borlanic 0:380207fcb5c1 20
borlanic 0:380207fcb5c1 21
borlanic 0:380207fcb5c1 22 #if defined(MBED_RTOS_SINGLE_THREAD)
borlanic 0:380207fcb5c1 23 #error [NOT_SUPPORTED] test not supported
borlanic 0:380207fcb5c1 24 #endif
borlanic 0:380207fcb5c1 25
borlanic 0:380207fcb5c1 26 using utest::v1::Case;
borlanic 0:380207fcb5c1 27
borlanic 0:380207fcb5c1 28 extern uint32_t mbed_heap_size;
borlanic 0:380207fcb5c1 29 static const int test_timeout = 25;
borlanic 0:380207fcb5c1 30 volatile bool thread_should_continue = true;
borlanic 0:380207fcb5c1 31 #define NUM_THREADS 4
borlanic 0:380207fcb5c1 32 #define THREAD_MALLOC_SIZE 100
borlanic 0:380207fcb5c1 33
borlanic 0:380207fcb5c1 34 #if defined(__CORTEX_A9)
borlanic 0:380207fcb5c1 35 #define THREAD_STACK_SIZE 512
borlanic 0:380207fcb5c1 36 #else
borlanic 0:380207fcb5c1 37 #define THREAD_STACK_SIZE 256
borlanic 0:380207fcb5c1 38 #endif
borlanic 0:380207fcb5c1 39
borlanic 0:380207fcb5c1 40
borlanic 0:380207fcb5c1 41 void task_using_malloc(void)
borlanic 0:380207fcb5c1 42 {
borlanic 0:380207fcb5c1 43 void *data = NULL;
borlanic 0:380207fcb5c1 44
borlanic 0:380207fcb5c1 45 while (thread_should_continue) {
borlanic 0:380207fcb5c1 46 // Repeatedly allocate and free memory
borlanic 0:380207fcb5c1 47 data = malloc(THREAD_MALLOC_SIZE);
borlanic 0:380207fcb5c1 48 TEST_ASSERT_NOT_NULL(data);
borlanic 0:380207fcb5c1 49
borlanic 0:380207fcb5c1 50 // test whole allocated memory
borlanic 0:380207fcb5c1 51 memset(data, 0, THREAD_MALLOC_SIZE);
borlanic 0:380207fcb5c1 52
borlanic 0:380207fcb5c1 53 free(data);
borlanic 0:380207fcb5c1 54 }
borlanic 0:380207fcb5c1 55 }
borlanic 0:380207fcb5c1 56
borlanic 0:380207fcb5c1 57 /** Test for multithreaded heap allocations
borlanic 0:380207fcb5c1 58
borlanic 0:380207fcb5c1 59 Given multiple threads are started in parallel
borlanic 0:380207fcb5c1 60 When each of the threads allocate memory
borlanic 0:380207fcb5c1 61 Then the memory allocation succeed and @a malloc return valid memory
borlanic 0:380207fcb5c1 62 */
borlanic 0:380207fcb5c1 63 void test_multithread_allocation(void)
borlanic 0:380207fcb5c1 64 {
borlanic 0:380207fcb5c1 65 // static stack for threads to reduce heap usage on devices with small RAM
borlanic 0:380207fcb5c1 66 // and eliminate run out of heap memory problem
borlanic 0:380207fcb5c1 67 uint8_t stack[NUM_THREADS][THREAD_STACK_SIZE];
borlanic 0:380207fcb5c1 68
borlanic 0:380207fcb5c1 69 bool thread_alloc_failure = false;
borlanic 0:380207fcb5c1 70 Thread *thread_list[NUM_THREADS];
borlanic 0:380207fcb5c1 71 int test_time = 20;
borlanic 0:380207fcb5c1 72
borlanic 0:380207fcb5c1 73 // Allocate threads for the test
borlanic 0:380207fcb5c1 74 for (int i = 0; i < NUM_THREADS; i++) {
borlanic 0:380207fcb5c1 75 thread_list[i] = new Thread(osPriorityNormal, THREAD_STACK_SIZE, stack[i]);
borlanic 0:380207fcb5c1 76 if (NULL == thread_list[i]) {
borlanic 0:380207fcb5c1 77 thread_alloc_failure = true;
borlanic 0:380207fcb5c1 78 } else {
borlanic 0:380207fcb5c1 79 thread_list[i]->start(task_using_malloc);
borlanic 0:380207fcb5c1 80 }
borlanic 0:380207fcb5c1 81 }
borlanic 0:380207fcb5c1 82
borlanic 0:380207fcb5c1 83 // Give the test time to run
borlanic 0:380207fcb5c1 84 while (test_time--) {
borlanic 0:380207fcb5c1 85 Thread::wait(1000);
borlanic 0:380207fcb5c1 86 }
borlanic 0:380207fcb5c1 87
borlanic 0:380207fcb5c1 88 // Join and delete all threads
borlanic 0:380207fcb5c1 89 thread_should_continue = false;
borlanic 0:380207fcb5c1 90 for (int i = 0; i < NUM_THREADS; i++) {
borlanic 0:380207fcb5c1 91 if (NULL != thread_list[i]) {
borlanic 0:380207fcb5c1 92 thread_list[i]->join();
borlanic 0:380207fcb5c1 93 delete thread_list[i];
borlanic 0:380207fcb5c1 94 thread_list[i] = NULL;
borlanic 0:380207fcb5c1 95 }
borlanic 0:380207fcb5c1 96 }
borlanic 0:380207fcb5c1 97 TEST_ASSERT_FALSE(thread_alloc_failure);
borlanic 0:380207fcb5c1 98 }
borlanic 0:380207fcb5c1 99
borlanic 0:380207fcb5c1 100 /** Test for large heap allocation
borlanic 0:380207fcb5c1 101
borlanic 0:380207fcb5c1 102 Given a heap of size mbed_heap_size
borlanic 0:380207fcb5c1 103 When try to allocate memory of size mbed_heap_size/5 (20% of whole heap)
borlanic 0:380207fcb5c1 104 Then the memory is allocated and @a malloc return valid memory
borlanic 0:380207fcb5c1 105 */
borlanic 0:380207fcb5c1 106 void test_big_allocation(void)
borlanic 0:380207fcb5c1 107 {
borlanic 0:380207fcb5c1 108 const uint32_t alloc_size = mbed_heap_size / 5;
borlanic 0:380207fcb5c1 109 void *data = NULL;
borlanic 0:380207fcb5c1 110
borlanic 0:380207fcb5c1 111 data = malloc(alloc_size);
borlanic 0:380207fcb5c1 112 TEST_ASSERT_NOT_NULL(data);
borlanic 0:380207fcb5c1 113
borlanic 0:380207fcb5c1 114 // test whole allocated memory
borlanic 0:380207fcb5c1 115 memset(data, 0, alloc_size);
borlanic 0:380207fcb5c1 116
borlanic 0:380207fcb5c1 117 free(data);
borlanic 0:380207fcb5c1 118 }
borlanic 0:380207fcb5c1 119
borlanic 0:380207fcb5c1 120 /** Test if allocation of zero size does not cause any undefined behaviour
borlanic 0:380207fcb5c1 121
borlanic 0:380207fcb5c1 122 Given a heap
borlanic 0:380207fcb5c1 123 When try to allocate memory of size 0
borlanic 0:380207fcb5c1 124 Then the return value of @a malloc depends on the particular library implementation
borlanic 0:380207fcb5c1 125 (NULL or smallest possible allocation) and no undefined behaviour happens
borlanic 0:380207fcb5c1 126
borlanic 0:380207fcb5c1 127 @note If allocation size is zero, the return value depends on the particular library implementation
borlanic 0:380207fcb5c1 128 (it may or may not be a null pointer), but the returned pointer shall not be dereferenced
borlanic 0:380207fcb5c1 129 */
borlanic 0:380207fcb5c1 130 void test_zero_allocation(void)
borlanic 0:380207fcb5c1 131 {
borlanic 0:380207fcb5c1 132 void *data = NULL;
borlanic 0:380207fcb5c1 133
borlanic 0:380207fcb5c1 134 data = malloc(0);
borlanic 0:380207fcb5c1 135 if(data != NULL) {
borlanic 0:380207fcb5c1 136 free(data);
borlanic 0:380207fcb5c1 137 }
borlanic 0:380207fcb5c1 138 TEST_ASSERT_MESSAGE(true, "malloc(0) succeed - no undefined behaviour happens");
borlanic 0:380207fcb5c1 139 }
borlanic 0:380207fcb5c1 140
borlanic 0:380207fcb5c1 141 /** Test if free on NULL pointer does not cause any undefined behaviour
borlanic 0:380207fcb5c1 142
borlanic 0:380207fcb5c1 143 Given a NULL pointer
borlanic 0:380207fcb5c1 144 When try to free it
borlanic 0:380207fcb5c1 145 Then the function @a free does nothing and no undefined behaviour happens
borlanic 0:380207fcb5c1 146 */
borlanic 0:380207fcb5c1 147 void test_null_free(void)
borlanic 0:380207fcb5c1 148 {
borlanic 0:380207fcb5c1 149 void *data = NULL;
borlanic 0:380207fcb5c1 150 free(data);
borlanic 0:380207fcb5c1 151
borlanic 0:380207fcb5c1 152 TEST_ASSERT_MESSAGE(true, "free(NULL) succeed - no undefined behaviour happens");
borlanic 0:380207fcb5c1 153 }
borlanic 0:380207fcb5c1 154
borlanic 0:380207fcb5c1 155 // Test cases
borlanic 0:380207fcb5c1 156 Case cases[] = {
borlanic 0:380207fcb5c1 157 Case("Test 0 size allocation", test_zero_allocation),
borlanic 0:380207fcb5c1 158 Case("Test NULL pointer free", test_null_free),
borlanic 0:380207fcb5c1 159 Case("Test multithreaded allocations", test_multithread_allocation),
borlanic 0:380207fcb5c1 160 Case("Test large allocation", test_big_allocation)
borlanic 0:380207fcb5c1 161 };
borlanic 0:380207fcb5c1 162
borlanic 0:380207fcb5c1 163 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
borlanic 0:380207fcb5c1 164 {
borlanic 0:380207fcb5c1 165 GREENTEA_SETUP(test_timeout, "timing_drift_auto");
borlanic 0:380207fcb5c1 166 return utest::v1::greentea_test_setup_handler(number_of_cases);
borlanic 0:380207fcb5c1 167 }
borlanic 0:380207fcb5c1 168
borlanic 0:380207fcb5c1 169 utest::v1::Specification specification(greentea_test_setup, cases);
borlanic 0:380207fcb5c1 170
borlanic 0:380207fcb5c1 171 int main()
borlanic 0:380207fcb5c1 172 {
borlanic 0:380207fcb5c1 173 return !utest::v1::Harness::run(specification);
borlanic 0:380207fcb5c1 174 }