takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed.h"
00017 #include "greentea-client/test_env.h"
00018 #include "utest/utest.h"
00019 #include "unity/unity.h"
00020 
00021 
00022 #if defined(MBED_RTOS_SINGLE_THREAD)
00023 #error [NOT_SUPPORTED] test not supported
00024 #endif
00025 
00026 #if !DEVICE_USTICKER
00027 #error [NOT_SUPPORTED] test not supported
00028 #endif
00029 
00030 using utest::v1::Case;
00031 
00032 extern uint32_t mbed_heap_size;
00033 static const int test_timeout = 25;
00034 volatile bool thread_should_continue = true;
00035 #define NUM_THREADS         4
00036 #define THREAD_MALLOC_SIZE  100
00037 
00038 #if defined(__CORTEX_A9)
00039 #define THREAD_STACK_SIZE   512
00040 #elif defined(__CORTEX_M23) || defined(__CORTEX_M33)
00041 #define THREAD_STACK_SIZE   512
00042 #elif defined(__ARM_FM)
00043 #define THREAD_STACK_SIZE   512
00044 #else
00045 #define THREAD_STACK_SIZE   256
00046 #endif
00047 
00048 
00049 void task_using_malloc(void)
00050 {
00051     void *data = NULL;
00052 
00053     while (thread_should_continue) {
00054         // Repeatedly allocate and free memory
00055         data = malloc(THREAD_MALLOC_SIZE);
00056         TEST_ASSERT_NOT_NULL(data);
00057 
00058         // test whole allocated memory
00059         memset(data, 0, THREAD_MALLOC_SIZE);
00060 
00061         free(data);
00062     }
00063 }
00064 
00065 /** Test for multithreaded heap allocations
00066 
00067     Given multiple threads are started in parallel
00068     When each of the threads allocate memory
00069     Then the memory allocation succeed and @a malloc return valid memory
00070  */
00071 void test_multithread_allocation(void)
00072 {
00073     // static stack for threads to reduce heap usage on devices with small RAM
00074     // and eliminate run out of heap memory problem
00075     uint8_t stack[NUM_THREADS][THREAD_STACK_SIZE];
00076 
00077     bool thread_alloc_failure = false;
00078     Thread *thread_list[NUM_THREADS];
00079     int test_time = 20;
00080 
00081     // Allocate threads for the test
00082     for (int i = 0; i < NUM_THREADS; i++) {
00083         thread_list[i] = new Thread(osPriorityNormal, THREAD_STACK_SIZE, stack[i]);
00084         if (NULL == thread_list[i]) {
00085             thread_alloc_failure = true;
00086         } else {
00087             thread_list[i]->start(task_using_malloc);
00088         }
00089     }
00090 
00091     // Give the test time to run
00092     while (test_time--) {
00093         Thread::wait(1000);
00094     }
00095 
00096     // Join and delete all threads
00097     thread_should_continue = false;
00098     for (int i = 0; i < NUM_THREADS; i++) {
00099         if (NULL != thread_list[i]) {
00100             thread_list[i]->join();
00101             delete thread_list[i];
00102             thread_list[i] = NULL;
00103         }
00104     }
00105     TEST_ASSERT_FALSE(thread_alloc_failure);
00106 }
00107 
00108 /** Test for large heap allocation
00109 
00110     Given a heap of size mbed_heap_size
00111     When try to allocate memory of size mbed_heap_size/5 (20% of whole heap)
00112     Then the memory is allocated and @a malloc return valid memory
00113  */
00114 void test_big_allocation(void)
00115 {
00116     const uint32_t alloc_size = mbed_heap_size / 5;
00117     void *data = NULL;
00118 
00119     data = malloc(alloc_size);
00120     TEST_ASSERT_NOT_NULL(data);
00121 
00122     // test whole allocated memory
00123     memset(data, 0, alloc_size);
00124 
00125     free(data);
00126 }
00127 
00128 /** Test if allocation of zero size does not cause any undefined behaviour
00129 
00130     Given a heap
00131     When try to allocate memory of size 0
00132     Then the return value of @a malloc depends on the particular library implementation
00133      (NULL or smallest possible allocation) and no undefined behaviour happens
00134 
00135     @note If allocation size is zero, the return value depends on the particular library implementation
00136     (it may or may not be a null pointer), but the returned pointer shall not be dereferenced
00137  */
00138 void test_zero_allocation(void)
00139 {
00140     void *data = NULL;
00141 
00142     data = malloc(0);
00143     if (data != NULL) {
00144         free(data);
00145     }
00146     TEST_ASSERT_MESSAGE(true, "malloc(0) succeed - no undefined behaviour happens");
00147 }
00148 
00149 /** Test if free on NULL pointer does not cause any undefined behaviour
00150 
00151     Given a NULL pointer
00152     When try to free it
00153     Then the function @a free does nothing and no undefined behaviour happens
00154  */
00155 void test_null_free(void)
00156 {
00157     void *data = NULL;
00158     free(data);
00159 
00160     TEST_ASSERT_MESSAGE(true, "free(NULL) succeed - no undefined behaviour happens");
00161 }
00162 
00163 // Test cases
00164 Case cases[] = {
00165     Case("Test 0 size allocation", test_zero_allocation),
00166     Case("Test NULL pointer free", test_null_free),
00167     Case("Test multithreaded allocations", test_multithread_allocation),
00168     Case("Test large allocation", test_big_allocation)
00169 };
00170 
00171 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
00172 {
00173     GREENTEA_SETUP(test_timeout, "timing_drift_auto");
00174     return utest::v1::greentea_test_setup_handler(number_of_cases);
00175 }
00176 
00177 utest::v1::Specification specification(greentea_test_setup, cases);
00178 
00179 int main()
00180 {
00181     return !utest::v1::Harness::run(specification);
00182 }