1 /* 2 Tests for the capabilities-based memory allocator. 3 */ 4 5 #include <esp_types.h> 6 #include <stdio.h> 7 #include "unity.h" 8 #include "esp_attr.h" 9 #include "esp_heap_caps.h" 10 #include "esp_spi_flash.h" 11 #include <stdlib.h> 12 #include <sys/param.h> 13 #include <string.h> 14 #include <malloc.h> 15 16 TEST_CASE("Capabilities aligned allocator test", "[heap]") 17 { 18 uint32_t alignments = 0; 19 20 printf("[ALIGNED_ALLOC] Allocating from default CAP: \n"); 21 22 for(;alignments <= 1024; alignments++) { 23 uint8_t *buf = (uint8_t *)memalign(alignments, (alignments + 137)); 24 if(((alignments & (alignments - 1)) != 0) || (!alignments)) { 25 TEST_ASSERT( buf == NULL ); 26 //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments); 27 } else { 28 TEST_ASSERT( buf != NULL ); 29 printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments); 30 printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf); 31 //Address of obtained block must be aligned with selected value 32 TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0); 33 34 //Write some data, if it corrupts memory probably the heap 35 //canary verification will fail: 36 memset(buf, 0xA5, (alignments + 137)); 37 38 free(buf); 39 } 40 } 41 42 //Alloc from a non permitted area: 43 uint32_t *not_permitted_buf = (uint32_t *)heap_caps_aligned_alloc(alignments, (alignments + 137), MALLOC_CAP_EXEC | MALLOC_CAP_32BIT); 44 TEST_ASSERT( not_permitted_buf == NULL ); 45 46 #if CONFIG_ESP32_SPIRAM_SUPPORT || CONFIG_ESP32S2_SPIRAM_SUPPORT 47 alignments = 0; 48 printf("[ALIGNED_ALLOC] Allocating from external memory: \n"); 49 50 for(;alignments <= 1024 * 1024; alignments++) { 51 //Now try to take aligned memory from IRAM: 52 uint8_t *buf = (uint8_t *)heap_caps_aligned_alloc(alignments, 10*1024, MALLOC_CAP_SPIRAM); 53 if(((alignments & (alignments - 1)) != 0) || (!alignments)) { 54 TEST_ASSERT( buf == NULL ); 55 //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments); 56 } else { 57 TEST_ASSERT( buf != NULL ); 58 printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments); 59 printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf); 60 //Address of obtained block must be aligned with selected value 61 TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0); 62 63 //Write some data, if it corrupts memory probably the heap 64 //canary verification will fail: 65 memset(buf, 0xA5, (10*1024)); 66 heap_caps_free(buf); 67 } 68 } 69 #endif 70 71 } 72 73 TEST_CASE("Capabilities aligned calloc test", "[heap]") 74 { 75 uint32_t alignments = 0; 76 77 printf("[ALIGNED_ALLOC] Allocating from default CAP: \n"); 78 79 for(;alignments <= 1024; alignments++) { 80 uint8_t *buf = (uint8_t *)heap_caps_aligned_calloc(alignments, 1, (alignments + 137), MALLOC_CAP_DEFAULT); 81 if(((alignments & (alignments - 1)) != 0) || (!alignments)) { 82 TEST_ASSERT( buf == NULL ); 83 //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments); 84 } else { 85 TEST_ASSERT( buf != NULL ); 86 printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments); 87 printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf); 88 //Address of obtained block must be aligned with selected value 89 TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0); 90 91 //Write some data, if it corrupts memory probably the heap 92 //canary verification will fail: 93 memset(buf, 0xA5, (alignments + 137)); 94 95 heap_caps_free(buf); 96 } 97 } 98 99 //Check if memory is initialized with zero: 100 uint8_t byte_array[1024]; 101 memset(&byte_array, 0, sizeof(byte_array)); 102 uint8_t *buf = (uint8_t *)heap_caps_aligned_calloc(1024, 1, 1024, MALLOC_CAP_DEFAULT); 103 TEST_ASSERT(memcmp(byte_array, buf, sizeof(byte_array)) == 0); 104 heap_caps_free(buf); 105 106 //Same size, but different chunk: 107 buf = (uint8_t *)heap_caps_aligned_calloc(1024, 1024, 1, MALLOC_CAP_DEFAULT); 108 TEST_ASSERT(memcmp(byte_array, buf, sizeof(byte_array)) == 0); 109 heap_caps_free(buf); 110 111 //Alloc from a non permitted area: 112 uint32_t *not_permitted_buf = (uint32_t *)heap_caps_aligned_calloc(alignments, 1, (alignments + 137), MALLOC_CAP_32BIT); 113 TEST_ASSERT( not_permitted_buf == NULL ); 114 115 #if CONFIG_ESP32_SPIRAM_SUPPORT || CONFIG_ESP32S2_SPIRAM_SUPPORT 116 alignments = 0; 117 printf("[ALIGNED_ALLOC] Allocating from external memory: \n"); 118 119 for(;alignments <= 1024 * 1024; alignments++) { 120 //Now try to take aligned memory from IRAM: 121 uint8_t *buf = (uint8_t *)(uint8_t *)heap_caps_aligned_calloc(alignments, 1, 10*1024, MALLOC_CAP_SPIRAM); 122 if(((alignments & (alignments - 1)) != 0) || (!alignments)) { 123 TEST_ASSERT( buf == NULL ); 124 //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments); 125 } else { 126 TEST_ASSERT( buf != NULL ); 127 printf("[ALIGNED_ALLOC] alignment required: %u \n", alignments); 128 printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf); 129 //Address of obtained block must be aligned with selected value 130 TEST_ASSERT(((intptr_t)buf & (alignments - 1)) == 0); 131 132 //Write some data, if it corrupts memory probably the heap 133 //canary verification will fail: 134 memset(buf, 0xA5, (10*1024)); 135 heap_caps_free(buf); 136 } 137 } 138 #endif 139 140 } 141 142 TEST_CASE("aligned_alloc(0) should return a NULL pointer", "[heap]") 143 { 144 void *p; 145 p = heap_caps_aligned_alloc(32, 0, MALLOC_CAP_DEFAULT); 146 TEST_ASSERT(p == NULL); 147 } 148