原创 一个外扩储存器的测试程序

2007-1-24 17:01 5773 11 11 分类: 软件与OS
徐爱钧,彭秀华老师书上的一个程序,稍加了点东西,在我的板子上试了,但不是很懂:
第一:

/*  检测地址位是否粘滞高 */
第二:
/*  检测地址位是否粘滞底或短路 */
两个部分的原理不是很懂,在网上也没找到相关资料,欢迎大家讨论,解答!

#define  uint unsigned int
#define uchar unsigned char

/***************************** 数据总线测试函数 ***************************
 * 函数原型:uchar  memTestDataBus(volatile datum xdata * address)
 * 功    能: 对某一固定地址存储器区域写入“移动的”1(walking 1’s),
*           存储器地址由主调函数给定。测试成功返回0,测试失败返回写入值。
*************************************************************************/
uchar memTestDataBus(volatile uchar xdata * address)
{
   uchar pattern;
    printf("begin memDataBus\n");
   for(pattern=1;pattern!=0;pattern<<=1)
   {
         *address = pattern;
           if(*address !=pattern)
           {          
             printf("DataBus failure = %x \n", (uint)pattern);
             return ((uchar)pattern);
           }
   }
  printf("finish DataBus & success!\n");
   return(0);
}
/***************************** 地址总线测试函数 **************************** 函数原型:uchar xdata *memTestAddressBus(volatile datum xdata
*                                  baseAddress, unsigned long nBytes)
* 功    能:对某一段存储器地址范围的地址相关位写入“移动的”1(walking 1’s),    
*           并检查是否发生混淆,测试中将发现单个位地址的错误,譬如“粘滞高、    
*           粘滞低”(stuck-high、stuck-low)以及引脚间短路现象。测试基地址以     
*           及测试范围由主调函数给定。测试成功返回 NULL,测试失败返回发生
*           混淆错误的首地址。
*
* 注:      为了获得最好的测试结果,测试基地址低位部分(LSB)应有足够多的的
*           0以保证单个位地址能够正确变化,例如要测试64KB范围的地址总线,测
*           试基地址应选择在64KB地址范围的边界上,并且应尽可能使被测试的地址
*           范围为2的整数次幂。通过检查存储器内容可以找出其 它错误信息。
*************************************************************************/
uchar xdata *memTestAddressBus(volatile uchar xdata * baseAddress,
                                       unsigned int nBytes)
{

unsigned int addressMask = (nBytes-1);
unsigned int offset;
unsigned int testOffset;

uchar pattern  =(uchar) 0xaa;
uchar antipattern  =(uchar) 0x55;

printf(" begin menTestAddressBus \n");

/* 对每一个2的整数次幂的偏移地址写入默认的测试数据 */
for (offset = sizeof(uchar);(offset & addressMask) != 0;offset <<= 1)
{
    baseAddress[offset] = pattern;
}

/*  检测地址位是否粘滞高 */
testOffset=0;
baseAddress[testOffset] = antipattern;

for (offset = sizeof(uchar); (offset & addressMask) != 0; offset <<= 1)
{
 /*       printf(" offset  = %x  \n",offset);
     printf(" baseAddress  = %x  \n",(uchar xdata *)&baseAddress[offset]);
     printf("  baseAddress  result = %x  \n",baseAddress[offset]);
*/
    if (baseAddress[offset] != pattern )
    {
        printf(" failure at baseAddress  = %x  stuck-high \n",(uint)(uchar xdata *)&baseAddress[offset]);
        return ((uchar xdata *)&baseAddress[offset]);
    }
}

baseAddress[testOffset] =  pattern;

/*  检测地址位是否粘滞底或短路 */

for(testOffset = sizeof(uchar); (testOffset & addressMask) != 0; testOffset <<= 1)
    {
        baseAddress[testOffset] = antipattern;
  
        for (offset = sizeof(uchar); (offset & addressMask) != 0; offset <<= 1)
        {
            if ((baseAddress[offset] != pattern) && (offset != testOffset))
                {
                    printf(" failure at baseAddress  = %x stuck-low\n ",(uchar xdata *)&baseAddress[offset]);
                    return ((uchar xdata *)&baseAddress[testOffset]);
                }
        }               
        baseAddress[testOffset] = pattern;
    }
   printf(" finish  menTestAddressBus \n");
        return (0);
    }
/******************************* 器件测试函数 ******************************
*函数原型:datum xdata *memTestDevice(volatile datum xdata * baseAddress,  
*                                                     unsigned long nBytes)
* 功    能:通过对存储器器件的整个地址单元进行加1和减1来测试其完整性,每一
*           个存储位都要进行写0和写1测试。测试基地址以及测试范围由主调函数
*           给定。测试成功返回NULL,并且整个存储器区域将用0填充。
*           测试失败则返回发生错误的第一个存储器地址。通过检查存储器内容可
*           以找出其它错误信息。
*************************************************************************/
uchar xdata *memTestDevice(volatile uchar xdata * baseAddress,
unsigned int nBytes)
{
  unsigned int offset;
  unsigned int nWords = nBytes / sizeof(uchar);
  uchar pattern;
  uchar antipattern;

   printf(" begin memTestDevice \n ");

  /* 用已知数据填充存储器单元 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
 {
    baseAddress[offset] = pattern;
 }

  /* 检查每个存储器单元并将其取反 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
  {
     if (baseAddress[offset] != pattern)
     {
       printf(" failure at baseAddress  = %x  \n",(uchar xdata *)&baseAddress[offset]);
       return ((uchar xdata *) &baseAddress[offset]);
     }
    antipattern = ~pattern;
    baseAddress[offset] = antipattern;
  }

  /* 检查每个存储器单元并将其清零 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
 {
    antipattern = ~pattern;
    if (baseAddress[offset] != antipattern)
   {
      printf(" failure at baseAddress  = %x  \n",(uchar xdata *)&baseAddress[offset]);
      return ((uchar xdata *) &baseAddress[offset]);
    }
    baseAddress[offset] = 0;
  }
   printf(" finish  menTestDevice \n");
  return (0);
}

/***************************** 存储器测试函数*****************************
* 函数原型:memTest()
* 功    能:测试外部RAM存储器数据总线、地址总线以及RAM器件。
*           测试成功返回0,测试失败返回-1
**************************************************************************/
int memTest(void)
{
  #define BASE_ADDRESS  (volatile uchar xdata *) 0x0000
  #define NUM_BYTES     (6 * 1024)
   printf(" begin memTest \n ");
  if ((memTestDataBus(BASE_ADDRESS) != 0) ||
      (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != 0) ||
      (memTestDevice(BASE_ADDRESS, NUM_BYTES) != 0))
  {
       printf(" failure at memTest function \n ");
       return (-1);
  }
  else
  {
    printf(" success at memTest function  \n");
    return (0);
  }        
}

void main(void)
{
    TMOD=0x20;
    TL1=0xfd;
    TH1=0xfd;
    SCON=0xd8;
    PCON=0x00;

    TR1=1;
    TI=1;
        if( !memTest()) printf(" main test ok \n");
        else printf("main test fail\n");
        while(1);
}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条