This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] [参考译文] [FAQ] TMS320C6678:DDR3读写测试代码(或)如何在 C6678 EVM 或 K2H EVM 板上进行 DDR3测试?

Guru**** 657500 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1244930/faq-tms320c6678-ddr3-read-write-test-code-or-how-to-do-ddr3-test-on-c6678-evm-or-k2h-evm-board

器件型号:TMS320C6678

您好  

请提供"DDR3读写测试代码"(或)如何在 C6678 EVM 或 K2H EVM 板上进行 DDR3测试?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    "DDR3读写测试代码"(或)如何在 C6678 EVM 或 K2H EVM 板上进行 DDR3测试?

    先决条件  :  

    1.下载并安装 BIOSLUXMCSDK-K2 -支持 KeyStone II ARM A15 + DSP C66x 的 SYS/BIOS RTOS 和 Linux OS 的 MCSDK
    版本:来自 http://software-dl.ti.com/sdoemb/sdoemb_public_sw/mcsdk/latest/index_FDS.html 的 MCSDK 3_01_04_07

    (请在建议的路径中安装 SDK:C:\ti\)

    2.下载并安装 CCS 9.3 , https://www.ti.com/tool/download/CCSTUDIO/9.3.0.00012

    (请在建议的路径中安装:C:\ti\)

    3.所讨论的 DDR3 Project 配套资料和源代码可从  http://www.ti.com/lit/zip/sprac04下载

    4.解压缩 sprac04.zip 后、文件夹"keystone2-ddr3-debug-tools"包含 ddr3_eDMA_test 源代码。 (或)
    从以下网址直接下载: e2e.ti.com/.../DDR3_5F00_EDMA_5F00_TEST.zip

    步骤  :   

    =========

    下面的视频中给出了相同的步骤:-  

    1.在 CCS 9.3中、将 DR3_EDMA_TEST 项目导入

    2.在项目属性中,将 pdk_LOC 变量的路径设置为"C:\ti\pdk_keystone2_3_01_04_07\packages"

    3. 在 main.c 的第47行中,将 K2K 更改为 K2H,如下所示

    #include "ti/CSL/device/K2K/src/cslr_device.h"//开普勒特定存储器映射定义需要

    #include "ti/CSL/device/k2h/src/cslr_device.h" //霍金特定的内存映射定义需要

    4.在 CCS 项目属性--> C6000链接器-->文件搜索路径-->中,包含位于 /ti/csl/lib/k2h/c66的 CSL 库:"ti.csl.ae66"。
    在 C6000编译器中-->高级选项-->预定义符号预定义名称--> SOC_C6678

    4.构建并运行

    5.在 C6678 EVM 或 K2H EVM 上测试

    a)"无引导模式"上的 DIP 开关设置

    b)启动目标配置文件并连接目标。 这将运行 GEL 文件。

    c)加载 DR3_EDMA_test 的二进制文件并运行/执行程序

    d)按如下所示观察输出。

    下面的视频中给出了相同的步骤:-  

    (视频将很快上传)

    e2e.ti.com/.../DDR3_5F00_EDMA_5F00_Import_5F00_Project.mp4

    e2e.ti.com/.../DDR3_5F00_EDMA_5F00_Build.mp4

    e2e.ti.com/.../RUn_5F00_DDR3_5F00_test_5F00_C6678.mp4

    =========

    对于 K2H:

    =========

    请遵循相同的过程。 在预定义符号中、设置 SOC_K2H 并生成

    e2e.ti.com/.../Build_5F00_K2H_5F00_DDR3test.mp4

    DDR3测试代码:  

    /******************************************************************************
     * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
     *
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * * Redistributions of source code must retain the above copyright
     * notice, this list of conditions and the following disclaimer.
     *
     * * 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.
     *
     * * Neither the name of Texas Instruments Incorporated 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.
     *
     ******************************************************************************
     *
     *	DDR3 EDMA Test
     *
     *	DDR3 Stress Test for K2 Devices
     *
     *	Revision v1.0, August 2015
     */
    
    // Project Includes ---------------------
    #include <stdio.h>
    #include <stdint.h>
    #include <c6x.h>
    #include "ti/csl/csl.h"							// needed for CSL data type definitions
    #include "ti/csl/device/k2h/src/cslr_device.h" 	// needed for Hawking specific memory map definition
    #include "ti/csl/csl_cacheAux.h"				// needed for cache disable functions
    #include "defines.h"
    
    // Project Defines (User Configurable)---
    #define EDMA_ON_WRITE1	1
    #define EDMA_ON_WRITE2	1
    
    #define EDMA_ON_READ1	1
    #define EDMA_ON_READ2	1
    
    #define DDR3A_TEST		1	//Select either DDR3A OR DDR3B, not both
    #define DDR3B_TEST		0	//Select either DDR3A OR DDR3B, not both
    
    
    // Global Declarations/Definitions ------
    unsigned int test_revision = 1;
    
    unsigned int errcnt;
    unsigned int global_count;
    unsigned int read_val, error_check;
    unsigned int delay = 2;
    unsigned int delay2 = 2000;
    unsigned int delay3a = 50000;
    
    #define L2_C66x0_GLOBAL_ADDR			(0x10800000)
    #define L2_C66x0_GLOBAL_ADDR_2			(0x10808000)
    #define MSMC_MEM_ADDR					(0x0c000000)
    #define MSMC_MEM_ADDR_2					(0x0c010000)
    #define MSMC_MEM_ADDR_3					(0x0c010000)
    #define DDR3B_PHYS_ADDR					(0x60000000)
    
    unsigned int temp_val;
    unsigned int L1_cache_value;
    unsigned int L2_cache_value;
    
    
    
    /************************************************************************************
     *
     * DDR3 MPAX Configuration
     * This function configures the c66x MPAX to point the local address 0x8000_0000
     * to the upper bits of the physical address given by address_start
     *
     -----------------------------------------------------------------------------------*/
    void ddr3_mpax_segment2_setup(unsigned int address_start){
    	XMPAX2_L = address_start | 0x3F;	// Upper Bits of 36-bit address space
    	XMPAX2_H = 0x8000001E;				//Local address of 0x8000_0000
    }
    
    void delay_func(unsigned int delay)
    {
    	unsigned int i;
    	for(i=0;i<delay;i++);
    }
    
    /************************************************************************************
     *
     * DDR3A EDMA Config
     * This function configures the QDMA in the EDMA for burst access. The physical address
     * of the source/destination, and the size of the transfer block are given in the
     * function parameters.
     *
     -----------------------------------------------------------------------------------*/
    void ddr3_edma_config(unsigned int src, unsigned int dst, unsigned int nbytes)
    {
    	unsigned int acnt = nbytes;
    	unsigned int bcnt = 1;
    	unsigned int ccnt = 1;
    
    	// Clear the pending interrupt
    	EDMA_ICR = 0x1;
    
    	// QDMA channel 0 uses parameter set 0, trigger word 7
    	EDMA_QCHMAP0 = 0x1C;
    
    	// Enable QDMA channel 0 */
    	EDMA_QEESR = 0x1;
    
    	// PARAM 0, opt - tciintn, static and syncdim set
    	EDMA_PARAM_0_0 = 0x0010000c;
    
    	// PARAM 1 - source address
    	EDMA_PARAM_0_1 = src;
    
    	// PARAM 2 - bcount, acount
    	EDMA_PARAM_0_2 = (bcnt << 16) | acnt;
    
    	// PARAM 3, destination
    	EDMA_PARAM_0_3 = dst;
    
    	// PARAM 4  dstbidx, srcbidx
    	EDMA_PARAM_0_4 = acnt;
    
    	// PARAM 5 - link
    	EDMA_PARAM_0_5 = 0xffff;
    
    	// PARAM 6 - dstcidx, srccidx
    	EDMA_PARAM_0_6 = 0;
    
    	// PARAM 7 - ccnt
    	EDMA_PARAM_0_7 = ccnt;
    
    	// Wait until complete interrupt
    	while ((EDMA_IPR & 0x1) != 1){
    			delay_func(10);
    		}
    
    	// Scrub Interrupt
    	EDMA_ICR = 0x1;
    
    	// Disable QDMA Channel 0
    	//EDMA_QEECR = 0x1
    
    	// Clear the channel map
    	EDMA_QCHMAP0 = 0x0;
    
    }
    
    /************************************************************************************
     *
     * MSM Populate Function
     * This function serves to populate the MSM of pattern and size given in the function
     * parameters. The data patterns themselves are provided in the defines.h
     * project file.
     *
     -----------------------------------------------------------------------------------*/
    void populate_MSM(unsigned long long int DATA_PATTERN, unsigned int nbytes)
    {
    	unsigned int i;
    
    	// Place First Data Pattern in MSM
    	if (DATA_PATTERN == 1){
    		for(i=0;i<nbytes;i++){
    				(*(unsigned long long int*)(MSMC_MEM_ADDR+(i*0x08))) = DATA_PATTERN_inc[i];
    		}
    	}
    	// Place Second Data Pattern in MSM
    	if (DATA_PATTERN == 2){
    			for(i=0;i<nbytes;i++){
    					(*(unsigned long long int*)(MSMC_MEM_ADDR+(i*0x08))) = DATA_PATTERN_zeroes[i];
    			}
    		}
    }
    
    /************************************************************************************
     *
     * DDR3 Write Read Memory Test
     * This function serves to execute the test write->read, write->read cycles
     *
     -----------------------------------------------------------------------------------*/
    void ddr3a_edma_memory_test(unsigned int DDR3_TEST_START, unsigned int nbytes)
    {
    	unsigned int PATTERN1 = 1;
    	unsigned int PATTERN2 = 2;
    
    	unsigned int TEST_WORDS = 2048;
    	unsigned int TEST_READS = 2;
    	unsigned int ERROR_MAX = 500;
    
    	unsigned int i,j,k,errCnt=0;
    	unsigned long long int doubletemp_val;
    
    	// First pass
    	// Populate MSM with 256 word pattern
    	populate_MSM(PATTERN1, nbytes);
    	errCnt = 0;
    	for(i=0;i<TEST_WORDS;i++){
    	// Block Write MSM->DDR
    #if (EDMA_ON_WRITE1)
    		ddr3_edma_config(MSMC_MEM_ADDR, (DDR3_TEST_START+(i*nbytes*8)), nbytes*8);
    
    #else
    		for(k=0;k<(nbytes);k++){
    			(*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k))) = DATA_PATTERN_inc[k];
    		}
    #endif
    
    	}
    #if(EDMA_ON_READ1)
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Block Read DDR->MSM
    			ddr3_edma_config((DDR3_TEST_START+(i*nbytes*8)), MSMC_MEM_ADDR_2, nbytes*8);
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_2 + (8*k)));
    				if ((doubletemp_val != DATA_PATTERN_inc[k]) && (errCnt < ERROR_MAX)){
    					printf("DMA1 Read Error @ %x, read cycle %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes)+(8*k)), j, DATA_PATTERN_inc[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #else
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			for(k=0;k<nbytes;k++){
    				*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)) = (*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k)));
    			}
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)));
    				if ((doubletemp_val != DATA_PATTERN_inc[k]) && (errCnt < ERROR_MAX)){
    					printf("Read1 Error @ %x, read cycle %d, word %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j,k, DATA_PATTERN_inc[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #endif
    
    	// Populate MSM with 256 word pattern
    	populate_MSM(PATTERN2, nbytes);
    	errCnt = 0;
    	for(i=0;i<TEST_WORDS;i++){
    	// Block Write MSM->DDR
    #if (EDMA_ON_WRITE2)
    		ddr3_edma_config(MSMC_MEM_ADDR, (DDR3_TEST_START+(i*nbytes*8)), nbytes*8);
    #else
    		for(k=0;k<(nbytes);k++){
    			(*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k))) = DATA_PATTERN_zeroes[k];
    		}
    #endif
    
    	}
    #if(EDMA_ON_READ1)
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Block Read DDR->MSM
    			ddr3_edma_config((DDR3_TEST_START+(i*nbytes*8)), MSMC_MEM_ADDR_2, nbytes*8);
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_2 + (8*k)));
    				if ((doubletemp_val != DATA_PATTERN_zeroes[k]) && (errCnt < ERROR_MAX)){
    					printf("DMA2 Read Error @ %x, read cycle %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j, DATA_PATTERN_zeroes[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    
    #else
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			for(k=0;k<nbytes;k++){
    				*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)) = (*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k)));
    			}
    			// Only check first burst (assumes nbytes=256)
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)));
    				if ((doubletemp_val != DATA_PATTERN_zeroes[k]) && (errCnt < ERROR_MAX)){
    					//GPIO_assert();
    					printf("Read2 Error @ %x, read cycle %d, word %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j,k, DATA_PATTERN_zeroes[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #endif
    	if(errCnt >= ERROR_MAX){printf("Error count hit maximum. Not all errors displayed.\n");}
    
    	// Error Conclusion
    	if(errCnt >= 1){
    		printf("Error(s) found in Test iteration.\n");
    	}
    }
    
    void ddr3b_edma_memory_test(unsigned int DDR3_TEST_START, unsigned int nbytes)
    {
    	unsigned int PATTERN1 = 1;
    	unsigned int PATTERN2 = 2;
    
    	unsigned int TEST_WORDS = 2048;
    	unsigned int TEST_READS = 2;
    	unsigned int ERROR_MAX = 5000;
    
    	unsigned int i,j,k,errCnt=0;
    	unsigned long long int doubletemp_val;
    
    	// First pass
    	// Populate MSM with 256 word pattern
    	populate_MSM(PATTERN1, nbytes);
    	errCnt = 0;
    	for(i=0;i<TEST_WORDS;i++){
    	// Block Write MSM->DDR
    #if (EDMA_ON_WRITE1)
    		ddr3_edma_config(MSMC_MEM_ADDR, (DDR3B_PHYS_ADDR+(i*nbytes*8)), nbytes*8);
    #else
    		for(k=0;k<(nbytes);k++){
    			(*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k))) = DATA_PATTERN_inc[k];
    		}
    #endif
    	}
    #if(EDMA_ON_READ1)
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Block Read DDR->MSM
    			ddr3_edma_config((DDR3B_PHYS_ADDR+(i*nbytes*8)), MSMC_MEM_ADDR_2, nbytes*8);
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_2 + (8*k)));
    				if ((doubletemp_val != DATA_PATTERN_inc[k]) && (errCnt < ERROR_MAX)){
    					printf("DMA1 Read Error @ %x, read cycle %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j, DATA_PATTERN_inc[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #else
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Read DDR->MSM
    			for(k=0;k<nbytes;k++){
    				*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)) = (*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k)));
    			}
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)));
    				if ((doubletemp_val != DATA_PATTERN_inc[k]) && (errCnt < ERROR_MAX)){
    					printf("Read1 Error @ %x, read cycle %d, word %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j,k, DATA_PATTERN_inc[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #endif
    
    
    
    	// Second Pass
    	// Populate MSM with 256 word pattern
    	populate_MSM(PATTERN2, nbytes);
    	errCnt = 0;
    	for(i=0;i<TEST_WORDS;i++){
    	// Block Write MSM->DDR
    #if (EDMA_ON_WRITE2)
    		ddr3_edma_config(MSMC_MEM_ADDR, (DDR3B_PHYS_ADDR+(i*nbytes*8)), nbytes*8);
    #else
    		for(k=0;k<(nbytes);k++){
    			(*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes)+(8*k))) = DATA_PATTERN_zeroes[k];
    		}
    #endif
    
    	}
    #if(EDMA_ON_READ2)
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Block Read DDR->MSM
    			ddr3_edma_config((DDR3B_PHYS_ADDR+(i*nbytes*8)), MSMC_MEM_ADDR_2, nbytes*8);
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_2 + (8*k)));
    				if ((doubletemp_val != DATA_PATTERN_zeroes[k]) && (errCnt < ERROR_MAX)){
    					printf("DMA2 Read Error @ %x, read cycle %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j, DATA_PATTERN_zeroes[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    
    #else
    	//Iterate through addresses range for read
    	for(i=0;i<TEST_WORDS;i++){
    		for(j=0;j<TEST_READS;j++){
    			// Read DDR->MSM
    			for(k=0;k<nbytes;k++){
    				*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)) = (*(unsigned long long int*)(DDR3_TEST_START+(i*nbytes*8)+(8*k)));
    			}
    			// Iterate through MSM, make data comparison
    			for(k=0;k<(nbytes);k++){
    				doubletemp_val = (*(unsigned long long int*)(MSMC_MEM_ADDR_3+(8*k)));
    				if ((doubletemp_val != DATA_PATTERN_zeroes[k]) && (errCnt < ERROR_MAX)){
    					//GPIO_assert();
    					printf("Read2 Error @ %x, read cycle %d, word %d. Expected: %.16llx, Got: %.16llx\n",(DDR3_TEST_START+(i*nbytes*8)+(8*k)), j,k, DATA_PATTERN_zeroes[k], doubletemp_val);
    					errCnt++;
    				}
    			}
    		}
    	}
    #endif
    	if(errCnt >= ERROR_MAX){printf("Error count hit maximum. Not all errors displayed.\n");}
    
    	// Error Conclusion
    	if(errCnt >= 1){
    		printf("Error(s) found in Test iteration.\n");
    	}
    }
    
    void main(void) {
    
    	unsigned int counter=0;
    
    	printf("Beginning DDR3 Memory Test (Rev %d)\n", test_revision);
    
    	printf("Turning off L1 Data Cache.\n");
    	CACHE_setL1DSize(CACHE_L1_0KCACHE);
    	printf("Turning off L2 Cache.\n");
    	CACHE_setL2Size(CACHE_0KCACHE);
    
    #if(DDR3A_TEST)
    		printf("Starting DDR3A memory test...\n");
    #elif(DDR3B_TEST)
    		printf("Starting DDR3B memory test...\n");
    #endif
    
    	while(counter < 500){
    #if(DDR3A_TEST)
    		ddr3a_edma_memory_test(0x80000000, 256);
    #elif(DDR3B_TEST)
    		ddr3_mpax_segment2_setup(0x08000000);
    		ddr3b_edma_memory_test(0x80000000, 256);
    		ddr3_mpax_segment2_setup(0x80000000);
    #endif
    		counter++;
    		if((counter % 25) == 0){
    			printf("Test Pulse %d\n", counter/25);
    		}
    	}
    
    
    	printf("Memory Test Completed.\n");
    
    }
    
    
    
    
    
    

    请访问有关"如何计算 KeyStone 器件的"DDR3接口–寄存器"和 Keystone EVM 上的测试/调试"的常见问题解答

    梯形- I

    [常见问题解答] TMS320C6657:如何计算 Keystone I 器件的"DDR3接口–寄存器"和 Keystone I EVM 上的测试/调试。 -处理器论坛-处理器- TI E2E 支持论坛

    梯形- II

    [常见问题解答] 66AK2E05:如何计算 Keystone II 器件的"DDR3接口–寄存器"以及 Keystone II EVM 上的测试/调试。 -处理器论坛-处理器- TI E2E 支持论坛

    此致

    尚卡里