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[i].vecAddr = 0xE59FF000 |
(EXC_VEC_TABLE_BASE - 8 - FIRST_VECTOR);
*(VOIDFUNCPTR *)
(excEnterTbl[i].vecAddr + EXC_VEC_TABLE_BASE - FIRST_VECTOR) =
excEnterTbl[i].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;
}
评论
发表评论