test(heap): DMA alignment test silently passed on every target

"test alignment for dma" discarded every test_alignment() verdict and
counted a failed allocation as a pass, so it could never fail. Fix that,
use the external line size for PSRAM, and run hw-align in PSRAM configs.
This commit is contained in:
harshal.patil
2026-08-27 12:54:57 +05:30
parent 13e18a6a43
commit e5026cafea
2 changed files with 35 additions and 9 deletions
@@ -15,6 +15,7 @@
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "hal/cache_ll.h" #include "hal/cache_ll.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "soc/soc_caps.h"
TEST_CASE("test heap_caps_malloc_prefer for dma memory", "[hw-align]") TEST_CASE("test heap_caps_malloc_prefer for dma memory", "[hw-align]")
{ {
@@ -41,13 +42,21 @@ TEST_CASE("test heap_caps_calloc_prefer for dma memory", "[hw-align]")
#define TEST_ALLOC_COUNT 100 #define TEST_ALLOC_COUNT 100
static bool test_alignment(uint32_t caps, int expected_alignment) { static bool test_alignment(uint32_t caps, int expected_alignment) {
bool ret=true; bool ret=true;
int alignment = (expected_alignment > 1) ? expected_alignment : 1;
void *mem[TEST_ALLOC_COUNT]; void *mem[TEST_ALLOC_COUNT];
size_t size[TEST_ALLOC_COUNT]; size_t size[TEST_ALLOC_COUNT];
//First, check if we can allocate memory with these caps anyway. //First, check if we can allocate memory with these caps anyway.
if ((caps & MALLOC_CAP_SPIRAM) && heap_caps_get_total_size(MALLOC_CAP_SPIRAM) == 0) {
printf("skipping caps 0x%" PRIx32 ": no PSRAM heap registered\n", caps);
return true;
}
void *tst=heap_caps_malloc(1, caps); void *tst=heap_caps_malloc(1, caps);
if (!tst) return true; if (!tst) {
printf("caps 0x%" PRIx32 ": cannot allocate 1 byte with alignment %d\n", caps, alignment);
return false;
}
free(tst); free(tst);
//Step 1: generate sizes and allocate memory. //Step 1: generate sizes and allocate memory.
@@ -59,9 +68,20 @@ static bool test_alignment(uint32_t caps, int expected_alignment) {
// Step 2: check alignment and fill up memory up to the aligned size // Step 2: check alignment and fill up memory up to the aligned size
// (which should succeed as we expect to get an integer amount of cache lines) // (which should succeed as we expect to get an integer amount of cache lines)
for (int i=0; i<TEST_ALLOC_COUNT; i++) { for (int i=0; i<TEST_ALLOC_COUNT; i++) {
if (size[i] == 0) {
continue;
}
if (!mem[i]) {
printf("caps 0x%" PRIx32 ": allocation %d of %u bytes failed\n", caps, i, (unsigned)size[i]);
ret = false;
continue;
}
intptr_t off=(intptr_t)mem[i]; intptr_t off=(intptr_t)mem[i];
if (off&(expected_alignment-1)) ret=false; if (off & (alignment - 1)) {
size_t size_aligned_up = (size[i] + expected_alignment - 1) & (~(expected_alignment - 1)); printf("caps 0x%" PRIx32 ": %p is not aligned to %d\n", caps, mem[i], alignment);
ret = false;
}
size_t size_aligned_up = (size[i] + alignment - 1) & (~(alignment - 1));
memset(mem[i], 0xA5, size_aligned_up); memset(mem[i], 0xA5, size_aligned_up);
} }
@@ -77,11 +97,16 @@ static bool test_alignment(uint32_t caps, int expected_alignment) {
TEST_CASE("test alignment for dma", "[hw-align]") TEST_CASE("test alignment for dma", "[hw-align]")
{ {
int int_cache_size=cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); int int_cache_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
int ext_cache_size=cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); int ext_cache_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
test_alignment(MALLOC_CAP_DMA, int_cache_size); TEST_ASSERT_TRUE_MESSAGE(test_alignment(MALLOC_CAP_DMA, int_cache_size), "MALLOC_CAP_DMA");
test_alignment(MALLOC_CAP_DMA_DESC_AHB, int_cache_size); TEST_ASSERT_TRUE_MESSAGE(test_alignment(MALLOC_CAP_DMA_DESC_AHB, int_cache_size), "MALLOC_CAP_DMA_DESC_AHB");
test_alignment(MALLOC_CAP_DMA_DESC_AXI, int_cache_size>8?int_cache_size:8); #if SOC_HAS(AXI_GDMA)
test_alignment(MALLOC_CAP_DMA|MALLOC_CAP_SPIRAM, ext_cache_size); int axi_desc_alignment = int_cache_size > 8 ? int_cache_size : 8;
#else
int axi_desc_alignment = int_cache_size;
#endif
TEST_ASSERT_TRUE_MESSAGE(test_alignment(MALLOC_CAP_DMA_DESC_AXI, axi_desc_alignment), "MALLOC_CAP_DMA_DESC_AXI");
TEST_ASSERT_TRUE_MESSAGE(test_alignment(MALLOC_CAP_DMA|MALLOC_CAP_SPIRAM, ext_cache_size), "MALLOC_CAP_DMA|MALLOC_CAP_SPIRAM");
} }
@@ -48,6 +48,7 @@ def test_heap_in_flash(dut: Dut) -> None:
@pytest.mark.parametrize('config', ['psram', 'psram_all_ext']) @pytest.mark.parametrize('config', ['psram', 'psram_all_ext'])
def test_heap(dut: Dut) -> None: def test_heap(dut: Dut) -> None:
dut.run_all_single_board_cases(group='psram') dut.run_all_single_board_cases(group='psram')
dut.run_all_single_board_cases(group='hw-align')
@pytest.mark.generic @pytest.mark.generic