Chinaunix首页 | 论坛 | 博客
  • 博客访问: 41576
  • 博文数量: 19
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-19 11:33
文章分类
文章存档

2010年(10)

2009年(9)

我的朋友

分类: 嵌入式

2010-01-06 09:55:36

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

点灯调试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[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;
}

阅读(854) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~