eboot 中断只响应一次

xingxing_y 2009-06-21 10:27:51
我想在eboot中加入USB中断的方式下载功能。现在遇到这么一个问题,中断触发时,响应中断,进入中断处理函数,然后退出中断。等下一个中断到来时,就无法响应中断了。中断处理函数退出时,已经开了中断。也就是说,只响应一次中断,请问,这是什么原因呢?请不吝赐教,谢谢!
...全文
112 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
taoyongjh 2009-08-10
  • 打赏
  • 举报
回复
请问你的问题解决了吗?
我也遇到中断只响应一次的问题,只在插上USB的时候才发生。
后来看了一下是USBS.S这部分汇编中的最后一句没有执行,但不知道该怎么解决。
LEAF_ENTRY IsrHandler

; sub sp,sp,#4 ;decrement sp(to store jump address)
sub lr, lr, #4
stmfd sp!, {r0-r12,lr}
mov r0, lr
bl IsrUsbd
ldmfd sp!, {r0-r12,lr}

movs pc, lr
ENDP ; |IsrHandler|

END
xingxing_y 2009-06-21
  • 打赏
  • 举报
回复
问题究竟出现在哪儿呢?堆栈太小?0x1a00不小了吧?退出中断时,也开中断了啊
中断响应代码如下,红色部分为中断执行部分
void HandlerUsbd(void)
{

U8 usbdIntpnd,epIntpnd;
U8 saveIndexReg=pUDCreg->INDEX;
pINTreg->rINTMSK |=BIT_USBD; //close usbd interrupt
ClearPending(BIT_USBD);//clear interrput
EdbgOutputDebugString ( "usb_interrupt!\r\n");

usbdIntpnd=pUDCreg->UIR;
epIntpnd=pUDCreg->EIR;

if(usbdIntpnd&SUSPEND_INT)
{
pUDCreg->UIR=SUSPEND_INT;
EdbgOutputDebugString( "SUSPEND_INT\r\n");
}
if(usbdIntpnd&RESUME_INT)
{
pUDCreg->UIR=RESUME_INT;
EdbgOutputDebugString("RESUME_INT\r\n");
}
if(usbdIntpnd&RESET_INT)
{
pUDCreg->UIR=RESET_INT; //RESET_INT should be cleared after ResetUsbd().
EdbgOutputDebugString( "RESET_INT\r\n");
ReconfigUsbd();
PrepareEp1Fifo();

}

if(epIntpnd&EP0_INT)
{
EdbgOutputDebugString( "EP0_INT\r\n");
pUDCreg->EIR=EP0_INT;
Ep0Handler();
}
if(epIntpnd&EP1_INT)
{
EdbgOutputDebugString( "EP1_INT\r\n");
pUDCreg->EIR=EP1_INT;
Ep1Handler();
}

if(epIntpnd&EP2_INT)
{
pUDCreg->EIR=EP2_INT;
EdbgOutputDebugString( "EP2_INT\r\n"); //not implemented yet
//Ep2Handler();
}

if(epIntpnd&EP3_INT)
{
EdbgOutputDebugString( "EP3_INT\r\n");
pUDCreg->EIR=EP3_INT;
Ep3Handler();
}

if(epIntpnd&EP4_INT)
{
EdbgOutputDebugString( "EP4_INT\r\n");//not implemented yet
pUDCreg->EIR=EP4_INT;
//Ep4Handler();
}
pUDCreg->INDEX=saveIndexReg;

pINTreg->rINTMSK &=~ (BIT_USBD); //open usbd interrupt


}
void ReconfigUsbd(void)
{
// *** End point information ***
// EP0: control
// EP1: bulk in end point
// EP2: not used
// EP3: bulk out end point
// EP4: not used
DbgPrintf("reconfigusbd start!\r\n");
pUDCreg->PMR=PWR_REG_DEFAULT_VALUE; //disable suspend mode

pUDCreg->INDEX=0;
pUDCreg->MAXP=FIFO_SIZE_8; //EP0 max packit size = 8
pUDCreg->EP0ICSR1=EP0_SERVICED_OUT_PKT_RDY|EP0_SERVICED_SETUP_END;
//EP0:clear OUT_PKT_RDY & SETUP_END

pUDCreg->INDEX=1;
#if (EP1_PKT_SIZE==32)
pUDCreg->MAXP=FIFO_SIZE_32; //EP1:max packit size = 32
#else
pUDCreg->MAXP=FIFO_SIZE_64; //EP1:max packit size = 64
#endif
pUDCreg->EP0ICSR1=EPI_FIFO_FLUSH|EPI_CDT;
pUDCreg->ICSR2=EPI_MODE_IN|EPI_IN_DMA_INT_MASK|EPI_BULK; //IN mode, IN_DMA_INT=masked
pUDCreg->OCSR1=EPO_CDT;
pUDCreg->OCSR2=EPO_BULK|EPO_OUT_DMA_INT_MASK;

pUDCreg->INDEX=2;
pUDCreg->MAXP=FIFO_SIZE_64; //EP2:max packit size = 64
pUDCreg->EP0ICSR1=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;
pUDCreg->ICSR2=EPI_MODE_IN|EPI_IN_DMA_INT_MASK; //IN mode, IN_DMA_INT=masked
pUDCreg->OCSR1=EPO_CDT;
pUDCreg->OCSR2=EPO_BULK|EPO_OUT_DMA_INT_MASK;

pUDCreg->INDEX=3;
#if (EP3_PKT_SIZE==32)
pUDCreg->MAXP=FIFO_SIZE_32; //EP3:max packit size = 32
#else
pUDCreg->MAXP=FIFO_SIZE_64; //EP3:max packit size = 64
#endif
pUDCreg->EP0ICSR1=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;
pUDCreg->ICSR2=EPI_MODE_OUT|EPI_IN_DMA_INT_MASK; //OUT mode, IN_DMA_INT=masked
pUDCreg->OCSR1=EPO_CDT;
//clear OUT_PKT_RDY, data_toggle_bit.
//The data toggle bit should be cleared when initialization.
pUDCreg->OCSR2=EPO_BULK|EPO_OUT_DMA_INT_MASK;

pUDCreg->INDEX=4;
pUDCreg->MAXP=FIFO_SIZE_64; //EP4:max packit size = 64
pUDCreg->EP0ICSR1=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;
pUDCreg->ICSR2=EPI_MODE_OUT|EPI_IN_DMA_INT_MASK; //OUT mode, IN_DMA_INT=masked
pUDCreg->OCSR1=EPO_CDT;
//clear OUT_PKT_RDY, data_toggle_bit.
//The data toggle bit should be cleared when initialization.
pUDCreg->OCSR2=EPO_BULK|EPO_OUT_DMA_INT_MASK;


pUDCreg->EIR=EP0_INT|EP1_INT|EP2_INT|EP3_INT|EP4_INT;
pUDCreg->UIR=RESET_INT|SUSPEND_INT|RESUME_INT;

//EP0,1,3 & reset interrupt are enabled
pUDCreg->EIER=EP0_INT|EP1_INT|EP3_INT;
pUDCreg->UIER=RESET_INT;
//ep0State=EP0_STATE_INIT;

pINTreg->rSRCPND = pINTreg->rSRCPND; // clear all interrupt
pINTreg->rINTPND = pINTreg->rINTPND; // clear all interrupt
DbgPrintf("reconfigusbd end!\r\n");

}
void PrepareEp1Fifo(void)
{
int i;
U8 in_csr1;
pUDCreg->INDEX=1;
in_csr1=pUDCreg->EP0ICSR1;

for(i=0;i<EP1_PKT_SIZE;i++)
ep1Buf[i]=(U8)(transferIndex+i);
WrPktEp1(ep1Buf,EP1_PKT_SIZE);
SET_EP1_IN_PKT_READY();
DbgPrintf("PrepareEp1Fifo ing \r\n");
}
gooogleman 2009-06-21
  • 打赏
  • 举报
回复
一样的道理。

或者看看 优龙的ADS bootloader吧。
xingxing_y 2009-06-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 gooogleman 的回复:]
你看看wince下的ISR部分是怎么做的,找个成功例子参考一下。
[/Quote]
这是在bootloader中的中断,还没有进系统呢!
在没有初始化中断堆栈时,进不了中断,初始化堆栈后,只能响应一次中断
gooogleman 2009-06-21
  • 打赏
  • 举报
回复
你看看wince下的ISR部分是怎么做的,找个成功例子参考一下。
xingxing_y 2009-06-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gooogleman 的回复:]
没有重新使能中断啊。哈哈

中断完毕要重新使能哦。
[/Quote]
中断退出时,
已经开中断了啊?
gooogleman 2009-06-21
  • 打赏
  • 举报
回复
没有重新使能中断啊。哈哈

中断完毕要重新使能哦。
xingxing_y 2009-06-21
  • 打赏
  • 举报
回复
以下是输出的打印信息,红色为进入中断时的寄存器信息,蓝色是退出中断时的寄存器信息,粉红色显示为中断再一次产生
usb_interrupt!
pUDCreg->EIR=0x0,pUDCreg->UIR=0x4

pINTreg->rSRCPND is 0x2000000

pINTreg->rINTMOD is 0x0

pINTreg->rINTMSK is 0xFDFFFFFF

pINTreg->rINTPND is 0x2000000

pINTreg->rINTOFFSET is 0x19

pINTreg->rSUBSRCPND is 0x3

pINTreg->rINTSUBMSK is 0x7FF

RESET_INT
reconfigusbd start!
reconfigusbd end!
PrepareEp1Fifo ing
pUDCreg->EIR=0x0,pUDCreg->UIR=0x0

pINTreg->rSRCPND is 0x0

pINTreg->rINTMOD is 0x0

pINTreg->rINTMSK is 0xFDFFFFFF

pINTreg->rINTPND is 0x0

pINTreg->rINTOFFSET is 0x0

pINTreg->rSUBSRCPND is 0x3

pINTreg->rINTSUBMSK is 0x7FF


pINTreg->rSRCPND is 0x2000000

pINTreg->rINTMOD is 0x0

pINTreg->rINTMSK is 0xFDFFFFFF

pINTreg->rINTPND is 0x2000000

pINTreg->rINTOFFSET is 0x19

pINTreg->rSUBSRCPND is 0x3

pINTreg->rINTSUBMSK is 0x7FF

pUDCreg->EIR is 0x1

pUDCreg->UIR is 0x4

pUDCreg->EIER is 0x1F

pUDCreg->UIER is 0x4

HandlerUsbd is 0x8C03FD04

19,504

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧