-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dma: Scatter gather test #44041
Merged
Merged
dma: Scatter gather test #44041
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(scatter_gather) | ||
|
||
FILE(GLOB app_sources src/*.c) | ||
target_sources(app PRIVATE ${app_sources}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Copyright (c) 2022 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
mainmenu "DMA Scatter Gather Test" | ||
|
||
source "Kconfig.zephyr" | ||
|
||
config DMA_SG_DRV_NAME | ||
string "DMA device name to use for test" | ||
default "DMA_0" | ||
|
||
config DMA_SG_CHANNEL_NR | ||
int "DMA channel to use" | ||
default 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
CONFIG_ZTEST=y | ||
CONFIG_DMA=y | ||
CONFIG_LOG=y | ||
CONFIG_DMA_LOG_LEVEL_INF=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright (c) 2022 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
|
||
#include <zephyr.h> | ||
#include <ztest.h> | ||
|
||
extern void test_dma_m2m_sg(void); | ||
|
||
void test_main(void) | ||
{ | ||
ztest_test_suite(dma_m2m_sg_test, | ||
ztest_unit_test(test_dma_m2m_sg)); | ||
ztest_run_test_suite(dma_m2m_sg_test); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* | ||
* Copyright (c) 2022 Intel Corporation. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @file | ||
* @brief Verify zephyr dma memory to memory transfer loops with scatter gather | ||
* @details | ||
* - Test Steps | ||
* -# Set dma configuration for scatter gather enable | ||
* -# Set direction memory-to-memory with two block transfers | ||
* -# Start transfer tx -> rx | ||
* - Expected Results | ||
* -# Data is transferred correctly from src buffers to dest buffers without | ||
* software intervention. | ||
*/ | ||
|
||
#include <kernel.h> | ||
#include <drivers/dma.h> | ||
#include <ztest.h> | ||
|
||
#define XFERS 2 | ||
#define XFER_SIZE 64 | ||
|
||
#if CONFIG_NOCACHE_MEMORY | ||
static const char TX_DATA[] = "The quick brown fox jumps over the lazy dog"; | ||
static __aligned(32) char tx_data[XFER_SIZE] __used | ||
__attribute__((__section__(".nocache"))); | ||
static __aligned(32) char rx_data[XFERS][XFER_SIZE] __used | ||
__attribute__((__section__(".nocache.dma"))); | ||
#else | ||
/* this src memory shall be in RAM to support usingas a DMA source pointer.*/ | ||
static const char tx_data[] = "The quick brown fox jumps over the lazy dog"; | ||
static __aligned(32) char rx_data[XFERS][XFER_SIZE] = { { 0 } }; | ||
#endif | ||
|
||
#define DMA_DEVICE_NAME CONFIG_DMA_SG_DRV_NAME | ||
|
||
K_SEM_DEFINE(xfer_sem, 0, 1); | ||
|
||
static struct dma_config dma_cfg = {0}; | ||
static struct dma_block_config dma_block_cfgs[XFERS]; | ||
|
||
static void dma_sg_callback(const struct device *dma_dev, void *user_data, | ||
uint32_t channel, int status) | ||
{ | ||
if (status) { | ||
TC_PRINT("callback status %d\n", status); | ||
} else { | ||
TC_PRINT("giving xfer_sem\n"); | ||
k_sem_give(&xfer_sem); | ||
} | ||
} | ||
|
||
static int test_sg(void) | ||
{ | ||
const struct device *dma; | ||
static int chan_id; | ||
|
||
TC_PRINT("DMA memory to memory transfer started on %s\n", | ||
DMA_DEVICE_NAME); | ||
TC_PRINT("Preparing DMA Controller\n"); | ||
|
||
#if CONFIG_NOCACHE_MEMORY | ||
memset(tx_data, 0, sizeof(tx_data)); | ||
memcpy(tx_data, TX_DATA, sizeof(TX_DATA)); | ||
#endif | ||
memset(rx_data, 0, sizeof(rx_data)); | ||
|
||
dma = device_get_binding(DMA_DEVICE_NAME); | ||
if (!dma) { | ||
TC_PRINT("Cannot get dma controller\n"); | ||
return TC_FAIL; | ||
} | ||
|
||
dma_cfg.channel_direction = MEMORY_TO_MEMORY; | ||
dma_cfg.source_data_size = 4U; | ||
dma_cfg.dest_data_size = 4U; | ||
dma_cfg.source_burst_length = 4U; | ||
dma_cfg.dest_burst_length = 4U; | ||
#ifdef CONFIG_DMAMUX_STM32 | ||
dma_cfg.user_data = (struct device *)dma; | ||
#else | ||
dma_cfg.user_data = NULL; | ||
#endif /* CONFIG_DMAMUX_STM32 */ | ||
dma_cfg.dma_callback = dma_sg_callback; | ||
dma_cfg.block_count = XFERS; | ||
dma_cfg.head_block = dma_block_cfgs; | ||
dma_cfg.complete_callback_en = false; /* per block completion */ | ||
|
||
#ifdef CONFIG_DMA_MCUX_TEST_SLOT_START | ||
dma_cfg.dma_slot = CONFIG_DMA_MCUX_TEST_SLOT_START; | ||
#endif | ||
|
||
chan_id = dma_request_channel(dma, NULL); | ||
if (chan_id < 0) { | ||
TC_PRINT("Platform does not support dma request channel," | ||
" using Kconfig DMA_SG_CHANNEL_NR\n"); | ||
chan_id = CONFIG_DMA_SG_CHANNEL_NR; | ||
} | ||
|
||
memset(dma_block_cfgs, 0, sizeof(dma_block_cfgs)); | ||
for (int i = 0; i < XFERS; i++) { | ||
dma_block_cfgs[i].source_gather_en = 1U; | ||
dma_block_cfgs[i].block_size = XFER_SIZE; | ||
dma_block_cfgs[i].source_address = (uint32_t)(tx_data); | ||
dma_block_cfgs[i].dest_address = (uint32_t)(rx_data[i]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't these address be 64bit if |
||
TC_PRINT("dma block %d block_size %d, source addr %x, dest addr %x\n", | ||
i, XFER_SIZE, dma_block_cfgs[i].source_address, | ||
dma_block_cfgs[i].dest_address); | ||
if (i < XFERS - 1) { | ||
dma_block_cfgs[i].next_block = &dma_block_cfgs[i+1]; | ||
TC_PRINT("set next block pointer to %p\n", dma_block_cfgs[i].next_block); | ||
} | ||
} | ||
|
||
TC_PRINT("Configuring the scatter-gather transfer on channel %d\n", chan_id); | ||
|
||
if (dma_config(dma, chan_id, &dma_cfg)) { | ||
TC_PRINT("ERROR: transfer config (%d)\n", chan_id); | ||
return TC_FAIL; | ||
} | ||
|
||
TC_PRINT("Starting the transfer on channel %d and waiting completion\n", chan_id); | ||
|
||
if (dma_start(dma, chan_id)) { | ||
TC_PRINT("ERROR: transfer start (%d)\n", chan_id); | ||
return TC_FAIL; | ||
} | ||
|
||
if (k_sem_take(&xfer_sem, K_MSEC(1000)) != 0) { | ||
TC_PRINT("timed out waiting for xfers\n"); | ||
return TC_FAIL; | ||
} | ||
|
||
TC_PRINT("Verify RX buffer should contain the full TX buffer string.\n"); | ||
|
||
for (int i = 0; i < XFERS; i++) { | ||
TC_PRINT("rx_data[%d] %s\n", i, rx_data[i]); | ||
if (strncmp(tx_data, rx_data[i], sizeof(rx_data[i])) != 0) { | ||
return TC_FAIL; | ||
} | ||
} | ||
|
||
TC_PRINT("Finished: DMA Scatter-Gather\n"); | ||
return TC_PASS; | ||
} | ||
|
||
/* export test cases */ | ||
void test_dma_m2m_sg(void) | ||
{ | ||
zassert_true((test_sg() == TC_PASS), NULL); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
tests: | ||
drivers.dma.scatter_gather: | ||
depends_on: dma | ||
tags: drivers dma | ||
skip: True |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this conditional really necessary ? I don't see the callback using the data passsed here. The driver should not do anything with the user pointer as well.
I may have missed something though.