void app_start(int, char **) { // set the baud rate for output printing get_stdio_serial().baud(YOTTA_CFG_K64F_BORDER_ROUTER_BAUD); // set heap size and memory error handler for this application ns_dyn_mem_init(app_stack_heap, APP_DEFINED_HEAP_SIZE, app_heap_error_handler, 0); trace_init(); // set up the tracing library set_trace_print_function(trace_printer); set_trace_config(TRACE_MODE_COLOR | TRACE_ACTIVE_LEVEL_DEBUG | TRACE_CARRIAGE_RETURN); const char *mac_src = STR(YOTTA_CFG_K64F_BORDER_ROUTER_BACKHAUL_MAC_SRC); if (strcmp(mac_src, "BOARD") == 0) { /* Setting the MAC Address from UID (A yotta function) * Takes UID Mid low and UID low and shuffles them around. */ mbed_mac_address((char *)mac); } else if (strcmp(mac_src, "CONFIG") == 0) { /* MAC is defined by the user through yotta configuration */ const uint8_t mac48[] = YOTTA_CFG_K64F_BORDER_ROUTER_BACKHAUL_MAC; for (uint32_t i = 0; i < sizeof(mac); ++i) { mac[i] = mac48[i]; } } // run LED toggler in the Minar scheduler minar::Scheduler::postCallback(mbed::util::FunctionPointer0<void> (toggle_led1).bind()).period(minar::milliseconds(500)); tr_info("Starting K64F border router..."); border_router_start(); }
TEST(dynmem, test_both_allocs_with_hole_usage) { uint16_t size = 112; mem_stat_t info; void *p[size]; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); void *ptr = ns_dyn_mem_alloc(15); void *ptr2 = ns_dyn_mem_alloc(4); ns_dyn_mem_free(ptr); ns_dyn_mem_free(ptr2); CHECK(info.heap_sector_allocated_bytes == 0); void *ptr3 = ns_dyn_mem_temporary_alloc(15); void *ptr4 = ns_dyn_mem_temporary_alloc(5); ns_dyn_mem_free(ptr3); ns_dyn_mem_free(ptr4); CHECK(info.heap_sector_allocated_bytes == 0); free(heap); }
TEST(dynmem, not_negative_stats) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); void *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); CHECK(info.heap_sector_allocated_bytes == 0); ns_dyn_mem_alloc(8); p = ns_dyn_mem_alloc(8); ns_dyn_mem_alloc(8); CHECK(info.heap_sector_allocated_bytes >= 24); int16_t last_value = info.heap_sector_allocated_bytes; ns_dyn_mem_free(p); CHECK(info.heap_sector_allocated_bytes >= 16); CHECK(info.heap_sector_allocated_bytes < last_value); last_value = info.heap_sector_allocated_bytes; for (int i=0; i<10; i++) { p = ns_dyn_mem_alloc(1); ns_dyn_mem_free(p); } CHECK(info.heap_sector_allocated_bytes == last_value); free(heap); }
TEST(dynmem, ns_dyn_mem_alloc) { uint16_t size = 1000; mem_stat_t info; void *p[size]; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int block = 1; int i; for (i=0; i<size; i++) { p[i] = ns_dyn_mem_alloc(block); if (!p[i]) break; } CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 1); CHECK(info.heap_sector_alloc_cnt == i); CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); for (; i>=0; i--) { ns_dyn_mem_free(p[i]); } CHECK(!heap_have_failed()); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); }
TEST(dynmem, different_sizes) { reset_heap_error(); for (uint16_t size = 1000; size<32768; size++) { mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(info.heap_sector_size >= (size-72)); CHECK(!heap_have_failed()); CHECK(ns_dyn_mem_alloc(10)); free(heap); } }
TEST(dynmem, test_invalid_pointer_freed) { uint16_t size = 92; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); int *ptr = (int *)ns_dyn_mem_alloc(4); ptr--; *ptr = 16; ptr++; ns_dyn_mem_free(ptr); CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); free(heap); }
TEST(dynmem, too_big) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *ptr = heap; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); ns_dyn_mem_alloc(size); CHECK(heap_have_failed()); CHECK(NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID == current_heap_error); free(heap); }
TEST(dynmem, free_on_empty_heap) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); ns_dyn_mem_free(&heap[1]); CHECK(heap_have_failed()); CHECK(NS_DYN_MEM_POINTER_NOT_VALID == current_heap_error); free(heap); }
TEST(dynmem, diff_alignment) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *ptr = heap; CHECK(NULL != heap); reset_heap_error(); for (int i=0; i<16; i++) { ptr++; size--; ns_dyn_mem_init(ptr, size, &heap_fail_callback, &info); CHECK(info.heap_sector_size >= (size-72)); CHECK(!heap_have_failed()); } free(heap); }
TEST(dynmem, over_by_one) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); p = (uint8_t *)ns_dyn_mem_alloc(100); CHECK(p); p[100] = 0xff; ns_dyn_mem_free(p); CHECK(heap_have_failed()); CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); free(heap); }
TEST(dynmem, corrupted_memory) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *ptr = heap; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int *pt = (int *)ns_dyn_mem_alloc(8); CHECK(!heap_have_failed()); pt -= 2; *pt = 0; ns_dyn_mem_alloc(8); CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); free(heap); }
void app_start(int, char **) { char if_desciption[] = "6LoWPAN_NODE"; pc.baud(115200); //Setting the Baud-Rate for trace output ns_dyn_mem_init(app_stack_heap, APP_DEFINED_HEAP_SIZE, app_heap_error_handler,0); randLIB_seed_random(); platform_timer_enable(); eventOS_scheduler_init(); trace_init(); set_trace_print_function( trace_printer ); set_trace_config(TRACE_ACTIVE_LEVEL_DEBUG|TRACE_CARRIAGE_RETURN); tr_debug("M \r\n"); net_init_core(); rf_phy_device_register_id = rf_device_register(); net_rf_id = arm_nwk_interface_init(NET_INTERFACE_RF_6LOWPAN, rf_phy_device_register_id, if_desciption); eventOS_event_handler_create(&tasklet_main, ARM_LIB_TASKLET_INIT_EVENT); }
TEST(dynmem, double_free) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); void *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); p = ns_dyn_mem_alloc(100); CHECK(p); ns_dyn_mem_free(p); CHECK(!heap_have_failed()); ns_dyn_mem_free(p); CHECK(heap_have_failed()); CHECK(NS_DYN_MEM_DOUBLE_FREE == current_heap_error); free(heap); }
TEST(dynmem, test_free_corrupted_next_block) { uint16_t size = 1000; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); CHECK(!heap_have_failed()); int *ptr = (int *)ns_dyn_mem_temporary_alloc(4); int *ptr2 = (int *)ns_dyn_mem_temporary_alloc(4); ns_dyn_mem_free(ptr); ptr = ptr2 + 2; *ptr = -2; ns_dyn_mem_free(ptr2); CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); free(heap); }
TEST(dynmem, no_big_enough_sector) { uint16_t size = 112; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *ptr = heap; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int *pt = (int *)ns_dyn_mem_alloc(8); pt = (int *)ns_dyn_mem_alloc(8); ns_dyn_mem_alloc(8); ns_dyn_mem_temporary_alloc(8); ns_dyn_mem_temporary_alloc(8); ns_dyn_mem_free(pt); pt = (int *)ns_dyn_mem_temporary_alloc(32); CHECK(NULL == pt); free(heap); }
TEST(dynmem, diff_sizes) { uint16_t size = 1000; mem_stat_t info; void *p; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int i; for (i=1; i<(size-72); i++) { p = ns_dyn_mem_temporary_alloc(i); CHECK(p); ns_dyn_mem_free(p); CHECK(!heap_have_failed()); } CHECK(!heap_have_failed()); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); }
TEST(dynmem, middle_free) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); void *p[3]; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); for (int i=0; i<3; i++) { p[i] = ns_dyn_mem_temporary_alloc(100); CHECK(p); } ns_dyn_mem_free(p[1]); CHECK(!heap_have_failed()); ns_dyn_mem_free(p[0]); CHECK(!heap_have_failed()); ns_dyn_mem_free(p[2]); CHECK(!heap_have_failed()); free(heap); }
void mesh_system_init(void) { if (mesh_initialized == false) { #ifndef YOTTA_CFG ns_hal_init(app_stack_heap, MBED_MESH_API_HEAP_SIZE, mesh_system_heap_error_handler, NULL); eventOS_scheduler_mutex_wait(); net_init_core(); eventOS_scheduler_mutex_release(); #else ns_dyn_mem_init(app_stack_heap, MBED_MESH_API_HEAP_SIZE, mesh_system_heap_error_handler, NULL); randLIB_seed_random(); platform_timer_enable(); eventOS_scheduler_init(); trace_init(); // trace system needs to be initialized right after eventOS_scheduler_init net_init_core(); /* initialize 6LoWPAN socket adaptation layer */ ns_sal_init_stack(); #endif mesh_initialized = true; } }
TEST(dynmem, ns_dyn_mem_temporary_alloc_with_heap_threshold) { uint16_t size = 1000; mem_stat_t info; void *p1, *p2; int ret_val; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); // test1: temporary alloc will fail if there is less than 5% heap free p1 = ns_dyn_mem_temporary_alloc((size-72)*0.96); CHECK(!heap_have_failed()); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.02); CHECK(p2 == NULL); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 1); // Test2, disable threshold feature and try p2 allocation again ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.02); CHECK(!heap_have_failed()); CHECK(p2); ns_dyn_mem_free(p1); ns_dyn_mem_free(p2); CHECK(info.heap_alloc_fail_cnt == 1); CHECK(info.heap_sector_alloc_cnt == 0); // Test3, enable feature by free heap percentage ns_dyn_mem_set_temporary_alloc_free_heap_threshold(40, 0); p1 = ns_dyn_mem_temporary_alloc((size-72)*0.65); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.10); CHECK(p2==NULL); ns_dyn_mem_free(p1); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 2); CHECK(info.heap_sector_alloc_cnt == 0); // Test4, enable feature by free heap amount ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 200); p1 = ns_dyn_mem_temporary_alloc(size-72-100 /*828 bytes */); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc(1); CHECK(p2==NULL); ns_dyn_mem_free(p1); // Test5, illegal API parameters ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size/2); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size*2); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(51, 0); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(255, 0); CHECK(ret_val==-2); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 3); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); // Test6, feature is disabled if info is not set heap = (uint8_t*)malloc(size); CHECK(NULL != heap); ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); CHECK(ret_val==-1); CHECK(!heap_have_failed()); free(heap); }