sturgessb wrote:So I think I need to get the runtime of the ISR down a bit more more. Could using Naked mode help? Can i get rid of those shr() functions, so everything is inline?
I'm not convinced that the execution time of the ISR is causing the occasional unexpected data values. I would be more inclined to suspect interference from other ISRs; in this case the RTC. If you have access to a logic analyzer, you can add instructions to the ISR to facilitate measuring its execution time. That should suggest which hypothesis to pursue. You can probably also set up the logic analyzer to show you if/when the pin change ISR is not being executed timely, a circumstance that could lead to unexpected data values.
As for the
Naked attribute, you can't just add the attribute to the ISR and expect the code to run properly. With that attribute in effect, the compiler omits the generation of some very essential instructions; it becomes your responsibility to include in the ISR all of the essential assembly language instructions to prevent the ISR code from corrupting registers that other code is expecting to remain unchanged. Consequently, use of the
Naked attribute is recommended only for those who a) are skilled assembly language programmers, b) completely understand AVR assembly language, and c) understand the register assumptions relied on by the avr-gcc compiler.
As for the
shr calls, while it is true that I recommended avoiding System Library calls in your ISR, it turns out that not all System Library invocations result in calls to procedures external to the ISR. I've reproduced below the C code generated by the ZBasic compiler for the ISR that you posted. Comparison of this code with the original ZBasic code reveals that the
shr function is realized by using the C operator >>. In fact, there are no obvious function calls anywhere in the generated C code. Further, I claim that the assembly language instructions ultimately produced for the ISR contain no call instructions at all. This can be verified by examining the .lss file (see the discussion in
another post on how to do so).
Code: Select all
ISR(PCINT2_vect)
{
zv_PC_B1 = PINC;
zv_timer2Data[1 - 1] = TCNT2;
zv_PC_TimerVal = *zv_timer2Value;
zv_PC_BitsChanged = zv_PC_B1 ^ zv_PC_B0;
zv_PC_B0 = zv_PC_B1;
{
uint8_t _zv_forEndTemp01 = 3;
for (zv_PC_i = 0; zv_PC_i <= _zv_forEndTemp01; zv_PC_i++)
{
if ((zv_PC_BitsChanged >> 2) == 1)
{
if ((zv_PC_B1 >> 2) == 1)
{
zv_PC_StartTime[zv_PC_i] = zv_PC_TimerVal;
}
else
{
zv_PC_Width[zv_PC_i] = zv_PC_TimerVal - zv_PC_StartTime[zv_PC_i];
}
}
zv_PC_BitsChanged = zv_PC_BitsChanged >> 1;
zv_PC_B1 = zv_PC_B1 >> 1;
}
}
}