Development mbed library for MAX32630FTHR

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Dec 16 16:27:57 2016 +0000
Revision:
3:1198227e6421
Parent:
0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*
switches 0:5c4d7b2438d3 2 * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
switches 0:5c4d7b2438d3 3 * SPDX-License-Identifier: Apache-2.0
switches 0:5c4d7b2438d3 4 *
switches 0:5c4d7b2438d3 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
switches 0:5c4d7b2438d3 6 * not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 7 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 8 *
switches 0:5c4d7b2438d3 9 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 10 *
switches 0:5c4d7b2438d3 11 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
switches 0:5c4d7b2438d3 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 14 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 15 * limitations under the License.
switches 0:5c4d7b2438d3 16 */
switches 0:5c4d7b2438d3 17
switches 0:5c4d7b2438d3 18 #include "mbed.h"
switches 0:5c4d7b2438d3 19 #include "greentea-client/test_env.h"
switches 0:5c4d7b2438d3 20 #include "unity/unity.h"
switches 0:5c4d7b2438d3 21 #include "utest/utest.h"
switches 0:5c4d7b2438d3 22 #include "mbed_mem_trace.h"
switches 0:5c4d7b2438d3 23 #include <stdlib.h>
switches 0:5c4d7b2438d3 24 #include <stdio.h>
switches 0:5c4d7b2438d3 25 #include <stdarg.h>
switches 0:5c4d7b2438d3 26
switches 0:5c4d7b2438d3 27 #ifndef MBED_MEM_TRACING_ENABLED
switches 0:5c4d7b2438d3 28 #error [NOT_SUPPORTED] test not supported
switches 0:5c4d7b2438d3 29 #endif
switches 0:5c4d7b2438d3 30
switches 0:5c4d7b2438d3 31 using namespace utest::v1;
switches 0:5c4d7b2438d3 32
switches 0:5c4d7b2438d3 33 /******************************************************************************/
switches 0:5c4d7b2438d3 34 /* Helper functions and data structures */
switches 0:5c4d7b2438d3 35 /******************************************************************************/
switches 0:5c4d7b2438d3 36
switches 0:5c4d7b2438d3 37 // This structure keeps data about the various memory allocation operations,
switches 0:5c4d7b2438d3 38 // as traced by 'test_trace_cb' below.
switches 0:5c4d7b2438d3 39 #define TEST_MAX_MEMORY_OPS 10
switches 0:5c4d7b2438d3 40 // Trace results for all possible operations
switches 0:5c4d7b2438d3 41 typedef struct {
switches 0:5c4d7b2438d3 42 uint8_t op;
switches 0:5c4d7b2438d3 43 void *res;
switches 0:5c4d7b2438d3 44 union {
switches 0:5c4d7b2438d3 45 struct {
switches 0:5c4d7b2438d3 46 size_t arg_size;
switches 0:5c4d7b2438d3 47 } malloc_info;
switches 0:5c4d7b2438d3 48 struct {
switches 0:5c4d7b2438d3 49 void *arg_ptr;
switches 0:5c4d7b2438d3 50 size_t arg_size;
switches 0:5c4d7b2438d3 51 } realloc_info;
switches 0:5c4d7b2438d3 52 struct {
switches 0:5c4d7b2438d3 53 size_t arg_nmemb;
switches 0:5c4d7b2438d3 54 size_t arg_size;
switches 0:5c4d7b2438d3 55 } calloc_info;
switches 0:5c4d7b2438d3 56 struct {
switches 0:5c4d7b2438d3 57 void *arg_ptr;
switches 0:5c4d7b2438d3 58 } free_info;
switches 0:5c4d7b2438d3 59 };
switches 0:5c4d7b2438d3 60 } mem_trace_data_t;
switches 0:5c4d7b2438d3 61 // Memory operation statistics
switches 0:5c4d7b2438d3 62 typedef struct {
switches 0:5c4d7b2438d3 63 mem_trace_data_t op_data[TEST_MAX_MEMORY_OPS];
switches 0:5c4d7b2438d3 64 uint32_t total_ops;
switches 0:5c4d7b2438d3 65 bool invalid_op, overflow;
switches 0:5c4d7b2438d3 66 } stats_t;
switches 0:5c4d7b2438d3 67 static stats_t stats;
switches 0:5c4d7b2438d3 68
switches 0:5c4d7b2438d3 69 // Clear all the memory statistics
switches 0:5c4d7b2438d3 70 static void test_clear_stats() {
switches 0:5c4d7b2438d3 71 memset(&stats, 0, sizeof(stats));
switches 0:5c4d7b2438d3 72 }
switches 0:5c4d7b2438d3 73
switches 0:5c4d7b2438d3 74 // Memory tracer callback that records each operation in "stats" (above)
switches 0:5c4d7b2438d3 75 extern "C" void test_trace_cb(uint8_t op, void *res, void *caller, ...) {
switches 0:5c4d7b2438d3 76 va_list va;
switches 0:5c4d7b2438d3 77 mem_trace_data_t *pmem = stats.op_data + stats.total_ops;
switches 0:5c4d7b2438d3 78
switches 0:5c4d7b2438d3 79 if (stats.total_ops >= TEST_MAX_MEMORY_OPS) {
switches 0:5c4d7b2438d3 80 stats.overflow = true;
switches 0:5c4d7b2438d3 81 return;
switches 0:5c4d7b2438d3 82 }
switches 0:5c4d7b2438d3 83 va_start(va, caller);
switches 0:5c4d7b2438d3 84 pmem->op = op;
switches 0:5c4d7b2438d3 85 pmem->res = res;
switches 0:5c4d7b2438d3 86 switch(op) {
switches 0:5c4d7b2438d3 87 case MBED_MEM_TRACE_MALLOC:
switches 0:5c4d7b2438d3 88 pmem->malloc_info.arg_size = va_arg(va, size_t);
switches 0:5c4d7b2438d3 89 break;
switches 0:5c4d7b2438d3 90
switches 0:5c4d7b2438d3 91 case MBED_MEM_TRACE_REALLOC:
switches 0:5c4d7b2438d3 92 pmem->realloc_info.arg_ptr = va_arg(va, void *);
switches 0:5c4d7b2438d3 93 pmem->realloc_info.arg_size = va_arg(va, size_t);
switches 0:5c4d7b2438d3 94 break;
switches 0:5c4d7b2438d3 95
switches 0:5c4d7b2438d3 96 case MBED_MEM_TRACE_CALLOC:
switches 0:5c4d7b2438d3 97 pmem->calloc_info.arg_nmemb = va_arg(va, size_t);
switches 0:5c4d7b2438d3 98 pmem->calloc_info.arg_size = va_arg(va, size_t);
switches 0:5c4d7b2438d3 99 break;
switches 0:5c4d7b2438d3 100
switches 0:5c4d7b2438d3 101 case MBED_MEM_TRACE_FREE:
switches 0:5c4d7b2438d3 102 pmem->free_info.arg_ptr = va_arg(va, void *);
switches 0:5c4d7b2438d3 103 break;
switches 0:5c4d7b2438d3 104
switches 0:5c4d7b2438d3 105 default:
switches 0:5c4d7b2438d3 106 stats.invalid_op = true;
switches 0:5c4d7b2438d3 107 }
switches 0:5c4d7b2438d3 108 stats.total_ops ++;
switches 0:5c4d7b2438d3 109 va_end(va);
switches 0:5c4d7b2438d3 110 }
switches 0:5c4d7b2438d3 111
switches 0:5c4d7b2438d3 112 // Generic sanity checks for the tracer
switches 0:5c4d7b2438d3 113 static void check_sanity(uint32_t expected_ops) {
switches 0:5c4d7b2438d3 114 TEST_ASSERT_FALSE(stats.overflow);
switches 0:5c4d7b2438d3 115 TEST_ASSERT_FALSE(stats.invalid_op);
switches 0:5c4d7b2438d3 116 TEST_ASSERT_EQUAL_UINT32(stats.total_ops, expected_ops);
switches 0:5c4d7b2438d3 117 }
switches 0:5c4d7b2438d3 118
switches 0:5c4d7b2438d3 119 // Check a "malloc" operation
switches 0:5c4d7b2438d3 120 static void check_malloc_op(const mem_trace_data_t *p, void *expected_res, size_t expected_arg_size) {
switches 0:5c4d7b2438d3 121 TEST_ASSERT_EQUAL_UINT8(p->op, MBED_MEM_TRACE_MALLOC);
switches 0:5c4d7b2438d3 122 TEST_ASSERT_EQUAL_PTR(p->res, expected_res);
switches 0:5c4d7b2438d3 123 TEST_ASSERT_EQUAL_UINT32(p->malloc_info.arg_size, expected_arg_size);
switches 0:5c4d7b2438d3 124 }
switches 0:5c4d7b2438d3 125
switches 0:5c4d7b2438d3 126 // Check a "free" operation
switches 0:5c4d7b2438d3 127 static void check_free_op(const mem_trace_data_t *p, void *expected_arg_ptr) {
switches 0:5c4d7b2438d3 128 TEST_ASSERT_EQUAL_UINT8(p->op, MBED_MEM_TRACE_FREE);
switches 0:5c4d7b2438d3 129 TEST_ASSERT_EQUAL_PTR(p->free_info.arg_ptr, expected_arg_ptr);
switches 0:5c4d7b2438d3 130 }
switches 0:5c4d7b2438d3 131
switches 0:5c4d7b2438d3 132 // Check a "realloc" operation
switches 0:5c4d7b2438d3 133 static void check_realloc_op(const mem_trace_data_t *p, void *expected_res, void *expected_arg_ptr, size_t expected_arg_size) {
switches 0:5c4d7b2438d3 134 TEST_ASSERT_EQUAL_UINT8(p->op, MBED_MEM_TRACE_REALLOC);
switches 0:5c4d7b2438d3 135 TEST_ASSERT_EQUAL_PTR(p->res, expected_res);
switches 0:5c4d7b2438d3 136 TEST_ASSERT_EQUAL_UINT32(p->realloc_info.arg_ptr, expected_arg_ptr);
switches 0:5c4d7b2438d3 137 TEST_ASSERT_EQUAL_UINT32(p->realloc_info.arg_size, expected_arg_size);
switches 0:5c4d7b2438d3 138 }
switches 0:5c4d7b2438d3 139
switches 0:5c4d7b2438d3 140 // Check a "calloc" operation
switches 0:5c4d7b2438d3 141 static void check_calloc_op(const mem_trace_data_t *p, void *expected_res, size_t expected_arg_nmemb, size_t expected_arg_size) {
switches 0:5c4d7b2438d3 142 TEST_ASSERT_EQUAL_UINT8(p->op, MBED_MEM_TRACE_CALLOC);
switches 0:5c4d7b2438d3 143 TEST_ASSERT_EQUAL_PTR(p->res, expected_res);
switches 0:5c4d7b2438d3 144 TEST_ASSERT_EQUAL_UINT32(p->calloc_info.arg_nmemb, expected_arg_nmemb);
switches 0:5c4d7b2438d3 145 TEST_ASSERT_EQUAL_UINT32(p->calloc_info.arg_size, expected_arg_size);
switches 0:5c4d7b2438d3 146 }
switches 0:5c4d7b2438d3 147
switches 0:5c4d7b2438d3 148 /******************************************************************************/
switches 0:5c4d7b2438d3 149 /* Tests */
switches 0:5c4d7b2438d3 150 /******************************************************************************/
switches 0:5c4d7b2438d3 151
switches 0:5c4d7b2438d3 152 // Allocate a single buffer, then free it. Check that tracing matches the operations.
switches 0:5c4d7b2438d3 153 static void test_case_single_malloc_free() {
switches 0:5c4d7b2438d3 154 const size_t block_size = 126;
switches 0:5c4d7b2438d3 155 const mem_trace_data_t *pmem = stats.op_data;
switches 0:5c4d7b2438d3 156
switches 0:5c4d7b2438d3 157 test_clear_stats();
switches 0:5c4d7b2438d3 158 mbed_mem_trace_set_callback(test_trace_cb);
switches 0:5c4d7b2438d3 159 // Allocate a single memory block
switches 0:5c4d7b2438d3 160 void *p = malloc(block_size);
switches 0:5c4d7b2438d3 161 TEST_ASSERT_NOT_EQUAL(p, NULL);
switches 0:5c4d7b2438d3 162 // Free the memory block
switches 0:5c4d7b2438d3 163 free(p);
switches 0:5c4d7b2438d3 164 // Stop tracing
switches 0:5c4d7b2438d3 165 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 166 // Check tracer result
switches 0:5c4d7b2438d3 167 check_sanity(2);
switches 0:5c4d7b2438d3 168 check_malloc_op(pmem ++, p, block_size);
switches 0:5c4d7b2438d3 169 check_free_op(pmem, p);
switches 0:5c4d7b2438d3 170 }
switches 0:5c4d7b2438d3 171
switches 0:5c4d7b2438d3 172 // Test all memory operations (malloc, realloc, free, calloc)
switches 0:5c4d7b2438d3 173 static void test_case_all_memory_ops() {
switches 0:5c4d7b2438d3 174 const size_t malloc_size = 40, realloc_size = 80, nmemb = 25, size = 10;
switches 0:5c4d7b2438d3 175 const mem_trace_data_t *pmem = stats.op_data;
switches 0:5c4d7b2438d3 176
switches 0:5c4d7b2438d3 177 test_clear_stats();
switches 0:5c4d7b2438d3 178 mbed_mem_trace_set_callback(test_trace_cb);
switches 0:5c4d7b2438d3 179 // Allocate a single memory block, the realloc it
switches 0:5c4d7b2438d3 180 void *p_malloc = malloc(malloc_size);
switches 0:5c4d7b2438d3 181 TEST_ASSERT_NOT_EQUAL(p_malloc, NULL);
switches 0:5c4d7b2438d3 182 void *p_realloc = realloc(p_malloc, realloc_size);
switches 0:5c4d7b2438d3 183 TEST_ASSERT_NOT_EQUAL(p_realloc, NULL);
switches 0:5c4d7b2438d3 184 // Use calloc() now
switches 0:5c4d7b2438d3 185 void *p_calloc = calloc(nmemb, size);
switches 0:5c4d7b2438d3 186 //TEST_ASSERT_NOT_EQUAL(p_calloc, NULL);
switches 0:5c4d7b2438d3 187 // Free the realloc() pointer first, then the calloc() one
switches 0:5c4d7b2438d3 188 free(p_realloc);
switches 0:5c4d7b2438d3 189 free(p_calloc);
switches 0:5c4d7b2438d3 190 // Stop tracing
switches 0:5c4d7b2438d3 191 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 192 // Check tracer result
switches 0:5c4d7b2438d3 193 check_sanity(6);
switches 0:5c4d7b2438d3 194 check_malloc_op(pmem ++, p_malloc, malloc_size);
switches 0:5c4d7b2438d3 195 check_realloc_op(pmem ++, p_realloc, p_malloc, realloc_size);
switches 0:5c4d7b2438d3 196 // calloc() calls malloc() internally
switches 0:5c4d7b2438d3 197 check_malloc_op(pmem ++, p_calloc, nmemb * size);
switches 0:5c4d7b2438d3 198 check_calloc_op(pmem ++, p_calloc, nmemb, size);
switches 0:5c4d7b2438d3 199 check_free_op(pmem ++, p_realloc);
switches 0:5c4d7b2438d3 200 check_free_op(pmem, p_calloc);
switches 0:5c4d7b2438d3 201 }
switches 0:5c4d7b2438d3 202
switches 0:5c4d7b2438d3 203 // Test that tracing is off when using a NULL callback
switches 0:5c4d7b2438d3 204 static void test_case_trace_off() {
switches 0:5c4d7b2438d3 205 const size_t malloc_size = 10;
switches 0:5c4d7b2438d3 206
switches 0:5c4d7b2438d3 207 test_clear_stats();
switches 0:5c4d7b2438d3 208 // We don't want any tracing
switches 0:5c4d7b2438d3 209 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 210 // Allocate a buffer and free it
switches 0:5c4d7b2438d3 211 void *p_malloc = malloc(malloc_size);
switches 0:5c4d7b2438d3 212 TEST_ASSERT_NOT_EQUAL(p_malloc, NULL);
switches 0:5c4d7b2438d3 213 free(p_malloc);
switches 0:5c4d7b2438d3 214 // Check that we didn't trace anything
switches 0:5c4d7b2438d3 215 check_sanity(0);
switches 0:5c4d7b2438d3 216 }
switches 0:5c4d7b2438d3 217
switches 0:5c4d7b2438d3 218 // Test partial tracing (start tracing, stop tracing, restart later)
switches 0:5c4d7b2438d3 219 static void test_case_partial_trace() {
switches 0:5c4d7b2438d3 220 const size_t malloc_size_1 = 20, malloc_size_2 = 30;
switches 0:5c4d7b2438d3 221 const mem_trace_data_t *pmem = stats.op_data;
switches 0:5c4d7b2438d3 222
switches 0:5c4d7b2438d3 223 test_clear_stats();
switches 0:5c4d7b2438d3 224 // Start tracing
switches 0:5c4d7b2438d3 225 mbed_mem_trace_set_callback(test_trace_cb);
switches 0:5c4d7b2438d3 226 // Allocate a buffer
switches 0:5c4d7b2438d3 227 void *p_malloc_1 = malloc(malloc_size_1);
switches 0:5c4d7b2438d3 228 TEST_ASSERT_NOT_EQUAL(p_malloc_1, NULL);
switches 0:5c4d7b2438d3 229 // Disable tracing before freeing the first buffer
switches 0:5c4d7b2438d3 230 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 231 free(p_malloc_1);
switches 0:5c4d7b2438d3 232 // Allocate another buffer (still not traced)
switches 0:5c4d7b2438d3 233 void *p_malloc_2 = malloc(malloc_size_2);
switches 0:5c4d7b2438d3 234 TEST_ASSERT_NOT_EQUAL(p_malloc_2, NULL);
switches 0:5c4d7b2438d3 235 // Re-enable tracing
switches 0:5c4d7b2438d3 236 mbed_mem_trace_set_callback(test_trace_cb);
switches 0:5c4d7b2438d3 237 // And free the second buffer (this operation should be tracer)
switches 0:5c4d7b2438d3 238 free(p_malloc_2);
switches 0:5c4d7b2438d3 239 // Stop tracing
switches 0:5c4d7b2438d3 240 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 241 // Check tracer result
switches 0:5c4d7b2438d3 242 check_sanity(2);
switches 0:5c4d7b2438d3 243 check_malloc_op(pmem ++, p_malloc_1, malloc_size_1);
switches 0:5c4d7b2438d3 244 check_free_op(pmem, p_malloc_2);
switches 0:5c4d7b2438d3 245 }
switches 0:5c4d7b2438d3 246
switches 0:5c4d7b2438d3 247 // Test new/delete tracing
switches 0:5c4d7b2438d3 248 static void test_case_new_delete() {
switches 0:5c4d7b2438d3 249 const mem_trace_data_t *pmem = stats.op_data;
switches 0:5c4d7b2438d3 250
switches 0:5c4d7b2438d3 251 test_clear_stats();
switches 0:5c4d7b2438d3 252 // Start tracing
switches 0:5c4d7b2438d3 253 mbed_mem_trace_set_callback(test_trace_cb);
switches 0:5c4d7b2438d3 254 // Test new, new[], delete and delete[]
switches 0:5c4d7b2438d3 255 int *p_int = new int;
switches 0:5c4d7b2438d3 256 int *p_int_array = new int[10];
switches 0:5c4d7b2438d3 257 delete p_int;
switches 0:5c4d7b2438d3 258 delete[] p_int_array;
switches 0:5c4d7b2438d3 259 // Stop tracing
switches 0:5c4d7b2438d3 260 mbed_mem_trace_set_callback(NULL);
switches 0:5c4d7b2438d3 261 // Check tracer result
switches 0:5c4d7b2438d3 262 check_sanity(4);
switches 0:5c4d7b2438d3 263 check_malloc_op(pmem ++, p_int, sizeof(int));
switches 0:5c4d7b2438d3 264 check_malloc_op(pmem ++, p_int_array, 10 * sizeof(int));
switches 0:5c4d7b2438d3 265 check_free_op(pmem ++, p_int);
switches 0:5c4d7b2438d3 266 check_free_op(pmem ++, p_int_array);
switches 0:5c4d7b2438d3 267 }
switches 0:5c4d7b2438d3 268
switches 0:5c4d7b2438d3 269 static Case cases[] = {
switches 0:5c4d7b2438d3 270 Case("single malloc/free", test_case_single_malloc_free),
switches 0:5c4d7b2438d3 271 Case("all memory operations", test_case_all_memory_ops),
switches 0:5c4d7b2438d3 272 Case("trace off", test_case_trace_off),
switches 0:5c4d7b2438d3 273 Case("partial trace", test_case_partial_trace),
switches 0:5c4d7b2438d3 274 Case("test new/delete", test_case_new_delete)
switches 0:5c4d7b2438d3 275 };
switches 0:5c4d7b2438d3 276
switches 0:5c4d7b2438d3 277 static status_t greentea_test_setup(const size_t number_of_cases) {
switches 0:5c4d7b2438d3 278 GREENTEA_SETUP(20, "default_auto");
switches 0:5c4d7b2438d3 279 return greentea_test_setup_handler(number_of_cases);
switches 0:5c4d7b2438d3 280 }
switches 0:5c4d7b2438d3 281
switches 0:5c4d7b2438d3 282 static Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
switches 0:5c4d7b2438d3 283
switches 0:5c4d7b2438d3 284 int main() {
switches 0:5c4d7b2438d3 285 // Disable stdout buffering to prevent any unwanted allocations
switches 0:5c4d7b2438d3 286 setvbuf(stdout, NULL, _IONBF, 0);
switches 0:5c4d7b2438d3 287 Harness::run(specification);
switches 0:5c4d7b2438d3 288 }
switches 0:5c4d7b2438d3 289