Arduino frequency measurement
You've clearly given this some thought, but some of the low-level details are tripping you up. I'm going to focus on one aspect of your problem, and maybe this will lead you into thinking in the right way to solve the rest of it.

After doing a little research, I learned that


Interrupts are not nested on the ATMEGA328 (at least, not by default)
Timer 2 is an 8-bit timer
Pin change interrupts have a higher priority than timer interrupts.


In your pin change ISR, you capture the state of the hardware and software counters:

// take quick snapshot
temp_TCNT2 = TCNT2;
TCNT2 = 0; // reset timer
temp_FREQovfcount = FREQovfcount;
FREQovfcount = 0; // clear overflow counter


One problem is that you're getting readings of around 1660, when calculation shows that a frequency of 9.543 kHz should give you readings of about 1676. You're consistently losing 16 clocks somewhere.

The first statement above reads the TCNT2 hardware register and stores it in an int variable. One problem is that TCNT2 is an 8-bit unsigned variable, while in the Arduino environment an unsigned int is a 16-bit variable. Furthermore, you've declared the variable as volatile, which means that the compiler must generate code to extend the value to 16 bits and then write it to memory as 2 bytes. Then you clear the register.

This code between the reading and the clearing of the register could easily account for the missing 16 clocks.

It would be better to write this ISR in assembly so that you know exactly what code is running in such a time-critical area. Or at least, examine the compiler output and tweak the source code to minimize the number of instructions it generates here. For example, just changing

volatile unsigned int temp_TCNT2 = 0;


to

register unsigned char temp_TCNT2;


and making it local to the ISR (it isn't used anywhere else) will probably get you close.

Better still, don't clear the timer at all &mdash; let it free-run and take the difference between the current and previous values. This way, you eliminate any possibility of "dead time", but this does make the job of resolving overflow events somewhat tricky.