阅读:2899回复:1
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.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; } |
|
沙发#
发布于:2004-11-16 10:51
呵呵
不错 :) |
|