跳至主要内容

【转】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;
}

评论

此博客中的热门博文

【转】smb协议栈使用示例

/*  * * uncdownload.c  * *  * * Utility for downloading files from SMB shares using libsmbclient  * *  * * Copyright(C) 2006 Sophos Plc, Oxford, England.  * *  * * This program is free software; you can redistribute it and/or modify it under the terms of the  * * GNU General Public License Version 2 as published by the Free Software Foundation.  * *  * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  * * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  * * See the GNU General Public License for more details.  * *  * * You should have received a copy of the GNU General Public License along with this program; if not,  * * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  * *  * */ # include < sys / types . h > # include < sys / time . h > # include ...

【转】Ether Types

Ether Types (last updated 2008-09-09) NOTE: Please see [RFC5342] for current information and registration procedures. This registry will be revised soon and will be replaced with up-to-date information. Many of the networks of all classes are Ethernets (10Mb) or Experimental Ethernets (3Mb). These systems use a message "type" field in much the same way the ARPANET uses the "link" field. If you need an Ether Type, contact: IEEE Registration Authority IEEE Standards Department 445 Hoes Lane Piscataway, NJ 08854 Phone +1 732 562 3813 Fax: +1 732 562 1571 Email: <ieee-registration-authority& ieee.org > http://standards.ieee.org/regauth/index.html The following list of EtherTypes is contributed unverified information from various sources. Another list of EtherTypes is maintained by Michael A. Patton and is accessible at: <URL: http://www.cavebear.com/CaveBear/Ethernet/ > <URL: ftp://ftp.cavebear.com/pub/Ethernet-codes > Assign...

【转】udp编程实例

UDP通讯实例 2008-04-29 15:30:05 / 个人分类: linux C编程 UDP协议的几点好处: 1.UDP不要求保持一个连接; 2.UDP没有因接收方认可收到数据包(或者当数据包没有正确抵达而自动重传)而带来的开销; 3.设计UDP的目的是用于短应用和控制信息; 4.在一个数据包接一个数据包的基础上,UDP要求的 网络 带宽比TCP更小。 UDP的几个缺点: 1.程序员必须创建代码检测传输错误并进行重传(如果应用程序要求这样做); 2.程序员必须把大数据包分片。 code: <1> /* * sender.c--UDP protocol example */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> int port = 6789; int main() {     int socket_descrīptor;     int iter = 0;     char buf[80];     struct sockaddr_in address;     /* Initialize socket address structure for Interner Protocols */     bzero(&address, sizeof(address)); // empty data structure     address.sin_family = AF_INET;     address.sin_addr.s_addr = inet_addr("127.0.0.1");     address...