FSMC_SRAM haltest. Added memcpy over DMA speed test
This commit is contained in:
parent
900963482d
commit
7ac7d41b20
|
@ -101,7 +101,8 @@ CSRC = $(PORTSRC) \
|
||||||
$(PLATFORMSRC) \
|
$(PLATFORMSRC) \
|
||||||
$(BOARDSRC) \
|
$(BOARDSRC) \
|
||||||
main.c \
|
main.c \
|
||||||
membench.c
|
membench.c \
|
||||||
|
memcpy_dma.c
|
||||||
|
|
||||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||||
# setting.
|
# setting.
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include "membench.h"
|
#include "membench.h"
|
||||||
|
#include "memcpy_dma.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
|
@ -54,9 +55,9 @@ volatile int warning_suppressor;
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Calculates memory access time in MiB.
|
* Calculates memory access time in MiB/s.
|
||||||
*/
|
*/
|
||||||
double speed(const time_measurement_t *tmu, size_t len) {
|
double speed_mibps(const time_measurement_t *tmu, size_t len) {
|
||||||
double size; // MiB
|
double size; // MiB
|
||||||
double time; // sec
|
double time; // sec
|
||||||
|
|
||||||
|
@ -69,6 +70,17 @@ double speed(const time_measurement_t *tmu, size_t len) {
|
||||||
return size / time;
|
return size / time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates memory access time in B/s.
|
||||||
|
*/
|
||||||
|
uint32_t speed_bps(const time_measurement_t *tmu, size_t len) {
|
||||||
|
|
||||||
|
uint64_t tmp = len;
|
||||||
|
tmp *= STM32_SYSCLK;
|
||||||
|
|
||||||
|
return tmp / tmu->last;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* EXPORTED FUNCTIONS
|
* EXPORTED FUNCTIONS
|
||||||
|
@ -93,20 +105,29 @@ void membench_run(membench_t *dest, const membench_t *src,
|
||||||
chTMStartMeasurementX(&mem_tmu);
|
chTMStartMeasurementX(&mem_tmu);
|
||||||
memset(dest->start, 0x55, dest->size);
|
memset(dest->start, 0x55, dest->size);
|
||||||
chTMStopMeasurementX(&mem_tmu);
|
chTMStopMeasurementX(&mem_tmu);
|
||||||
result->memset_spd = speed(&mem_tmu, dest->size);
|
result->memset = speed_bps(&mem_tmu, dest->size);
|
||||||
|
|
||||||
/* memcpy */
|
/* memcpy */
|
||||||
chTMObjectInit(&mem_tmu);
|
chTMObjectInit(&mem_tmu);
|
||||||
chTMStartMeasurementX(&mem_tmu);
|
chTMStartMeasurementX(&mem_tmu);
|
||||||
memcpy(dest->start, src->start, len);
|
memcpy(dest->start, src->start, len);
|
||||||
chTMStopMeasurementX(&mem_tmu);
|
chTMStopMeasurementX(&mem_tmu);
|
||||||
result->memcpy_spd = speed(&mem_tmu, len);
|
result->memcpy = speed_bps(&mem_tmu, len);
|
||||||
|
|
||||||
/* memcmp */
|
/* memcmp */
|
||||||
chTMObjectInit(&mem_tmu);
|
chTMObjectInit(&mem_tmu);
|
||||||
chTMStartMeasurementX(&mem_tmu);
|
chTMStartMeasurementX(&mem_tmu);
|
||||||
warning_suppressor = memcmp(dest->start, src->start, len);
|
warning_suppressor = memcmp(dest->start, src->start, len);
|
||||||
chTMStopMeasurementX(&mem_tmu);
|
chTMStopMeasurementX(&mem_tmu);
|
||||||
result->memcmp_spd = speed(&mem_tmu, len);
|
result->memcmp = speed_bps(&mem_tmu, len);
|
||||||
|
|
||||||
|
/* memcpy DMA */
|
||||||
|
memcpy_dma_start();
|
||||||
|
chTMObjectInit(&mem_tmu);
|
||||||
|
chTMStartMeasurementX(&mem_tmu);
|
||||||
|
memcpy_dma(dest->start, src->start, len);
|
||||||
|
chTMStopMeasurementX(&mem_tmu);
|
||||||
|
result->memcpy_dma = speed_bps(&mem_tmu, len);
|
||||||
|
memcpy_dma_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,13 @@ typedef struct {
|
||||||
} membench_t;
|
} membench_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* all values in B/s
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
double memset_spd;
|
uint32_t memset;
|
||||||
double memcpy_spd;
|
uint32_t memcpy;
|
||||||
double memcmp_spd;
|
uint32_t memcpy_dma;
|
||||||
|
uint32_t memcmp;
|
||||||
} membench_result_t;
|
} membench_result_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2013-2014 Uladzimir Pylinsky aka barthess
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#include "memcpy_dma.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
* DEFINES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#define STM32_MEMCPY_DMA_PRIORITY 0
|
||||||
|
#define STM32_MEMCPY_DMA_STREAM STM32_DMA_STREAM_ID(2, 6)
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
* EXTERNS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
* PROTOTYPES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
* GLOBAL VARIABLES
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
static memcpy_dma_engine_t engine;
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
******************************************************************************
|
||||||
|
* LOCAL FUNCTIONS
|
||||||
|
******************************************************************************
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
******************************************************************************
|
||||||
|
* EXPORTED FUNCTIONS
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void memcpy_dma_start(void) {
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
engine.dma = STM32_DMA_STREAM(STM32_MEMCPY_DMA_STREAM);
|
||||||
|
b = dmaStreamAllocate(engine.dma, STM32_NAND_DMA_PRIORITY, NULL, NULL);
|
||||||
|
osalDbgAssert(!b, "stream already allocated");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void memcpy_dma_stop(void) {
|
||||||
|
dmaStreamRelease(engine.dma);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void memcpy_dma(void *dest, const void *src, size_t size) {
|
||||||
|
|
||||||
|
size_t words = size / 4;
|
||||||
|
size_t remainder = size % 4;
|
||||||
|
size_t max_block = 0xFFFF; /* DMA limitation */
|
||||||
|
|
||||||
|
uint32_t cr = STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
|
||||||
|
|
||||||
|
while (words > max_block) {
|
||||||
|
dmaStartMemCopy(engine.dma, cr, src, dest, max_block)
|
||||||
|
dmaWaitCompletion(engine.dma);
|
||||||
|
words -= max_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmaStartMemCopy(engine.dma, cr, src, dest, words)
|
||||||
|
dmaWaitCompletion(engine.dma);
|
||||||
|
|
||||||
|
if (remainder > 0)
|
||||||
|
memcpy(dest+size-remainder, src+size-remainder, remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef MEMCPY_DMA_H_
|
||||||
|
#define MEMCPY_DMA_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const stm32_dma_stream_t *dma;
|
||||||
|
} memcpy_dma_engine_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void memcpy_dma_start(void);
|
||||||
|
void memcpy_dma_stop(void);
|
||||||
|
void memcpy_dma(void *dest, const void *src, size_t size);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MEMCPY_DMA_H_ */
|
Loading…
Reference in New Issue