test_malloc_caps.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. Tests for the capabilities-based memory allocator.
  3. */
  4. #include <esp_types.h>
  5. #include <stdio.h>
  6. #include "unity.h"
  7. #include "esp_attr.h"
  8. #include "esp_heap_caps.h"
  9. #include "esp_spi_flash.h"
  10. #include <stdlib.h>
  11. TEST_CASE("Capabilities allocator test", "[heap]")
  12. {
  13. char *m1, *m2[10];
  14. int x;
  15. size_t free8start, free32start, free8, free32;
  16. /* It's important we printf() something before we take the empty heap sizes,
  17. as the first printf() in a task allocates heap resources... */
  18. printf("Testing capabilities allocator...\n");
  19. free8start = heap_caps_get_free_size(MALLOC_CAP_8BIT);
  20. free32start = heap_caps_get_free_size(MALLOC_CAP_32BIT);
  21. printf("Free 8bit-capable memory (start): %dK, 32-bit capable memory %dK\n", free8start, free32start);
  22. TEST_ASSERT(free32start>free8start);
  23. printf("Allocating 10K of 8-bit capable RAM\n");
  24. m1= heap_caps_malloc(10*1024, MALLOC_CAP_8BIT);
  25. printf("--> %p\n", m1);
  26. free8 = heap_caps_get_free_size(MALLOC_CAP_8BIT);
  27. free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT);
  28. printf("Free 8bit-capable memory (both reduced): %dK, 32-bit capable memory %dK\n", free8, free32);
  29. //Both should have gone down by 10K; 8bit capable ram is also 32-bit capable
  30. TEST_ASSERT(free8<(free8start-10*1024));
  31. TEST_ASSERT(free32<(free32start-10*1024));
  32. //Assume we got DRAM back
  33. TEST_ASSERT((((int)m1)&0xFF000000)==0x3F000000);
  34. free(m1);
  35. printf("Freeing; allocating 10K of 32K-capable RAM\n");
  36. m1 = heap_caps_malloc(10*1024, MALLOC_CAP_32BIT);
  37. printf("--> %p\n", m1);
  38. free8 = heap_caps_get_free_size(MALLOC_CAP_8BIT);
  39. free32 = heap_caps_get_free_size(MALLOC_CAP_32BIT);
  40. printf("Free 8bit-capable memory (after 32-bit): %dK, 32-bit capable memory %dK\n", free8, free32);
  41. //Only 32-bit should have gone down by 10K: 32-bit isn't necessarily 8bit capable
  42. TEST_ASSERT(free32<(free32start-10*1024));
  43. TEST_ASSERT(free8==free8start);
  44. //Assume we got IRAM back
  45. TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000);
  46. free(m1);
  47. printf("Allocating impossible caps\n");
  48. m1= heap_caps_malloc(10*1024, MALLOC_CAP_8BIT|MALLOC_CAP_EXEC);
  49. printf("--> %p\n", m1);
  50. TEST_ASSERT(m1==NULL);
  51. printf("Testing changeover iram -> dram");
  52. // priorities will exhaust IRAM first, then start allocating from DRAM
  53. for (x=0; x<10; x++) {
  54. m2[x]= heap_caps_malloc(10*1024, MALLOC_CAP_32BIT);
  55. printf("--> %p\n", m2[x]);
  56. }
  57. TEST_ASSERT((((int)m2[0])&0xFF000000)==0x40000000);
  58. TEST_ASSERT((((int)m2[9])&0xFF000000)==0x3F000000);
  59. printf("Test if allocating executable code still gives IRAM, even with dedicated IRAM region depleted\n");
  60. // (the allocation should come from D/IRAM)
  61. m1= heap_caps_malloc(10*1024, MALLOC_CAP_EXEC);
  62. printf("--> %p\n", m1);
  63. TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000);
  64. free(m1);
  65. for (x=0; x<10; x++) free(m2[x]);
  66. printf("Done.\n");
  67. }
  68. TEST_CASE("heap_caps metadata test", "[heap]")
  69. {
  70. /* need to print something as first printf allocates some heap */
  71. printf("heap_caps metadata test\n");
  72. heap_caps_print_heap_info(MALLOC_CAP_8BIT);
  73. heap_caps_print_heap_info(MALLOC_CAP_32BIT);
  74. multi_heap_info_t original;
  75. heap_caps_get_info(&original, MALLOC_CAP_8BIT);
  76. void *b = heap_caps_malloc(original.largest_free_block, MALLOC_CAP_8BIT);
  77. TEST_ASSERT_NOT_NULL(b);
  78. printf("After allocating %d bytes:\n", original.largest_free_block);
  79. heap_caps_print_heap_info(MALLOC_CAP_8BIT);
  80. multi_heap_info_t after;
  81. heap_caps_get_info(&after, MALLOC_CAP_8BIT);
  82. TEST_ASSERT(after.largest_free_block < original.largest_free_block);
  83. TEST_ASSERT(after.total_free_bytes < original.total_free_bytes);
  84. free(b);
  85. heap_caps_get_info(&after, MALLOC_CAP_8BIT);
  86. TEST_ASSERT_EQUAL(after.total_free_bytes, original.total_free_bytes);
  87. TEST_ASSERT_EQUAL(after.largest_free_block, original.largest_free_block);
  88. TEST_ASSERT(after.minimum_free_bytes < original.total_free_bytes);
  89. }
  90. /* Small function runs from IRAM to check that malloc/free/realloc
  91. all work OK when cache is disabled...
  92. */
  93. static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test()
  94. {
  95. spi_flash_guard_get()->start(); // Disables flash cache
  96. bool result = true;
  97. void *x = heap_caps_malloc(64, MALLOC_CAP_32BIT);
  98. result = result && (x != NULL);
  99. void *y = heap_caps_realloc(x, 32, MALLOC_CAP_32BIT);
  100. result = result && (y != NULL);
  101. heap_caps_free(y);
  102. spi_flash_guard_get()->end(); // Re-enables flash cache
  103. return result;
  104. }
  105. TEST_CASE("heap_caps_xxx functions work with flash cache disabled", "[heap]")
  106. {
  107. TEST_ASSERT( iram_malloc_test() );
  108. }