fs44b0x
驱动牛犊
驱动牛犊
  • 注册日期2004-11-13
  • 最后登录2005-09-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2824回复:1

S3C44B0X的BSP调试记录,包含部分vxworks的中断处理源码!

楼主#
更多 发布于:2004-11-15 13:43
点灯调试S3C44B0 vxworks  BSP
1. romInit的调试方法:
 /*************点亮0号端口的LED,验证内存配置是否成功 *******************/        
LDR r1, L$_PCONC    
LDR r2, L$_PCONC_VALUE    
STR    r2,  [r1]
        
    LDR r1, L$_PUPC    
LDR r2, L$_PUPC_VALUE  
STR    r2,  [r1]

LDR r1, L$_PDATC    
LDR r2, L$_PDATC_LED0    
STR    r2, [r1]

    B .     /*为了防止后面语句的影响,用该语句进行无限循环,使用ADS进行内存访问 */

/*****************************************************************************/        
2. C函数的调试方法
#define    IOPDATA    (*(volatile unsigned *)(0x1d20014))
IOPDATA  = 0xFFF8;
while(1);
/***************** 代码运行到此函数,2004-10-10,9:39  ******************/
  
3. 中断处理函数的调试方法:验证时钟中断服务程序是否工作正常
   void sysClkInt (void)
{

     if(intTimers == 0)
     {
       IOPDATA  = 0xFFF2;  /*点亮LED1*/
       intTimers = 1;
     }
     else
     {
       IOPDATA  = 0xFFF1; /* 熄灭LED1 */
       intTimers = 1;
     }
     if (sysClkRoutine != NULL)
(* sysClkRoutine) (sysClkArg);
}



关于xworks中断的处理函数实现:
STATUS intEnable ( int level /* level to be enabled */ )
{
    return (*sysIntLvlEnableRtn) (level);   /*在自己的BSP中实现 */
}


STATUS intDisable( int level /* level to be disabled */ )
{
    return (*sysIntLvlDisableRtn) (level);
}


STATUS intConnect
(
  VOIDFUNCPTR* vector, /* vector id */
    VOIDFUNCPTR routine, /* interrupt service routine */
    int argument /* argument for isr */
    )
    {
    int vecNum;
    VEC_ENTRY *pVec;

    if (intVecTable == NULL)
return ERROR; /* library not initialized */

    vecNum = IVEC_TO_INUM (vector);

    /* check vector specified is in range allocated */

    if (vecNum < 0 || vecNum >= intNumVectors)
return ERROR;

    pVec = &intVecTable[vecNum];

    if (routine == NULL)
{
routine = intUninitVec;
argument = vecNum;
}

    pVec->routine = routine;
    pVec->arg = argument;

    return OK;
    }



STATUS intLibInit
    (
    int numLevels, /* number of levels */
    int numVectors, /* number of vectors */
    int mode /* type of interrupt handling */
    )
    {
    int i;

    if (intVecTable == NULL)
{

/* Allocate and initialize the vector table */

intVecTable = malloc (numVectors * sizeof (VEC_ENTRY));

if (intVecTable != NULL)
   {
   intNumVectors = numVectors;

 /* initialize table with uninitialized vec handler */

   for (i = 0; i < numVectors; i++)
{
intConnect (INUM_TO_IVEC(i), NULL, 0);
}

   /* connect architecture interrupt exception */

   if (mode & INT_PREEMPT_MODEL)
EXC_CONNECT_INTR_RTN (intIntRtnPreempt);
   else
EXC_CONNECT_INTR_RTN (intIntRtnNonPreempt);

   return OK;
   }

return ERROR; /* malloc failure */
}

    return OK; /* already initialized */
}




STATUS excVecInit (void)
    {
    FAST int i;


    /* initialise ARM exception mode registers */

    armInitExceptionModes ();


    /* initialise hardware exception vectors */

    for (i = 0; i < NUM_EXC_VECS; ++i)
{
/*
* Each vector contains a LDR PC,[PC,#offset] instruction to
* load the PC from a table of addresses stored at
* EXC_VEC_TABLE_BASE. This allows full 32 bit addressing rather
* than 12 bit (MOV #) or 24 bit (B).
*/
*(UINT32 *)excEnterTbl.vecAddr = 0xE59FF000 |
(EXC_VEC_TABLE_BASE - 8 - FIRST_VECTOR);
*(VOIDFUNCPTR *)
   (excEnterTbl.vecAddr + EXC_VEC_TABLE_BASE - FIRST_VECTOR) =
   excEnterTbl.fn;
}


    /*
     * Branch through zero has to be handled differently if it is
     * possible for address 0 to be be branched to in ARM and Thumb
     * states (no LDR pc,[pc,#n] in Thumb state). The following
     * instruction, installed at address 0, will cause an undefined
     * instruction exception in both ARM and Thumb states.
     */

    *(UINT32 *)EXC_OFF_RESET = 0xE7FDDEFE;


    /* now sort out the instruction cache to reflect the changes */

    CACHE_TEXT_UPDATE(EXC_OFF_RESET, EXC_OFF_IRQ + 4);


    /* install default IRQ handler */

    _func_armIrqHandler = excIntHandle;


    return OK;
}


中断的调试:
1. 验证romInit.s能否捕获中断,中断控制器能否正确产生中断,在romInit.s的IRQ中断处理入口处点灯:
_romIRQ:
      SUB sp, sp, #4
      STMFD sp!, {r1}

/******点亮1号端口的LED,验证是否捕获到中断 **************************************/        
  LDR r1, L$_PDATC    
LDR r2, L$_PDATC_LED0  
STR r2, [r1]      
/****************************************************************************************/            
      
      LDR r1, L$_IRQVec
      LDR r1, [r1]
      STR r1, [sp, #4]
LDMFD sp!, {r1, pc}




为了验证中断发生时,是否可以跳转到intEnter中处理,写了如下测试代码替代intEnter:
void sysKeyInt(void)
{
       FS44B0XIntLvlVecAck(21,21);

       if(IOPDATA&(0x08)  != 0x08)
           IOPDATA  = 0xFFF8;   /*点亮LED*/
       else
           IOPDATA  = 0xFFF1; /* 熄灭LED */  
}
void FS44B0XExcVecSet(void)
{
int i;
i=(int)&excEnterUndef;
*(volatile int *)(S3C_EXE_BASE+0x0) = i;

        i=(int)&excEnterSwi;
*(volatile int *)(S3C_EXE_BASE+0x4) = i;

i=(int)&excEnterPrefetchAbort;
*(volatile int *)(S3C_EXE_BASE+0x8) = i;

i=(int)&excEnterDataAbort;
*(volatile int *)(S3C_EXE_BASE+0xC) = i;

i=(int)&sysKeyInt; /* intEnt; */
*(volatile int *)(S3C_EXE_BASE+0x14) = i;

return;
}


为了验证intEnter函数是否被执行,添加如下调试代码:
STATUS  FS44B0XIntLvlVecChk
   (
    int* pLevel,  /* ptr to receive old interrupt level */
    int* pVector  /* ptr to receive current interrupt vector */
    )
{



    int newLevel;
    int intPendMask = 0x2000000;  /*0~26位为正常中断,27位保留 */
    int count;
    UINT32 isr;
 
    int i;
    for(i=0;i<5;i++)
    {
       Delay(2000);
       Led_DisplayOn(0x01);    /* VPINT(FS44B0X_PDATC)= 0xFFF2; 点亮第1盏灯*/
       Delay(2000);
       Led_DisplayOn(0x02);    /* VPINT(FS44B0X_PDATC)= 0xFFF4;            */
    }
    Led_DisplayOn(0x02);      

    /* Read pending interrupt register and mask undefined bits */

    FS44B0X_INT_REG_READ (FS44B0X_INT_PEND, newLevel);

 
    /*
     * Step through the bits looking for a 1. This *will* terminate.
     * We could use ffsLsb() for this if we don't mind the function call
     * overhead
     */
    for (count = 0, isr = 25; count < FS44B0X_INT_NUM_LEVELS; count++)
    {
if (intPendMask & newLevel)
break;
isr--;
intPendMask >>= 1;
   }
   *pVector = 21;

  /* Acknowledge the interrupt as given in FS44B0X sample code */
  /* FS44B0X_INT_REG_WRITE(FS44B0X_INT_PEND,(1 << isr)); */

   FS44B0X_INT_REG_WRITE(FS44B0X_I_ISPC,0xFFFFFFF);  /*清除IRQ_MASK中的悬挂位*/
   return OK;
}

bugs_bunny8
驱动牛犊
驱动牛犊
  • 注册日期2002-12-01
  • 最后登录2015-07-27
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-11-16 10:51
呵呵
不错
:)
游客

返回顶部