完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,Xilinxusers。
那里的任何人都成功地使用了micrlaze中的快速中断。 我已经使用普通中断实现了一些我的设计,但它的运行速度并不是很快,所以我尝试使用快速。 XPS部分任务似乎相当微不足道。 您可以像以前一样在Intc块中选择“包括快速中断逻辑”来连接它。 我选择了级别IRQ使用率和高。 我也选择包括所有寄存器。 我在这里没有别的事可做吗? 使用普通中断硬件很好,所以这些简单的更改对于快速应该没问题吗? 在SDK中的代码上。 免责声明:我在C垃圾。然而......我的setup_intc函数(减去所有错误检查)看起来像htis: XIntc_Initialize(& InterruptController,XPAR_INTC_0_DEVICE_ID); XIntc_ConnectFastHandler(& InterruptController,XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR,(XInterruptHandler)PromInterruptHandler); XIntc_Start(& InterruptController,XIN_REAL_MODE); XIntc_Enable(& InterruptController,XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR); Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XIntc_InterruptHandler,& InterruptController); Xil_ExceptionEnable(); 它与普通中断内容之间唯一的区别是XIntc_ConnectFastHandler函数,而不仅仅是使用XIntc_Connect ...... 当我运行代码并触发中断时,一切都开始了。 在中断进程完成后,我希望IRQ由processor_ack位清零,IAR寄存器由寄存器写入清零。 第一个事件确实发生(processor_ack = b“01”),它清除IRQ并运行处理程序(PromInterruptHandler)。 第二个事件永远不会发生(processor_ack = b“10”)。 因此,我的中断控制器在ISR寄存器中停留了一段时间,因为IAR写指令永远不会到达...(据我所知,intc中有一个状态机卡在一个被捕获的状态 第一个ack位的到来,但它还没有看到第二个。它会留在那里indefinitley并忽略新的中断,因为它这样做)。 希望这能激发一些有关微博中断的有趣讨论! 希望有人可以发现我错过的东西!任何专业知识都会非常感激。 谢谢大家。 人。 以上来自于谷歌翻译 以下为原文 Hi fellow Xilinx users. Anyone out there had success using fast interrupts in microblaze. I've implemented a bit of my design using a normal interrupt but it doesn't really run quickly enough, so I am trying the fast instead. The XPS part of the task seems fairly trivial. You just hook it up as before with "Include Fast interrupt logic" selected in the Intc block. I've selected level IRQ usage and High. I've selected to include all registers too. There's nothing else I need to do here is there? The hardware was fine using normal interrupts, so should be fine for fast with these simple changes? Onto the code in SDK. Disclaimer: I'm rubbish at C. Nevertheless... My setup_intc function (minus all the error checking) looks something like htis: XIntc_Initialize(&InterruptController, XPAR_INTC_0_DEVICE_ID); XIntc_ConnectFastHandler(&InterruptController, XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR, (XInterruptHandler)PromInterruptHandler); XIntc_Start(&InterruptController, XIN_REAL_MODE); XIntc_Enable(&InterruptController, XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR); Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XIntc_InterruptHandler, &InterruptController); Xil_ExceptionEnable(); The only differerence between that and the normal interrupt stuff is the XIntc_ConnectFastHandler function, instead of just using XIntc_Connect... When I run code and trigger the interrupt, everything starts off OK. After the interrupt is processes, I expect the IRQ to be cleared by the processor_ack bits and the IAR register to be cleared by a register write. The first event does occur (processor_ack = b"01"), which clears the IRQ and runs the handler (PromInterruptHandler). The second event never occurs though (processor_ack = b"10"). Thus my interrupt controller gets left with a bit in the ISR register stuck high, since the IAR write instruction never arrives... (As far as I can tell, there's a state machine inside the intc that gets stuck in a state where it's captured the arrival of the first ack bit, but it hasn't yet seen the second. It will stay there indefinitley and ignore new interrupts as it does so). Hope this stimulates some interesting discussion about interrupt in microblaze! And hopefully someone can spot what I've missed! Any expertise would be much appreciated. Thanks all. Al. |
|
相关推荐
12个回答
|
|
嗨,戈兰,
谢谢你的回复。 你是现货! 我有这条线,但忘记取消注释(并且实际上并不知道它是什么)。 我把它改成了这个,所以我不能再忘记了...我有点害怕快速的冲突,因为他们在执行期间做了一些可怕的事情。 他们是否可靠地保存环境,或者您需要注意哪些事项? #ifdef FAST_INTERRUPT_ENABLE_ void PromInterruptHandler()__ attribute __((fast_interrupt)); //用于快速中断。 #其他 void PromInterruptHandler(); //正常中断... #万一 和这个... #ifdef FAST_INTERRUPT_ENABLE_ Status = XIntc_ConnectFastHandler(& InterruptController,XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR,(XFastInterruptHandler)PromInterruptHandler); #其他 Status = XIntc_Connect(& InterruptController,XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR,(XInterruptHandler)PromInterruptHandler,(void *)0); #万一 谢啦。 发现得好! 人。 以上来自于谷歌翻译 以下为原文 Hi Goran, Thanks for the response. You are spot on! I had that line in, but forgot to uncomment it (and didn't really know what it was for to be honest). I've changed it to this so I can't forget again... I'm a little afraid of fast interruts, incase they do something horrendous during execution. Do they preserve the context reliably, or are there things you need to be careful about? #ifdef FAST_INTERRUPT_ENABLE_ void PromInterruptHandler() __attribute__ ((fast_interrupt)); // for fast interrupt. #else void PromInterruptHandler(); // for normal interrupt... #endif and this... #ifdef FAST_INTERRUPT_ENABLE_ Status = XIntc_ConnectFastHandler(&InterruptController, XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR, (XFastInterruptHandler)PromInterruptHandler); #else Status = XIntc_Connect(&InterruptController, XPAR_AXI_INTC_0_AXI_PROM_STREAM_0_INTERRUPT_INTR, (XInterruptHandler)PromInterruptHandler, (void *)0); #endif Thanks man. Well spotted! Al. |
|
|
|
嗨,
太好了,我可以帮助你。 正常中断和快速中断处理的上下文保存相同。 然而,快速中断机制需要更少的上下文保存,因为MicroBlaze直接跳转到特定中断的处理程序。 通常情况下,快速中断处理会使中断延迟提高10倍。 戈兰 以上来自于谷歌翻译 以下为原文 Hi, Great that I could help you. The context saving is the same for normal interrupt and fast interrupt handling. However the fast interrupt mechanism needs much less context saving since MicroBlaze is jumping directly to the handler for a specific interrupt. You would normally see a 10x better interrupt latency with fast interrupt handling. Göran |
|
|
|
hiii举报
正如您所说的正常中断和快速中断的上下文保存相同,我们是否需要保存上下文或提供的ISE Intc驱动程序是否具有该特定功能? 如果提供了驱动程序,在哪个功能呢? 以上来自于谷歌翻译 以下为原文 hiii As you are telling context saving is same for both normal interrupts and fast interrupts, do we need to save the context or does the ISE provided Intc driver is having that particular function? If driver is provided with, In which function does this? |
|
|
|
嗨,
通过正常中断,上下文保存由intc设备驱动程序完成。 通过快速中断,用户需要添加函数属性fast_interrupt以使GCC保存上下文。 这是因为快速中断正在跳过intc设备驱动程序并直接跳转到特定中断的中断处理程序。 戈兰 以上来自于谷歌翻译 以下为原文 Hi, With normal interrupt, context saving is done by the intc device driver. With fast interrupt, the user needs to add the function attribute fast_interrupt to make GCC to save the context. This is due to that fast interrupts is skipping over the intc device driver and jumps directly to the interrrupt handler for the specific interrupt. Göran |
|
|
|
Hiii goran,
你说的是intc驱动程序执行上下文保存,但是在xintc_intr.c源文件中,他们提到过“thedriver假定在调用中断控制器中断处理程序之前已经保存了处理器的上下文,然后在处理程序返回之后恢复” 。 这意味着用户需要保存上下文或默认GCC负责这一点? 提前致谢 以上来自于谷歌翻译 以下为原文 Hiii goran, You are saying that the intc driver does context saving, But In xintc_intr.c source file, they have mentioned like "the driver assumes that the context of the processor has been saved prior to the calling of the Interrupt Controller interrupt handler and then restored after the handler returns". It means user need to save the context or By default GCC takes care of that? Thanks in advance |
|
|
|
嗨,
GCC负责这一点。 如果使用汇编程序进行编程,则需要注意所使用的寄存器。 戈兰 以上来自于谷歌翻译 以下为原文 Hi, GCC takes care of that. If you programming in assembler, you need to take care of the registers that you uses. Göran |
|
|
|
|
|
|
|
嗨,
我对这个话题还有其他问题。 我应该解释中断的使用。 第一个具有高优先级,触发复制ADC数据。 我想为此使用快速中断处理。 第二个,优先级低,只是重新启动配置部分。 问题是: 我应该将两个中断初始化为快速中断吗? 或者,有没有理由在标准模式下仍然使用第一个? 问候, 本杰明 以上来自于谷歌翻译 以下为原文 Hi, I do have a further questions to this topic. I should explain the use of interrupts. The first, with high priority, trigger to copy ADC data. I would like to use fast interrupt handling for this. The second, with low priority, just to restart the configuration part. The question: Should I initialize both interrupts as fast interrupt? Or, is there a reason to still use the first in standard mode? Regards, Benjamin |
|
|
|
嗨,
如果您已经有快速中断,则与快速中断模式相比,使用标准中断模式没有任何实际好处。 快速中断需要更多的硬件资源(LUT),但如果您已经拥有它,则将其用于所有中断的成本并不高。 戈兰 以上来自于谷歌翻译 以下为原文 Hi, There are no real benefit of using the standard interrupt mode compared to fast interrupt mode if you already have the fast interrupt. Fast interrupt requires more hardware resources (LUTs) but if you already have it doesn't cost more for using it for all interrupts. Göran |
|
|
|
嗨,
感谢您的快速回复。 是否可以包括快速和标准模式,包括不同的中断处理程序功能? 例如: void StandardInterruptHandler(void * DeviceId) { u32 BaseAddress = IOModule.CfgPtr-> BaseAddress; / ** void FastInterruptHandler(void * DeviceId)__ attribute __((fast_interrupt)) {//没有选择,只需运行必要的,只有一个中断被定义为快速 runADC(); } void init(void) { XIOModule_Initialize(安培; IOModule,0); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)InternInterruptHandler,(void *)0); XIOModule_ConnectFastHandler(&amp; IOModule,u8 Id,FastInterruptHandler); microblaze_enable_interrupts(); } 我不确定如何使用ID / DeviceID声明。 如果您愿意,请修改部件:-) 哪些功能才能正确运行? 问候, 本杰明 以上来自于谷歌翻译 以下为原文 Hi, thanks for your soon response. Would it be possible to include both the fast and the standard mode, with including different Interrupt Handler functions? For example: void StandardInterruptHandler(void *DeviceId){ u32 BaseAddress = IOModule.CfgPtr->BaseAddress; /**< BaseAddress of IOModule */ u32 IntrStatus; /**< Interrupt Status of IRQ Handler */ IntrStatus = XIOModule_GetIntrStatus(BaseAddress); if ((IntrStatus & IRQ1) != 0 ) {...} if ((IntrStatus & IRQ2) != 0 ) {...}} void FastInterruptHandler(void *DeviceId) __attribute__ ((fast_interrupt)){ // without selection, just run that is necessary, only one interrupt is defined as fast runADC();} void init(void){ XIOModule_Initialize(&IOModule,0); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)InternInterruptHandler,(void*) 0); XIOModule_ConnectFastHandler(&IOModule, u8 Id, FastInterruptHandler); microblaze_enable_interrupts();} I am not sure of how I have to use the ID/DeviceID declaration. Please, modify parts if you like to :-) Which functions are really necessary to run correctly? Regards, Benjamin[size=1 2 3 4 5 6 7] |
|
|
|
嗨,
至少,它有效。 下面是一些代码,我是怎么做的? 亲切的问候和愉快的周末, 本杰明 void StandardInterruptHandler(void) { u32 BaseAddress = IOModule.CfgPtr-> BaseAddress; / ** ChannelEnableReg; // activeCh =(u8)((stateFiFo&amp;〜(stateFiFo >> 8))&amp; 0x000F); // activeCh&amp; = 0x0F; //与上面相同,但需要少350 ns activeCh =(XIomodule_In8(0xC0000310)&amp;〜(XIomodule_In8(0xC0000311))); if((configReg&amp; 1)== 0) { if((activeCh&amp; 1)!= 0) { pFPGA-> Res4 [3066] ^ = 1; // @hlaben:应该删除测试LED输出 // pFPGA-> FiFo32Ch [0] = pFPGA-> CalibDataCh [0]; //与上面相同,但需要1.66我们少,总和6.7我们少(现在:1.1我们,在7.8我们之前) XIomodule_Out32(0xC0000200,(XIomodule_In32(0xC0004000))); } if((activeCh&amp; 2)!= 0) { // pFPGA-> FiFo32Ch [1] = pFPGA-> CalibDataCh [1]; XIomodule_Out32(0xC0000204,(XIomodule_In32(0xC0004004))); } if((activeCh&amp; 4)!= 0) { // pFPGA-> FiFo32Ch [2] = pFPGA-> CalibDataCh [2]; XIomodule_Out32(0xC0000208,(XIomodule_In32(0xC0004008))); } if((activeCh&amp; 8)!= 0) { // pFPGA-> FiFo32Ch [3] = pFPGA-> CalibDataCh [3]; XIomodule_Out32(0xC000020C,(XIomodule_In32(0xC000400C))); } } 其他 { if((activeCh&amp; 1)!= 0) { pFPGA-> Res4 [3066] ^ = 1; // @hlaben:应该删除测试LED输出 // pFPGA-> FiFo16Ch [0] =(u16)(pFPGA-> CalibDataCh [0] >> 2); //与上面相同,但需要少960 ns,总和少3.82 us(现在:1.28 us,5.1 us之前) XIomodule_Out16(0xC0000210,(u16)((XIomodule_In32(0xC0004000))>> 2)); } if((activeCh&amp; 2)!= 0) { // pFPGA-> FiFo16Ch [1] =(u16)(pFPGA-> CalibDataCh [1] >> 2); XIomodule_Out16(0xC0000212,(u16)((XIomodule_In32(0xC0004004))>> 2)); } if((activeCh&amp; 4)!= 0) { // pFPGA-> FiFo16Ch [2] =(u16)(pFPGA-> CalibDataCh [2] >> 2); XIomodule_Out16(0xC0000214,(u16)((XIomodule_In32(0xC0004008))>> 2)); } if((activeCh&amp; 8)!= 0) { // pFPGA-> FiFo16Ch [3] =(u16)(pFPGA-> CalibDataCh [3] >> 2); XIomodule_Out16(0xC0000216,(u16)((XIomodule_In32(0xC000400C))>> 2)); } } pFPGA-> FiFoUnlockReg = 1; pFPGA-> Res4 [3066] ^ = 1; // @hlaben:应该删除测试LED输出 } //初始化中断处理程序 XIOModule_Initialize(安培; IOModule,0); XIOModule_Start(安培; IOModule); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)StandardInterruptHandler,(void *)0); XIOModule_EnableIntr(IOModule.CfgPtr-> BaseAddress,USEDIRQ); XIOModule_ConnectFastHandler(&amp; IOModule,16,(XFastInterruptHandler)InterruptADC); microblaze_enable_interrupts(); 以上来自于谷歌翻译 以下为原文 Hi, at least, it works. Below some code, how I did? Kind regards and nice weekend, Benjamin void StandardInterruptHandler(void){u32 BaseAddress = IOModule.CfgPtr->BaseAddress; /**< BaseAddress of IOModule */u32 IntrStatus; /**< Interrupt Status of IRQ Handler *//* Get the interrupts that are waiting to be serviced */IntrStatus = XIOModule_GetIntrStatus(BaseAddress);/* Service each interrupt that is active and enabled by checking each * bit in the register from LSB to MSB which corresponds to an interrupt * input signal */if ((IntrStatus & CONFIGIRQ) != 0){// disable all defined interrupts, no need of interrupt with higher priority during configuration//XIOModule_DisableIntr(BaseAddress, ALLIRQ);systemState = CONFIG;XIOModule_AckIntr(BaseAddress, CONFIGIRQ);}}void InterruptADC(void){u8 activeCh;//u16 stateFiFo;//stateFiFo = pFPGA->ChannelEnableReg;//activeCh = (u8)((stateFiFo & ~(stateFiFo >> 8)) & 0x000F);//activeCh &= 0x0F;// same as above, but needs 350 ns lessactiveCh = (XIomodule_In8(0xC0000310) & ~(XIomodule_In8(0xC0000311)));if ((configReg & 1) == 0){if ((activeCh & 1) != 0){pFPGA->Res4[3066] ^= 1; // @hlaben: Test LED output, should be removed//pFPGA->FiFo32Ch[0] = pFPGA->CalibDataCh[0];// same as above, but needs 1.66 us less, in sum 6.7 us less (now: 1.1 us, before 7.8 us)XIomodule_Out32(0xC0000200, (XIomodule_In32(0xC0004000)));}if ((activeCh & 2) != 0){//pFPGA->FiFo32Ch[1] = pFPGA->CalibDataCh[1];XIomodule_Out32(0xC0000204, (XIomodule_In32(0xC0004004)));}if ((activeCh & 4) != 0){//pFPGA->FiFo32Ch[2] = pFPGA->CalibDataCh[2];XIomodule_Out32(0xC0000208, (XIomodule_In32(0xC0004008)));}if ((activeCh & 8) != 0){//pFPGA->FiFo32Ch[3] = pFPGA->CalibDataCh[3];XIomodule_Out32(0xC000020C, (XIomodule_In32(0xC000400C)));}}else{if ((activeCh & 1) != 0){pFPGA->Res4[3066] ^= 1; // @hlaben: Test LED output, should be removed//pFPGA->FiFo16Ch[0] = (u16)(pFPGA->CalibDataCh[0] >> 2);// same as above, but needs 960 ns less, in sum 3.82 us less (now: 1.28 us, before 5.1 us)XIomodule_Out16(0xC0000210, (u16)((XIomodule_In32(0xC0004000)) >> 2));}if ((activeCh & 2) != 0){//pFPGA->FiFo16Ch[1] = (u16)(pFPGA->CalibDataCh[1] >> 2);XIomodule_Out16(0xC0000212, (u16)((XIomodule_In32(0xC0004004)) >> 2));}if ((activeCh & 4) != 0){//pFPGA->FiFo16Ch[2] = (u16)(pFPGA->CalibDataCh[2] >> 2);XIomodule_Out16(0xC0000214, (u16)((XIomodule_In32(0xC0004008)) >> 2));}if ((activeCh & 8) != 0){//pFPGA->FiFo16Ch[3] = (u16)(pFPGA->CalibDataCh[3] >> 2);XIomodule_Out16(0xC0000216, (u16)((XIomodule_In32(0xC000400C)) >> 2));}}pFPGA->FiFoUnlockReg = 1;pFPGA->Res4[3066] ^= 1; // @hlaben: Test LED output, should be removed} // initialize Interrupt Handlers XIOModule_Initialize(&IOModule,0); XIOModule_Start(&IOModule); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)StandardInterruptHandler,(void*) 0); XIOModule_EnableIntr(IOModule.CfgPtr->BaseAddress, USEDIRQ); XIOModule_ConnectFastHandler(&IOModule, 16, (XFastInterruptHandler)InterruptADC); microblaze_enable_interrupts(); |
|
|
|
in header..void StandardInterruptHandler(void)__ attribute __((interrupt_handler)); void InterruptADC(void)__ attribute __((fast_interrupt));
以上来自于谷歌翻译 以下为原文 in header.. void StandardInterruptHandler(void) __attribute__ ((interrupt_handler)); void InterruptADC(void) __attribute__ ((fast_interrupt)); |
|
|
|
只有小组成员才能发言,加入小组>>
2415 浏览 7 评论
2821 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2292 浏览 9 评论
3372 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2458 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
1080浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
579浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
440浏览 1评论
2000浏览 0评论
723浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 09:58 , Processed in 1.695200 second(s), Total 100, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号