From 5ee86601a172384191c3ea92d72785711c7cc201 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 27 Mar 2013 00:03:25 +0000 Subject: Add apps/system/ramtest. I will use this for the LPC1788 SDRAM bringup git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5791 42af7a65-404d-4744-a932-0658087f49c3 --- apps/system/ramtest/Kconfig | 10 + apps/system/ramtest/Makefile | 115 ++++++++++ apps/system/ramtest/ramtest.c | 483 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 608 insertions(+) create mode 100644 apps/system/ramtest/Kconfig create mode 100644 apps/system/ramtest/Makefile create mode 100644 apps/system/ramtest/ramtest.c (limited to 'apps/system/ramtest') diff --git a/apps/system/ramtest/Kconfig b/apps/system/ramtest/Kconfig new file mode 100644 index 000000000..5e7e479f0 --- /dev/null +++ b/apps/system/ramtest/Kconfig @@ -0,0 +1,10 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config SYSTEM_RAMTEST + bool "RAM Test" + default n + ---help--- + Enable a simple RAM test. diff --git a/apps/system/ramtest/Makefile b/apps/system/ramtest/Makefile new file mode 100644 index 000000000..a208f6e5b --- /dev/null +++ b/apps/system/ramtest/Makefile @@ -0,0 +1,115 @@ +############################################################################ +# apps/system/ramtest/Makefile +# +# Copyright (C) 2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +ifeq ($(WINTOOL),y) +INCDIROPT = -w +endif + +# USB Monitor Application + +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 768 + +ASRCS = +CSRCS = ramtest.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: context depend clean distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + $(Q) touch .built + +# Register application + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)ramtest.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,"ramtest",$(PRIORITY),$(STACKSIZE),ramtest_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)ramtest.bdat +else +context: +endif + +# Create dependencies + +.depend: Makefile $(SRCS) + $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep + diff --git a/apps/system/ramtest/ramtest.c b/apps/system/ramtest/ramtest.c new file mode 100644 index 000000000..120b1732c --- /dev/null +++ b/apps/system/ramtest/ramtest.c @@ -0,0 +1,483 @@ +/**************************************************************************** + * apps/system/ramtest/ramtest.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_SYSTEM_RAMTEST + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RAMTEST_PREFIX "RAMTest: " + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ramtest_s +{ + uint8_t width; + uintptr_t start; + size_t size; + uint32_t mask; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void show_usage(FAR const char *progname, int exitcode) +{ + printf("\nUsage: %s [-w|h|b] \n", progname); + printf("\nWhere:\n"); + printf(" starting address of the test."); + printf(" number of memory locations."); + printf(" -w Sets the width of a memory location to 32-bits."); + printf(" -h Sets the width of a memory location to 16-bits (default)."); + printf(" -b Sets the width of a memory location to 8-bits."); + exit(exitcode); +} + +static void parse_commandline(int argc, char **argv, FAR struct ramtest_s *info) +{ + FAR char *ptr; + int option; + + while ((option = getopt(argc, argv, "whb")) != ERROR) + { + if (option == 'w') + { + info->width = 32; + info->mask = 0xffffffff; + } + else if (option == 'h') + { + info->width = 16; + info->mask = 0x0000ffff; + } + else if (option == 'b') + { + info->width = 8; + info->mask = 0x000000ff; + } + else + { + printf(RAMTEST_PREFIX "Unrecognized option: '%c'\n", option); + show_usage(argv[0], EXIT_FAILURE); + } + } + + /* There should be two parameters remaining on the command line */ + + if (optind >= argc) + { + printf(RAMTEST_PREFIX "Missing required arguments\n"); + show_usage(argv[0], EXIT_FAILURE); + } + + info->start = (uintptr_t)strtoul(argv[optind], &ptr, 16); + if (*ptr != '\0'); + { + printf(RAMTEST_PREFIX "Invalid \n"); + show_usage(argv[0], EXIT_FAILURE); + } + + optind++; + + if (optind >= argc) + { + printf(RAMTEST_PREFIX "Missing \n"); + show_usage(argv[0], EXIT_FAILURE); + } + + info->size = (size_t)strtoul(argv[optind], &ptr, 10); + if (*ptr != '\0'); + { + printf(RAMTEST_PREFIX "Invalid \n"); + show_usage(argv[0], EXIT_FAILURE); + } + + if (optind != argc) + { + printf(RAMTEST_PREFIX "Too many arguments\n"); + show_usage(argv[0], EXIT_FAILURE); + } +} + +static void write_memory(FAR struct ramtest_s *info, uint32_t value) +{ + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < info->size; i++) + { + *ptr++ = value; + } + } + else if (info->width == 16) + { + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < info->size; i++) + { + *ptr++ = (uint16_t)value; + } + } + else /* if (info->width == 8) */ + { + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < info->size; i++) + { + *ptr++ = (uint8_t)value; + } + } +} + +static void verify_memory(FAR struct ramtest_s *info, uint32_t value) +{ + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < info->size; i++) + { + if (*ptr != value) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %08x Expected %08x\n", + ptr, *ptr, value); + } + + ptr++; + } + } + else if (info->width == 16) + { + uint16_t value16 = (uint16_t)(value & 0x0000ffff); + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < info->size; i++) + { + if (*ptr != value16) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %04x Expected %04x\n", + ptr, *ptr, value16); + } + + ptr++; + } + } + else /* if (info->width == 8) */ + { + uint8_t value8 = (uint8_t)(value & 0x000000ff); + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < info->size; i++) + { + if (*ptr != value8) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %02x Expected %02x\n", + ptr, *ptr, value8); + } + + ptr++; + } + } +} + +static void marching_ones(FAR struct ramtest_s *info) +{ + uint32_t pattern = 0x00000001; + + while (pattern != 0) + { + write_memory(info, pattern); + verify_memory(info, pattern); + pattern <<= 1; + pattern &= info->mask; + } +} + +static void marching_zeros(FAR struct ramtest_s *info) +{ + uint32_t pattern = 0xfffffffe; + + while (pattern != 0xffffffff) + { + write_memory(info, pattern); + verify_memory(info, pattern); + pattern <<= 1; + pattern |= 1; + pattern |= ~info->mask; + } +} + +static void write_memory2(FAR struct ramtest_s *info, uint32_t value_1, uint32_t value_2) +{ + size_t even_size = info->size & ~1; + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + *ptr++ = value_1; + *ptr++ = value_2; + } + } + else if (info->width == 16) + { + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + *ptr++ = (uint16_t)value_1; + *ptr++ = (uint16_t)value_2; + } + } + else /* if (info->width == 8) */ + { + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + *ptr++ = (uint8_t)value_1; + *ptr++ = (uint8_t)value_2; + } + } +} + +static void verify_memory2(FAR struct ramtest_s *info, uint32_t value_1, uint32_t value_2) +{ + size_t even_size = info->size & ~1; + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + if (ptr[0] != value_1 || ptr[1] != value_2) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %08x and %08x\n", + ptr, ptr[0], ptr[1]); + printf(RAMTEST_PREFIX " Expected: %08x and %08x\n", + value_1, value_2); + } + + ptr += 2; + } + } + else if (info->width == 16) + { + uint16_t value16_1 = (uint16_t)(value_1 & 0x0000ffff); + uint16_t value16_2 = (uint16_t)(value_2 & 0x0000ffff); + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + if (ptr[0] != value16_1 || ptr[1] != value16_2) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %04x and %04x\n", + ptr, ptr[0], ptr[1]); + printf(RAMTEST_PREFIX " Expected: %04x and %04x\n", + value16_1, value16_2); + } + + ptr += 2; + } + } + else /* if (info->width == 8) */ + { + uint8_t value8_1 = (uint8_t)(value_1 & 0x000000ff); + uint8_t value8_2 = (uint8_t)(value_2 & 0x000000ff); + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < even_size; i += 2) + { + if (ptr[0] != value8_1 || ptr[1] != value8_2) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %02x and %02x\n", + ptr, ptr[0], ptr[1]); + printf(RAMTEST_PREFIX " Expected: %02x and %02x\n", + value8_1, value8_2); + } + + ptr += 2; + } + } +} + +static void pattern_test(FAR struct ramtest_s *info, uint32_t pattern1, uint32_t pattern2) +{ + write_memory2(info, pattern1, pattern2); + verify_memory2(info, pattern1, pattern2); +} + +static void write_addrinaddr(FAR struct ramtest_s *info) +{ + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint32_t value32 = (uint32_t)((uintptr_t)ptr); + *ptr++ = value32; + } + } + else if (info->width == 16) + { + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); + *ptr++ = value16; + } + } + else /* if (info->width == 8) */ + { + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint8_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); + *ptr++ = value8; + } + } +} + +static void verify_addrinaddr(FAR struct ramtest_s *info) +{ + size_t i; + + if (info->width == 32) + { + uint32_t *ptr = (uint32_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint32_t value32 = (uint32_t)((uintptr_t)ptr); + if (*ptr != value32) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %08x Expected %08x\n", + ptr, *ptr, value32); + } + + ptr++; + } + } + else if (info->width == 16) + { + uint16_t *ptr = (uint16_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint16_t value16 = (uint16_t)((uintptr_t)ptr & 0x0000ffff); + if (*ptr != value16) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %04x Expected %04x\n", + ptr, *ptr, value16); + } + + ptr++; + } + } + else /* if (info->width == 8) */ + { + uint8_t *ptr = (uint8_t*)info->start; + for (i = 0; i < info->size; i++) + { + uint16_t value8 = (uint8_t)((uintptr_t)ptr & 0x000000ff); + if (*ptr != value8) + { + printf(RAMTEST_PREFIX "ERROR: Address %p Found: %02x Expected %02x\n", + ptr, *ptr, value8); + } + + ptr++; + } + } +} + +static void addr_in_addr(FAR struct ramtest_s *info) +{ + write_addrinaddr(info); + verify_addrinaddr(info); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int ramtest_main(int argc, char **argv) +{ + struct ramtest_s info; + + /* Setup defaults and parse the command line */ + + info.width = 16; + info.mask = 0x0000ffff; + parse_commandline(argc, argv, &info); + + /* Perform the memory tests */ + + marching_ones(&info); + marching_zeros(&info); + pattern_test(&info, 0x55555555, 0xaaaaaaaa); + pattern_test(&info, 0x66666666, 0x99999999); + pattern_test(&info, 0x33333333, 0xcccccccc); + addr_in_addr(&info); + return 0; +} + +#endif /* CONFIG_SYSTEM_RAMTEST */ -- cgit v1.2.3