📄 memtest.c
字号:
/**************************************************************************
* Copyright (c) 2004 Altera Corporation, San Jose, California, USA. *
* All rights reserved. All use of this software and documentation is *
* subject to the License Agreement located at the end of this file below.*
*************************************************************************/
/**************************************************************************
*
*
* Description
***************
* This is a test program which tests RAM and flash memory.
*
*
* Requirements
****************
* This is a "Hosted" application. According to the ANSI C standard, hosted
* applications can rely on numerous system-services (including properly-
* initialized device drivers and, in this case, STDOUT).
*
* When this program is compiled, code is added before main(), so that all
* devices are properly-initialized and all system-services (e.g. the <stdio>
* library) are ready-to-use. In this hosted environment, all standard C
* programs will run.
*
* A hosted application (like this example) does not need to concern itself
* with initializing devices. As long as it only calls C Standard Library
* functions, a hosted application can run "as if on a workstation."
*
* An application runs in a hosted environment if it declares the function
* main(), which this application does.
*
* This software example requires a STDOUT component such as a UART or
* JTAG UART, a CFI flash component, and 2 RAM components (one for running
* the program, and one for testing) Therefore it can run on the following
* hardware examples:
*
* Nios Development Board, Stratix II Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* DSP Development Board, Stratix II Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* Nios Development Board, Stratix Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* Nios Development Board, Stratix Professional Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* Nios Development Board, Cyclone Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* Nios Development Board, Cyclone II Edition:
* - Standard (DMA RAM test will not run)
* - Full Featured
*
* Note: This example will not run on the Nios II Instruction Set Simulator
*
* Peripherals Exercised by SW
*******************************
* The example's purpose is to test RAM and flash, as well as demonstrate the
* use of the DMA controller and flash API in NiosII.
*
* The RAM test routine performs the following operations:
* 1.) Tests the address and data lines for shorts and opens.
* 2.) Tests byte and half-word access.
* 3.) Tests every bit in the memory to store both '1' and '0'.
* 4.) Tests DMA access to the memory.
*
* IMPORTANT: The RAM test is destructive to the contents of the RAM. For this
* reason, you MUST assure that none of the software sections are located in
* the RAM being tested. This requires that code, data, and exception
* locations must all be in a memory seperate from the one being tested.
* These locations can be adjusted in Nios II IDE and SOPC Builder.
*
*
* The flash tests demonstrate the use of the flash programming API. After the
* flash device specified is opened, the test routine searches for a block in
* the device that is already erased. This prevents any overwriting of
* important data that may be programmed in flash. When an erased block is
* found, the routine performs a test of the flash API calls on that block.
*
* The following API functions are then run to test the flash interface:
*
* - alt_get_flash_info
* This function queries the flash device and collects various information
* about it. In the example, the results of this query are compared to what
* is expected, and an error is reported in the event of a mismatch.
* - alt_write_flash
* This function writes a specified number of bytes to the flash device.
* In the example, this function is called repeatedly in a loop to write a
* lengthy amount of data.
* - alt_read_flash
* This function reads a specified number of bytes of data from the flash
* device. In the example, alt_read_flash is used to read back and test
* all of the writing routines.
* - alt_erase_flash_block
* This function performs a block erase on the flash device.
* - alt_write_flash_block
* This function writes an erase block of data to the flash device.
*
* During the test, status and error information is passed to the user via
* printf's.
*
* Software Files
******************
* memtest.c - Main C file that contains all memory testing code in this
* example.
*
**************************************************************************/
#include <stdio.h>
#include <alt_types.h>
#include <io.h>
#include <system.h>
#include <string.h>
#include "sys/alt_dma.h"
#include "system.h"
#include "sys/alt_flash.h"
#include "sys/alt_flash_dev.h"
/* Mode parameters for Flash Test */
#define TEST 1
#define SHOWMAP 2
#define CFI 3
#define EPCS 4
#define QUIT_WITHOUT_TESTING -1
/* One nice define for going to menu entry functions. */
#define MenuCase(letter,proc) case letter:proc; break;
/* Global DMA "transaction finished" flag */
//#ifdef DMA_NAME
//static volatile int rx_done = 0;
//#endif /* DMA_NAME */
/******************************************************************
* Function: MenuHeader
*
* Purpose: Prints the menu header.
*
******************************************************************/
static void MenuHeader(void)
{
printf("\n\n");
printf(" <----> Nios II Memory Test. <---->\n");
printf("This software example tests the memory in your system to assure it\n");
printf("is working properly. This test is destructive to the contents of\n");
printf("the memory it tests. Assure the memory being tested does not contain\n");
printf("the executable or data sections of this code or the exception address\n");
printf("of the system.\n");
}
/******************************************************************
* Function: MenuBegin
*
* Purpose: Prints the top portion of the menu.
*
******************************************************************/
static void MenuBegin( char *title )
{
printf("\n\n");
printf("----------------------------------\n");
printf("%s\n",title);
printf("----------------------------------\n");
}
/******************************************************************
* Function: MenuItem
*
* Purpose: Prints selection items in the menu, enumerated by the
* specified letter.
*
******************************************************************/
static void MenuItem( char letter, char *name )
{
printf(" %c: %s\n" ,letter, name);
}
/******************************************************************
* Function: GetInputString
*
* Purpose: Parses an input string for the character '\n'. Then
* returns the string, minus any '\r' characters it
* encounters.
*
******************************************************************/
//void GetInputString( char* entry, int size, FILE * stream )
//{
// int i;
// int ch = 0;
//
// for(i = 0; (ch != '\n') && (i < size); )
// {
// if( (ch = getc(stream)) != '\r')
// {
// entry[i] = ch;
// i++;
// }
// }
//}
/******************************************************************
* Function: MenuEnd
*
* Purpose: Prints the end of the menu, then captures and returns
* the user's selection.
*
******************************************************************/
//static int MenuEnd( char lowLetter, char highLetter )
//{
// static char entry[4];
// static char ch, i;
//
// printf(" q: Exit\n");
// printf("----------------------------------\n");
// printf("\nSelect Choice (%c-%c): [Followed by <enter>]",lowLetter,highLetter);
//
// GetInputString( entry, sizeof(entry), stdin );
// if(sscanf(entry, "%c\n", &ch))
// {
// if( ch >= 'A' && ch <= 'Z' )
// ch += 'a' - 'A';
// if( ch == 27 )
// ch = 'q';
// if(ch != 'q' && ( ch < lowLetter && ch > highLetter ))
// {
// printf("\n -ERROR: %c is an invalid entry. Please try again\n", ch);
// }
// }
// return ch;
//}
/******************************************************************
* Function: MemGetAddressRange
*
* Purpose: Gathers a range of memory from the user.
*
******************************************************************/
//static int MemGetAddressRange(int* base_address, int* end_address)
//{
//
// char line[12];
// char i, ch;
//
// while(1)
// {
// /* Get the base address */
// printf("Base address to start memory test: (i.e. 0x800000)\n");
// printf(">");
//
//// fgets(line, sizeof(line), stdin);
// GetInputString( line, sizeof(line), stdin );
//
// /* Check the format to make sure it was entered as hex */
// if(sscanf(line, "0x%X", base_address) != 1)
// {
// printf("%s\n", line);
// printf(" -ERROR: Invalid base address entered. Address must be in the form '0x800000'\n\n");
// continue;
// }
//
// /* Get the end address */
// printf("End Address:\n");
// printf(">");
//
//// fgets(line, sizeof(line), stdin);
// GetInputString( line, sizeof(line), stdin );
//
// /* Check the format to make sure it was entered as hex */
// if(sscanf(line, "0x%X", end_address) != 1)
// {
// printf(" -ERROR: Invalid end address entered. Address must be in the form '0x8FFFFF'\n\n");
// continue;
// }
//
// /* Make sure end address is greater than base address. */
// if (end_address <= base_address)
// {
// printf(" -ERROR: End address must be greater than the start address\n\n");
//
// continue;
// }
// break;
// }
//
// return(0);
//}
/******************************************************************
* Function: MemTestDataBus
*
* Purpose: Tests that the data bus is connected with no
* stuck-at's, shorts, or open circuits.
*
******************************************************************/
static int MemTestDataBus(unsigned int address)
{
unsigned int pattern;
unsigned int ret_code = 0x0;
/* Perform a walking 1's test at the given address. */
for (pattern = 1; pattern != 0; pattern <<= 1)
{
/* Write the test pattern. */
IOWR_32DIRECT(address, 0, pattern);
/* Read it back (immediately is okay for this test). */
if (IORD_32DIRECT(address, 0) != pattern)
{
ret_code = pattern;
break;
}
}
return ret_code;
}
/******************************************************************
* Function: MemTestAddressBus
*
* Purpose: Tests that the address bus is connected with no
* stuck-at's, shorts, or open circuits.
*
******************************************************************/
static int MemTestAddressBus(unsigned int memory_base, unsigned int nBytes)
{
unsigned int address_mask = (nBytes - 1);
unsigned int offset;
unsigned int test_offset;
unsigned int pattern = 0xAAAAAAAA;
unsigned int antipattern = 0x55555555;
unsigned int ret_code = 0x0;
/* Write the default pattern at each of the power-of-two offsets. */
for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1)
{
IOWR_32DIRECT(memory_base, offset, pattern);
}
/* Check for address bits stuck high. */
test_offset = 0;
IOWR_32DIRECT(memory_base, test_offset, antipattern);
for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1)
{
if (IORD_32DIRECT(memory_base, offset) != pattern)
{
ret_code = (memory_base+offset);
break;
}
}
/* Check for address bits stuck low or shorted. */
IOWR_32DIRECT(memory_base, test_offset, pattern);
for (test_offset = sizeof(unsigned int); (test_offset & address_mask) != 0; test_offset <<= 1)
{
if (!ret_code)
{
IOWR_32DIRECT(memory_base, test_offset, antipattern);
for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1)
{
if ((IORD_32DIRECT(memory_base, offset) != pattern) && (offset != test_offset))
{
ret_code = (memory_base + test_offset);
break;
}
}
IOWR_32DIRECT(memory_base, test_offset, pattern);
}
}
return ret_code;
}
/******************************************************************
* Function: MemTest8_16BitAccess
*
* Purpose: Tests that the memory at the specified base address
* can be read and written in both byte and half-word
* modes.
*
******************************************************************/
static int MemTest8_16BitAccess(unsigned int memory_base)
{
int ret_code = 0x0;
/* Write 4 bytes */
IOWR_8DIRECT(memory_base, 0, 0x0A);
IOWR_8DIRECT(memory_base, 1, 0x05);
IOWR_8DIRECT(memory_base, 2, 0xA0);
IOWR_8DIRECT(memory_base, 3, 0x50);
/* Read it back as one word */
if(IORD_32DIRECT(memory_base, 0) != 0x50A0050A)
{
ret_code = memory_base;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -