mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/sdmmc_bdl_casting_v6.0' into 'release/v6.0'
fix(sdmmc): BDL calculate sectors cast fix + Add a better handling of devices accessing PSRAM through DMA (v6.0) See merge request espressif/esp-idf!51044
This commit is contained in:
@@ -460,6 +460,16 @@ bool sd_host_check_buffer_alignment(sd_host_sdmmc_slot_t *slot, const void *buf,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !SOC_SDMMC_PSRAM_DMA_CAPABLE
|
||||
// The SDMMC peripheral's DMA cannot reach PSRAM on this target, so a PSRAM
|
||||
// buffer can never be used directly regardless of its alignment. Reporting
|
||||
// it as not directly usable makes the protocol layer fall back to an
|
||||
// internal DMA-capable buffer.
|
||||
if (esp_ptr_external_ram(buf)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
int cache_flags = 0;
|
||||
size_t cache_alignment_bytes = 0;
|
||||
|
||||
@@ -73,6 +73,31 @@ void sdmmc_test_rw_highprio_task(sdmmc_card_t* card);
|
||||
*/
|
||||
void sdmmc_test_rw_unaligned_buffer_multiblock(sdmmc_card_t* card, size_t chunk_size);
|
||||
|
||||
/**
|
||||
* @brief Test read/write with PSRAM-allocated buffers
|
||||
*
|
||||
* This function verifies that the driver correctly handles buffers allocated in PSRAM.
|
||||
* When the host reports the PSRAM buffer as directly usable (via check_buffer_alignment),
|
||||
* data is transferred directly without intermediate copying. Otherwise, the driver uses
|
||||
* double-buffering through internal RAM.
|
||||
*
|
||||
* The test covers:
|
||||
* - Writing from PSRAM, reading to internal RAM
|
||||
* - Writing from internal RAM, reading to PSRAM
|
||||
* - Both writing and reading from PSRAM
|
||||
*
|
||||
* If PSRAM is not enabled (CONFIG_SPIRAM), this function is a no-op. Callers
|
||||
* must skip the test (TEST_IGNORE) BEFORE initializing the slot/controller, so
|
||||
* that this function is not relied upon to abort the test. Doing the skip here
|
||||
* would longjmp out of the test before the caller's cleanup runs and leak the
|
||||
* SD slot.
|
||||
*
|
||||
* This test function works both with SDMMC and SDSPI hosts.
|
||||
*
|
||||
* @param card Pointer to the card object, must be initialized before calling this function.
|
||||
*/
|
||||
void sdmmc_test_rw_psram_buffer(sdmmc_card_t *card);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "test_utils.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "unity.h"
|
||||
#include "sd_protocol_defs.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
@@ -295,3 +296,64 @@ void sdmmc_test_rw_unaligned_buffer_multiblock(sdmmc_card_t* card, size_t chunk_
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void sdmmc_test_rw_psram_buffer(sdmmc_card_t *card)
|
||||
{
|
||||
#if !CONFIG_SPIRAM
|
||||
/* The PSRAM-disabled skip is intentionally NOT done here via TEST_IGNORE.
|
||||
* This function runs after the slot/controller has been initialized, and
|
||||
* TEST_IGNORE would longjmp out before the caller's *_end() cleanup runs,
|
||||
* leaking the slot. Callers must skip before initializing the hardware.
|
||||
*/
|
||||
(void)card;
|
||||
#else
|
||||
const size_t block_size = card->csd.sector_size;
|
||||
const size_t block_count = 8;
|
||||
const size_t buffer_size = block_size * block_count;
|
||||
|
||||
/* Allocate buffer in PSRAM */
|
||||
uint8_t *psram_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(psram_buf, "Failed to allocate PSRAM buffer; is PSRAM enabled?");
|
||||
TEST_ASSERT_MESSAGE(esp_ptr_external_ram(psram_buf), "Buffer not in PSRAM");
|
||||
|
||||
/* Also allocate a reference buffer in internal RAM for comparison */
|
||||
uint8_t *internal_buf = heap_caps_malloc(buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED);
|
||||
TEST_ASSERT_NOT_NULL(internal_buf);
|
||||
|
||||
/* A PSRAM buffer can be transferred directly only if the host reports it as
|
||||
* usable; otherwise the protocol layer transparently bounce-buffers it. This
|
||||
* test verifies correctness for both cases. */
|
||||
bool host_can_use_psram_directly =
|
||||
card->host.check_buffer_alignment(card->host.slot, psram_buf, buffer_size);
|
||||
printf("Testing PSRAM buffer R/W: %d blocks, host can use PSRAM directly=%s\n",
|
||||
(int)block_count, host_can_use_psram_directly ? "true" : "false");
|
||||
|
||||
/* Test A: Write from PSRAM buffer, read back to internal buffer, verify */
|
||||
const uint32_t seed_a = 0xABCD1234;
|
||||
fill_buffer(seed_a, psram_buf, buffer_size / sizeof(uint32_t));
|
||||
TEST_ESP_OK(sdmmc_write_sectors(card, psram_buf, 0, block_count));
|
||||
memset(internal_buf, 0xcc, buffer_size);
|
||||
TEST_ESP_OK(sdmmc_read_sectors(card, internal_buf, 0, block_count));
|
||||
check_buffer(seed_a, internal_buf, buffer_size / sizeof(uint32_t));
|
||||
|
||||
/* Test B: Write from internal buffer, read back to PSRAM buffer, verify */
|
||||
const uint32_t seed_b = 0x5678EFAB;
|
||||
fill_buffer(seed_b, internal_buf, buffer_size / sizeof(uint32_t));
|
||||
TEST_ESP_OK(sdmmc_write_sectors(card, internal_buf, 0, block_count));
|
||||
memset(psram_buf, 0xcc, buffer_size);
|
||||
TEST_ESP_OK(sdmmc_read_sectors(card, psram_buf, 0, block_count));
|
||||
check_buffer(seed_b, psram_buf, buffer_size / sizeof(uint32_t));
|
||||
|
||||
/* Test C: Both write and read from PSRAM buffer */
|
||||
const uint32_t seed_c = 0xDEAD9876;
|
||||
fill_buffer(seed_c, psram_buf, buffer_size / sizeof(uint32_t));
|
||||
TEST_ESP_OK(sdmmc_write_sectors(card, psram_buf, 0, block_count));
|
||||
memset(psram_buf, 0xcc, buffer_size);
|
||||
TEST_ESP_OK(sdmmc_read_sectors(card, psram_buf, 0, block_count));
|
||||
check_buffer(seed_c, psram_buf, buffer_size / sizeof(uint32_t));
|
||||
|
||||
free(psram_buf);
|
||||
free(internal_buf);
|
||||
printf("PSRAM buffer R/W test passed\n");
|
||||
#endif // CONFIG_SPIRAM
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -128,3 +128,26 @@ TEST_CASE("sdmmc read/write with concurrent high-prio task, slot 1, 4-bit", "[sd
|
||||
{
|
||||
do_one_sdmmc_rw_test_highprio_task(1, 4);
|
||||
}
|
||||
|
||||
static void do_one_sdmmc_rw_test_psram_dma_buffer(int slot, int width)
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
int freq_khz = SDMMC_FREQ_HIGHSPEED;
|
||||
#if !CONFIG_SPIRAM
|
||||
TEST_IGNORE_MESSAGE("PSRAM is not enabled");
|
||||
#endif
|
||||
sdmmc_test_sd_skip_if_board_incompatible(slot, width, freq_khz, NO_DDR, NO_EMMC);
|
||||
sdmmc_test_sd_begin(slot, width, freq_khz, 0, &card);
|
||||
sdmmc_test_rw_psram_buffer(&card);
|
||||
sdmmc_test_sd_end(&card);
|
||||
}
|
||||
|
||||
TEST_CASE("sdmmc read/write using PSRAM DMA accessible buffer, slot 0, 4-bit", "[sdmmc]")
|
||||
{
|
||||
do_one_sdmmc_rw_test_psram_dma_buffer(0, 4);
|
||||
}
|
||||
|
||||
TEST_CASE("sdmmc read/write using PSRAM DMA accessible buffer, slot 1, 4-bit", "[sdmmc]")
|
||||
{
|
||||
do_one_sdmmc_rw_test_psram_dma_buffer(1, 4);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -107,3 +107,30 @@ TEST_CASE("sdspi read/write performance - wait_for_miso == -1, slot 1", "[sdspi]
|
||||
//here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749
|
||||
do_one_sdspi_perf_test_dont_wait_for_miso(SLOT_1, SDMMC_FREQ_DEFAULT);
|
||||
}
|
||||
|
||||
/* ========== Read/write PSRAM DMA test, SPI ========== */
|
||||
|
||||
static void do_one_sdspi_psram_dma_test(int slot, int freq_khz)
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
#if !CONFIG_SPIRAM
|
||||
TEST_IGNORE_MESSAGE("PSRAM is not enabled");
|
||||
#endif
|
||||
sdmmc_test_spi_skip_if_board_incompatible(slot, freq_khz);
|
||||
sdmmc_test_spi_begin(slot, freq_khz, &card, NULL, NULL, NULL);
|
||||
sdmmc_card_print_info(stdout, &card);
|
||||
sdmmc_test_rw_psram_buffer(&card);
|
||||
sdmmc_test_spi_end(slot, &card);
|
||||
}
|
||||
|
||||
TEST_CASE("sdspi read/write psram dma, slot 0", "[sdspi]")
|
||||
{
|
||||
do_one_sdspi_psram_dma_test(SLOT_0, SDMMC_FREQ_HIGHSPEED);
|
||||
}
|
||||
|
||||
TEST_CASE("sdspi read/write psram dma, slot 1", "[sdspi]")
|
||||
{
|
||||
//TODO: IDF-8749
|
||||
//here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749
|
||||
do_one_sdspi_psram_dma_test(SLOT_1, SDMMC_FREQ_DEFAULT);
|
||||
}
|
||||
|
||||
22
components/sdmmc/include/esp_private/sdmmc_blockdev.h
Normal file
22
components/sdmmc/include/esp_private/sdmmc_blockdev.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
esp_err_t sdmmc_blockdev_calculate_sectors(size_t sector_size, uint64_t addr, size_t data_len,
|
||||
size_t *out_start_sector_num, size_t *out_num_of_sectors);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -247,7 +247,7 @@ typedef struct {
|
||||
*/
|
||||
void* dma_aligned_buffer;
|
||||
sd_pwr_ctrl_handle_t pwr_ctrl_handle; /*!< Power control handle */
|
||||
bool (*check_buffer_alignment)(int slot, const void *buf, size_t size); /*!< Check if buffer meets alignment requirements */
|
||||
bool (*check_buffer_alignment)(int slot, const void *buf, size_t size); /*!< Check if the host can use the buffer directly for a transfer (accounts for alignment and any hardware-specific DMA reachability constraints) */
|
||||
esp_err_t (*is_slot_set_to_uhs1)(int slot, bool *is_uhs1); /*!< host slot is set to uhs1 or not*/
|
||||
} sdmmc_host_t;
|
||||
|
||||
|
||||
@@ -1,34 +1,37 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "esp_private/sdmmc_common.h"
|
||||
#include "esp_private/sdmmc_blockdev.h"
|
||||
#include "esp_blockdev.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
|
||||
static esp_err_t calculate_start_sector_num_and_sector_count(size_t sector_size, uint64_t addr, size_t data_len, size_t* out_start_sector_num, size_t* out_num_of_sectors)
|
||||
esp_err_t sdmmc_blockdev_calculate_sectors(size_t sector_size, uint64_t addr, size_t data_len,
|
||||
size_t *out_start_sector_num, size_t *out_num_of_sectors)
|
||||
{
|
||||
size_t offset_in_start_sector = (size_t) addr % sector_size;
|
||||
size_t offset_in_end_sector = (size_t) data_len % sector_size;
|
||||
|
||||
// Has to be aligned to sector boundaries
|
||||
if (offset_in_start_sector != 0 || offset_in_end_sector != 0) {
|
||||
if (sector_size == 0 || addr % sector_size != 0 || data_len % sector_size != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (data_len > UINT64_MAX - addr) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
size_t start_sector_num = (size_t) addr / sector_size;
|
||||
size_t last_byte_addr = (size_t) (addr + data_len - 1); // Address of the last accessed byte
|
||||
size_t end_sector_num = last_byte_addr / sector_size;
|
||||
uint64_t start_sector_num = addr / sector_size;
|
||||
size_t num_of_sectors = data_len / sector_size;
|
||||
if (start_sector_num > SIZE_MAX || num_of_sectors > SIZE_MAX - start_sector_num) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (out_start_sector_num) {
|
||||
*out_start_sector_num = start_sector_num;
|
||||
*out_start_sector_num = (size_t) start_sector_num;
|
||||
}
|
||||
|
||||
if (out_num_of_sectors) {
|
||||
*out_num_of_sectors = end_sector_num - start_sector_num + 1;
|
||||
*out_num_of_sectors = num_of_sectors;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
@@ -41,7 +44,7 @@ static esp_err_t sdmmc_blockdev_read(esp_blockdev_handle_t handle, uint8_t* dst_
|
||||
}
|
||||
sdmmc_card_t* card = (sdmmc_card_t*) handle->ctx;
|
||||
size_t start_sector_num, num_of_sectors;
|
||||
esp_err_t err = calculate_start_sector_num_and_sector_count((size_t) card->csd.sector_size, src_addr, data_read_len, &start_sector_num, &num_of_sectors);
|
||||
esp_err_t err = sdmmc_blockdev_calculate_sectors((size_t) card->csd.sector_size, src_addr, data_read_len, &start_sector_num, &num_of_sectors);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -56,7 +59,7 @@ static esp_err_t sdmmc_blockdev_write(esp_blockdev_handle_t handle, const uint8_
|
||||
}
|
||||
sdmmc_card_t* card = (sdmmc_card_t*) handle->ctx;
|
||||
size_t start_sector_num, num_of_sectors;
|
||||
esp_err_t err = calculate_start_sector_num_and_sector_count((size_t) card->csd.sector_size, dst_addr, data_write_len, &start_sector_num, &num_of_sectors);
|
||||
esp_err_t err = sdmmc_blockdev_calculate_sectors((size_t) card->csd.sector_size, dst_addr, data_write_len, &start_sector_num, &num_of_sectors);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -71,7 +74,7 @@ static esp_err_t sdmmc_blockdev_erase(esp_blockdev_handle_t handle, uint64_t sta
|
||||
}
|
||||
sdmmc_card_t* card = (sdmmc_card_t*) handle->ctx;
|
||||
size_t start_sector_num, num_of_sectors;
|
||||
esp_err_t err = calculate_start_sector_num_and_sector_count((size_t) card->csd.sector_size, start_addr, erase_len, &start_sector_num, &num_of_sectors);
|
||||
esp_err_t err = sdmmc_blockdev_calculate_sectors((size_t) card->csd.sector_size, start_addr, erase_len, &start_sector_num, &num_of_sectors);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,20 @@ static inline size_t get_chunk_size(const sdmmc_card_t *card)
|
||||
return (chunk_size != 0) ? chunk_size : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether the host can transfer the user buffer directly, without an
|
||||
* intermediate DMA-capable buffer.
|
||||
*
|
||||
* The protocol layer does not need to reason about DMA or PSRAM: it simply asks
|
||||
* the host driver whether the buffer is usable as-is. The driver accounts for
|
||||
* alignment and any hardware-specific reachability constraints (e.g. whether the
|
||||
* peripheral's DMA can reach PSRAM).
|
||||
*/
|
||||
static inline bool sdmmc_buffer_directly_usable(const sdmmc_card_t *card, const void *buf, size_t size)
|
||||
{
|
||||
return card->host.check_buffer_alignment(card->host.slot, buf, size);
|
||||
}
|
||||
|
||||
static esp_err_t allocate_dma_buf(size_t* actual_size, size_t block_size, void **buf)
|
||||
{
|
||||
if (actual_size == NULL || buf == NULL) {
|
||||
@@ -486,16 +500,10 @@ esp_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src,
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
size_t block_size = card->csd.sector_size;
|
||||
bool is_aligned = card->host.check_buffer_alignment(card->host.slot, src, block_size * block_count);
|
||||
|
||||
if (is_aligned
|
||||
#if !SOC_SDMMC_PSRAM_DMA_CAPABLE
|
||||
&& !esp_ptr_external_ram(src)
|
||||
#endif
|
||||
) {
|
||||
if (sdmmc_buffer_directly_usable(card, src, block_size * block_count)) {
|
||||
err = sdmmc_write_sectors_dma(card, src, start_block, block_count, block_size * block_count);
|
||||
} else {
|
||||
// SDMMC peripheral needs DMA-capable buffers. Split the write into
|
||||
// The host cannot transfer this buffer directly. Split the write into
|
||||
// separate (multi) block writes, if needed, and allocate a temporary
|
||||
// DMA-capable buffer.
|
||||
size_t chunk_size = get_chunk_size(card);
|
||||
@@ -649,16 +657,10 @@ esp_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst,
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
size_t block_size = card->csd.sector_size;
|
||||
bool is_aligned = card->host.check_buffer_alignment(card->host.slot, dst, block_size * block_count);
|
||||
|
||||
if (is_aligned
|
||||
#if !SOC_SDMMC_PSRAM_DMA_CAPABLE
|
||||
&& !esp_ptr_external_ram(dst)
|
||||
#endif
|
||||
) {
|
||||
if (sdmmc_buffer_directly_usable(card, dst, block_size * block_count)) {
|
||||
err = sdmmc_read_sectors_dma(card, dst, start_block, block_count, block_size * block_count);
|
||||
} else {
|
||||
// SDMMC peripheral needs DMA-capable buffers. Split the read into
|
||||
// The host cannot transfer this buffer directly. Split the read into
|
||||
// separate (multi) block reads, if needed, and allocate a temporary
|
||||
// DMA-capable buffer.
|
||||
size_t chunk_size = get_chunk_size(card);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -9,23 +9,42 @@
|
||||
#include <inttypes.h>
|
||||
#include "unity.h"
|
||||
#include "unity_fixture.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "sd_protocol_defs.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "sdmmc_test_begin_end_sd.h"
|
||||
#include "sdmmc_test_rw_common.h"
|
||||
#include "esp_blockdev.h"
|
||||
#include "esp_private/sdmmc_blockdev.h"
|
||||
|
||||
TEST_GROUP(sdmmc);
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (200)
|
||||
|
||||
TEST_SETUP(sdmmc)
|
||||
TEST_CASE("sdmmc blockdev converts byte ranges to sectors", "[sdmmc]")
|
||||
{
|
||||
size_t start_sector;
|
||||
size_t sector_count;
|
||||
|
||||
TEST_ESP_OK(sdmmc_blockdev_calculate_sectors(512, UINT64_C(0x100000000), 1024,
|
||||
&start_sector, §or_count));
|
||||
TEST_ASSERT_EQUAL_UINT32(8388608, start_sector);
|
||||
TEST_ASSERT_EQUAL_UINT32(2, sector_count);
|
||||
|
||||
TEST_ESP_OK(sdmmc_blockdev_calculate_sectors(512, UINT64_C(0x100000000), 0,
|
||||
&start_sector, §or_count));
|
||||
TEST_ASSERT_EQUAL_UINT32(8388608, start_sector);
|
||||
TEST_ASSERT_EQUAL_UINT32(0, sector_count);
|
||||
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG,
|
||||
sdmmc_blockdev_calculate_sectors(512, 1, 512, NULL, NULL));
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG,
|
||||
sdmmc_blockdev_calculate_sectors(512, 0, 1, NULL, NULL));
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG,
|
||||
sdmmc_blockdev_calculate_sectors(0, 0, 512, NULL, NULL));
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE,
|
||||
sdmmc_blockdev_calculate_sectors(512, UINT64_MAX - 511, 512, NULL, NULL));
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(sdmmc)
|
||||
{
|
||||
}
|
||||
|
||||
TEST(sdmmc, test_bdl_interface)
|
||||
TEST_CASE("sdmmc extra, bdl interface test", "[sdcard]")
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
int slot = 1;
|
||||
@@ -70,7 +89,7 @@ TEST(sdmmc, test_bdl_interface)
|
||||
sdmmc_test_sd_end(&card);
|
||||
}
|
||||
|
||||
TEST(sdmmc, test_multiblock_unaligned_rw)
|
||||
TEST_CASE("sdmmc extra, multiblock unaligned rw test", "[sdcard]")
|
||||
{
|
||||
sdmmc_card_t card;
|
||||
int slot = 1;
|
||||
@@ -82,13 +101,17 @@ TEST(sdmmc, test_multiblock_unaligned_rw)
|
||||
sdmmc_test_sd_end(&card);
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(sdmmc)
|
||||
void setUp(void)
|
||||
{
|
||||
RUN_TEST_CASE(sdmmc, test_bdl_interface)
|
||||
RUN_TEST_CASE(sdmmc, test_multiblock_unaligned_rw)
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
UNITY_MAIN(sdmmc);
|
||||
unity_run_menu();
|
||||
}
|
||||
|
||||
@@ -10,4 +10,4 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
@idf_parametrize('config', ['default'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_sdmmc_extra(dut: Dut) -> None:
|
||||
dut.expect_unity_test_output()
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
Reference in New Issue
Block a user