Added SDRAM teshtal. Not tested in hardware

This commit is contained in:
barthess 2015-06-30 23:53:35 +03:00
parent b7175b4510
commit 95da8798dd
8 changed files with 399 additions and 68 deletions

View File

@ -107,11 +107,14 @@ CSRC = $(STARTUPSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(TESTSRC) \
main.c
main.c \
memcpy_dma.c \
membench.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC =
CPPSRC = $(CHCPPSRC) \
$(CHIBIOS)/community/os/various/memtest.cpp
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler

View File

@ -18,24 +18,20 @@
aka barthess.
*/
/*
TODO:
write memtest function using ideas from http://www.memtest86.com/technical.htm
*/
#include "ch.h"
#include "hal.h"
#include "string.h"
#include "fsmc_sdram.h"
#include "membench.h"
#include "memtest.hpp"
/*
******************************************************************************
* DEFINES
******************************************************************************
*/
#define USE_INFINITE_MEMTEST FALSE
/*
* FMC SDRAM Mode definition register defines
@ -116,6 +112,9 @@ write memtest function using ideas from http://www.memtest86.com/technical.htm
#define FMC_Write_Protection_Disable ((uint32_t)0x00000000)
#define FMC_Write_Protection_Enable ((uint32_t)0x00000200)
#define SDRAM_SIZE (8 * 1024 * 1024)
#define SDRAM_START ((void *)FSMC_Bank6_MAP_BASE)
/*
******************************************************************************
* EXTERNS
@ -128,14 +127,13 @@ write memtest function using ideas from http://www.memtest86.com/technical.htm
******************************************************************************
*/
static void mem_error_cb(memtest_t *memp, testtype e, size_t address);
/*
******************************************************************************
* GLOBAL VARIABLES
******************************************************************************
*/
static uint32_t extram_check_buf[16 * 1024];
static uint32_t *extram_start = (uint32_t *)STM32_SDRAM1_MAP_BASE;
static const size_t extram_size = 1024*1024;
/*
* SDRAM driver configuration structure.
@ -164,17 +162,46 @@ static const SDRAMConfig sdram_cfg = {
FMC_SDCMR_MRD_OPERATING_MODE_STANDARD |
FMC_SDCMR_MRD_WRITEBURST_MODE_SINGLE) << 9,
/* if (STM32_SYSCLK == 180000000) ->
64ms/4096=15.625us
15.625us*90MHz=1406-20=1386 */
.sdrtr = 1386 << 1
.sdrtr = (uint32_t)(683 << 1),
};
/* benchmarking results in MiB/S */
double memset_speed_ext;
double memset_speed_int;
double memcpy_speed_ext2int;
double memcpy_speed_int2ext;
/*
*
*/
static uint8_t int_buf[64*1024];
/*
*
*/
static memtest_t memtest_struct = {
SDRAM_START,
SDRAM_SIZE,
MEMTEST_WIDTH_16,
mem_error_cb,
42
};
/*
*
*/
static membench_t membench_ext = {
SDRAM_START,
SDRAM_SIZE,
};
/*
*
*/
static membench_t membench_int = {
int_buf,
sizeof(int_buf),
};
/*
*
*/
static membench_result_t membench_result_ext2int;
static membench_result_t membench_result_int2ext;
/*
******************************************************************************
@ -183,58 +210,33 @@ double memcpy_speed_int2ext;
******************************************************************************
******************************************************************************
*/
/**
*
*/
static void extram_benchmark(void){
size_t i=0;
time_measurement_t mem_tmu;
void mem_error_cb(memtest_t *memp, testtype e, size_t address) {
(void)memp;
(void)e;
(void)address;
/* memset speed ext */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
memset(extram_start, 0x55, extram_size);
//memset(extram_start, 0x00, extram_size);
chTMStopMeasurementX(&mem_tmu);
memset_speed_ext = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK);
/* memset speed int */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
for (i=0; i<16; i++)
memset(extram_check_buf, i, sizeof(extram_check_buf));
chTMStopMeasurementX(&mem_tmu);
memset_speed_int = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK);
/* memcpy ext2int */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
for (i=0; i<16; i++)
memcpy(extram_check_buf, extram_start+ i * sizeof(extram_check_buf), sizeof(extram_check_buf));
chTMStopMeasurementX(&mem_tmu);
memcpy_speed_ext2int = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK);
/* memcpy int2ext */
chTMObjectInit(&mem_tmu);
memset(extram_check_buf, 0xAA, sizeof(extram_check_buf));
chTMStartMeasurementX(&mem_tmu);
for (i=0; i<16; i++)
memcpy(extram_start + i * sizeof(extram_check_buf), extram_check_buf, sizeof(extram_check_buf));
chTMStopMeasurementX(&mem_tmu);
memcpy_speed_int2ext = 1 / (mem_tmu.cumulative / (double)STM32_SYSCLK);
osalSysHalt("Memory broken");
}
/**
/*
*
*/
#if USE_INFINITE_MEMTEST
static void memstest(void){
static void memtest(void) {
while (true) {
;
memtest_struct.rand_seed = chSysGetRealtimeCounterX();
memtest_run(&memtest_struct, MEMTEST_RUN_ALL);
}
}
#endif /* USE_INFINITE_MEMTEST */
/*
*
*/
static void membench(void) {
membench_run(&membench_ext, &membench_int, &membench_result_int2ext);
membench_run(&membench_int, &membench_ext, &membench_result_ext2int);
}
/*
******************************************************************************
@ -259,11 +261,9 @@ int main(void) {
fsmcSdramInit();
fsmcSdramStart(&SDRAMD, &sdram_cfg);
extram_benchmark();
#if USE_INFINITE_MEMTEST
membench();
memtest();
#endif
/*
* Normal main() thread activity, in this demo it does nothing.

View File

@ -24,4 +24,5 @@
* FSMC SDRAM driver system settings.
*/
#define STM32_USE_FSMC_SDRAM TRUE
#define STM32_SDRAM_USE_FSMC_SDRAM1 TRUE
#define STM32_SDRAM_USE_FSMC_SDRAM1 FALSE
#define STM32_SDRAM_USE_FSMC_SDRAM2 TRUE

View File

@ -0,0 +1,133 @@
/*
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 "membench.h"
#include "memcpy_dma.h"
/*
******************************************************************************
* DEFINES
******************************************************************************
*/
/*
******************************************************************************
* EXTERNS
******************************************************************************
*/
/*
******************************************************************************
* PROTOTYPES
******************************************************************************
*/
/*
******************************************************************************
* GLOBAL VARIABLES
******************************************************************************
*/
volatile int warning_suppressor;
/*
******************************************************************************
******************************************************************************
* LOCAL FUNCTIONS
******************************************************************************
******************************************************************************
*/
/*
* Calculates memory access time in MiB/s.
*/
double speed_mibps(const time_measurement_t *tmu, size_t len) {
double size; // MiB
double time; // sec
size = len;
size /= 1024 * 1024;
time = tmu->last;
time /= STM32_SYSCLK;
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
******************************************************************************
*/
/*
*
*/
void membench_run(membench_t *dest, const membench_t *src,
membench_result_t *result) {
time_measurement_t mem_tmu;
size_t len;
if (src->size < dest->size)
len = src->size;
else
len = dest->size;
/* memset */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
memset(dest->start, 0x55, dest->size);
chTMStopMeasurementX(&mem_tmu);
result->memset = speed_bps(&mem_tmu, dest->size);
/* memcpy */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
memcpy(dest->start, src->start, len);
chTMStopMeasurementX(&mem_tmu);
result->memcpy = speed_bps(&mem_tmu, len);
/* memcmp */
chTMObjectInit(&mem_tmu);
chTMStartMeasurementX(&mem_tmu);
warning_suppressor = memcmp(dest->start, src->start, len);
chTMStopMeasurementX(&mem_tmu);
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();
}

View File

@ -0,0 +1,49 @@
/*
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.
*/
#ifndef MEMBENCH_H_
#define MEMBENCH_H_
/*
*
*/
typedef struct {
void *start;
size_t size;
} membench_t;
/*
* all values in B/s
*/
typedef struct {
uint32_t memset;
uint32_t memcpy;
uint32_t memcpy_dma;
uint32_t memcmp;
} membench_result_t;
/*
*
*/
#ifdef __cplusplus
extern "C" {
#endif
void membench_run(membench_t *dest, const membench_t *src, membench_result_t *ret);
#ifdef __cplusplus
}
#endif
#endif /* MEMBENCH_H_ */

View File

@ -0,0 +1,105 @@
/*
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_MEMCPY_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);
}

View File

@ -0,0 +1,40 @@
/*
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.
*/
#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_ */

View File

@ -68,7 +68,7 @@ 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);
b = dmaStreamAllocate(engine.dma, STM32_MEMCPY_DMA_PRIORITY, NULL, NULL);
osalDbgAssert(!b, "stream already allocated");
}