Microchip C18 上的正常中断延迟和上下文保存时间是多少?
我正在使用 Microchip C18 编译器,并且在发生中断时,我在 ISR 代码开始运行之前经历了相当长的延迟。
作为一个实验,这是我的主要功能:
while(1)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
作为中断处理程序,我使用从某些示例复制的代码(我不知道为什么这样做):
#pragma interrupt high_isr
void high_isr(void)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
我正在通过 SPI 接收字节,并且在收到字节后不久,主循环停止。然后,在 ISR 代码开始运行之前,会延迟 16.5 µs。那是 165 个指令周期!
我知道有一些与中断相关的上下文保存,并且低优先级情况更糟中断。我已禁用 IPEN 并且仅使用高优先级向量。 165 条指令是上下文保存的正常持续时间吗?
I am using the Microchip C18 compiler and on occurrence of an interrupt I am experiencing a quite long delay before the ISR code starts running.
As an experiment, this is in my main function:
while(1)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
As interrupt handler I am using this code I copied from some example (I don't know why it's done this way):
#pragma interrupt high_isr
void high_isr(void)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
I am receiving bytes via SPI and shortly after a byte is received, the main loop stops. Then a delay of 16.5 µs follows before the ISR code starts running. That is 165 instruction cycles!
I know there is some context saving associated with interrupts and that it's even worse with low priority interrupts. I have disabled IPEN and I am using only the high priority vector. Is 165 instructions a normal duration for context saving?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在某些情况下,中断开销可能和您一样大!
看看这个。
Under some circumstances interrupt overhead can be great as yours!
Take a look at this.
从 PIC 上的中断获得良好性能的关键是最大限度地减少所需的上下文保存/恢复代码的范围。在许多情况下,这意味着用机器代码编写中断处理程序的时间关键部分。在至少有一些可专门用于中断使用的无组寄存器的部分上(我真的不喜欢 Microchip 决定吞噬大部分或全部公共组用于 FSR2 寻址,而不是分配例如 15 个字节用于 FSR2 寻址,每个 7 个字节用于FSR0 和 FSR1 寻址,以及每个 FSR 的一个“神奇操作”寄存器 [我很乐意讨论此类事情的想法])有时可以在没有任何上下文的情况下完成在常见情况下保存/恢复。例如,在我的一个 14 位 PIC 项目中,我需要每 1000 个时钟周期进行一次中断。因此,在禁用 RTCC 预分频器的情况下,我的中断类似于:
请注意,有 3/4 的时间,中断将在执行总共三个指令后返回,从下面执行的任何代码总共花费大约 6 个周期。
The key to getting good performance from interrupts on the PIC is to minimize the extent of required context save/restore code required. In many cases, this means writing the time-critical parts of the interrupt handler in machine code. On parts which have at least some unbanked registers that can be devoted to interrupt use (I really dislike Microchip's decision to gobble up most or all of the common bank for FSR2 addressing, instead of allocating e.g. 15 bytes for FSR2 addressing, 7 bytes each for FSR0 and FSR1 addressing, and one "magic manipulation" register for each FSR [I'd love to chat about ideas for such things]) it's sometimes possible to get by without any context save/restore in the common case. For example, in one of my 14-bit PIC projects, I needed an interrupt every 1000 clock cycles. So with RTCC prescalar disabled, my interrupt was something like:
Note that 3/4 of the time, an interrupt will return after executing a whopping total of three instructions, taking a total of about 6 cycles from whatever code was executing underneath.