跳至主要内容

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

评论

此博客中的热门博文

【转】VxWorks中的地址映射

在运用嵌入式系统VxWorks和MPC860进行通信系统设计开发时,会遇到一个映射地址不能访问的问题。 缺省情况下,VxWorks系统已经进行了如下地址的映射:   memory地址、bcsr(Board Control and Status)地址、PC_BASE_ADRS(PCMCIA)地址、Internal Memory地址、rom(Flach memory)地址等,但是当你的硬件开发中要加上别的外设时,如(falsh、dsp、FPGA等),对这些外设的访问也是通过地址形式进行读写,如果你没有加相应的地址映射,那么是无法访问这些外设的。   和VxWorks缺省地址映射类似,你也可以进行相应的地址映射。   如下是地址映射原理及实现:   1、 地址映射结构 在Tornado\target\h\vmLib.h文件中 typedef struct phys_mem_desc { void *virtualAddr; void *physicalAddr; UINT len; UINT initialStateMask; /* mask parameter to vmStateSet */ UINT initialState; /* state parameter to vmStateSet */ } PHYS_MEM_DESC; virtualAddr:你要映射的虚拟地址 physicalAddr:硬件设计时定义的实际物理地址 len;要进行映射的地址长度 initialStateMask:可以初始化的地址状态: 有如下状态: #define VM_STATE_MASK_VALID 0x03 #define VM_STATE_MASK_WRITABLE 0x0c #define VM_STATE_MASK_CACHEABLE 0x30 #define VM_STATE_MASK_MEM_COHERENCY 0x40 #define VM_STATE_MASK_GUARDED 0x80 不同的CPU芯片类型还有其特殊状态 initialState:实际初始化的地址状态: 有如下状态: #define VM_STATE_VALID 0x01 #define VM_STATE_VALID_NOT 0x00 #define VM_STATE_WRITA

【转】cs8900网卡的移植至基于linux2.6内核的s3c2410平台

cs8900网卡的移植至基于linux2.6内核的s3c2410平台(转) 2008-03-11 20:58 硬件环境:SBC-2410X开发板(CPU:S3C2410X) 内核版本:2.6.11.1 运行环境:Debian2.6.8 交叉编译环境:gcc-3.3.4-glibc-2.3.3 第一部分 网卡CS8900A驱动程序的移植 一、从网上将Linux内核源代码下载到本机上,并将其解压: #tar jxf linux-2.6.11.1.tar.bz2 二、打开内核顶层目录中的Makefile文件,这个文件中需要修改的内容包括以下两个方面。 (1)指定目标平台。 移植前:         ARCH?= $(SUBARCH) 移植后: ARCH            :=arm (2)指定交叉编译器。 移植前: CROSS_COMPILE ?= 移植后: CROSS_COMPILE   :=/opt/crosstool/arm-s3c2410-linux-gnu/gcc-3.3.4-glibc-2.3.3/bin/arm-s3c2410-linux-gnu- 注:这里假设编译器就放在本机的那个目录下。 三、添加驱动程序源代码,这涉及到以下几个方面。(1)、从网上下载了cs8900.c和cs8900.h两个针对2.6.7的内核的驱动程序源代码,将其放在drivers/net/arm/目录下面。 #cp cs8900.c ./drivers/net/arm/ #cp cs8900.h ./drivers/net/arm/ 并在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下两条语句: __raw_writel(0x2211d110,S3C2410_BWSCON); __raw_writel(0x1f7c,S3C2410_BANKCON3); 注:其原因在"第二部分"解释。 (2)、修改drivers/net/arm/目录下的Kconfig文件,在最后添加如下内容: Config ARM_CS8900    tristate "CS8900 support" depends on NET_ETHERNET && A

【转】多迷人Gtkmm啊

前边已经说过用glade设计界面然后动态装载,接下来再来看看怎么改变程序的皮肤(主题)     首先从 http://art.gnome.org/themes/gtk2 下载喜欢的主题,从压缩包里提取gtk-2.0文件夹让它和我们下边代码生成的可执行文件放在同一个目录下,这里我下载的的 http://art.gnome.org/download/themes/gtk2/1317/GTK2-CillopMidnite.tar.gz     然后用glade设计界面,命名为main.glade,一会让它和我们下边代码生成的可执行程序放在同一个目录下边     然后开始写代码如下: //main.cc #include <gtkmm.h> #include <libglademm/xml.h> int main(int argc, char *argv[]) {     Gtk::Main kit(argc,argv);         Gtk::Window *pWnd;        gtk_rc_parse("E:\\theme-viewer\\themes\\gtk-2.0\\gtkrc");       Glib::RefPtr<Gnome::Glade::Xml> refXml;     try     {         refXml = Gnome::Glade::Xml::create("main.glade");     }     catch(const Gnome::Glade::XmlError& ex)     {         Gtk::MessageDialog dialog("Load glade file failed!", false,       \                                   Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK);         dialog.run();               return 1;     }         refXml->get_widget("main", pWnd);     if(pW