Using the HC12B32 on-chip timer to determine accurate execution times for functions 

When using any BDM debug tool on the HC12 it is not possible for the BDM unit to provide accurate execution time. The reason is due to the nature of the BDM interface itself. Basically the BDM unit has to poll on-chip registers to determine if the CPU is executing or broke (in BDM mode). The BDM unit communicates with the CPU via a single bit serial interface down which it must shift out commands to read the on-chip register and shift in the result. This process takes a relatively long time (relative to CPU execution speeds!) and so it is not possible for the BDM unit itself to provide accurate execution time information. 

This leads us to look at using the timer built into the HC12 itself. Assuming your program can live without the timer for the duration of the function we can re-program it to measure execution time. The feature of the timer which lets us use it (via BDM) to measure the execution time is its option to freeze the timer unit when the CPU enters BDM mode. So the basis of the procedure is: 

  • get the CPU to the start of the function to time
  • set a breakpoint at the function exit
  • reset the on-chip timer value
  • start execution
  • wait for the CPU to break (enter BDM)
  • read the timer value and convert this to actual execution time
Before going into the details here are a few notes about the on-chip timer itself. 
  • The clock to the timer is PCLK which is 1/2 XTAL. So if your XTAL is 16MHz, PCLK will be 8MHz. So the basic clock going to the timer is 8MHz.
  • The timer is a 16 bit counter with an extra latched bit indicating overflow from FFFF -> 0000.
  • You can set a divisor on the clock to the timer. The divisor can be 1, 2, 4, 8, 16 or 32.
Using the above information we can build a table of max. execution time vs resolution for each of the divisor settings. Remember we are assuming a 16MHz XTAL. 
 
Divisor
Resolution
Max. time period
1
125ns
8.192ms
2
250ns
16.384ms
4
500ns
32.768ms
8
1us
65.636ms
16
2us
131.1072ms (0.131072s)
32
4us
262.144ms (0.262144s)

Which divisor you choose to use will depend on how long the function takes to execute (....which is what you are trying to measure!). You may know an approximate figure for the execution time in which case choose the divisor which gives the timer an adequate max. time period. If you have no idea of execution time and want the best resolution, you should start with the largest divisor and run the timing procedure. If the on-chip timer did no indicate an overflow (TFLG2.TOF) you should re-run the timing procedure with a smaller divisor. When (if) you see the timing procedure ending with the TOF bit set you should up the divisor. (Strictly speaking you do not need to up the divisor - the TOF bit set can be used as the 17th bit of the counter value - since we know the timer only wrapped once). 

To set-up the timer you can use flex's Monitor Points window set to display the Timer Module settings. 

To bring this window up, switch flex toolbars (click the  button on the right hand side of the toolbar) until you see the  button and click the button. 

Here is an image of the settings I used: 

This window shows the state of the timer prior to running the timing procedure. The points to note are: 

  • the timer value TCNT is set to 0
  • the timer is enabled
  • timer is disabled whilst in BDM
  • timer interrupts are disabled
  • the divisor (pre-scaler) TMSK2.PR was set to 1 - set this as appropriate
  • the overflow flag is clear TFLG2.TOF=0. If this flag is set write a 1 to it to clear it.

 

Example timing procedure

This procedure was run on the Noral 68HC12B32 Evaluation Board modified to run at 8MHz. Part of the demo program supplied by Noral has a routine called FFT. We wish to know how long this function takes to execute. The procedure is as follows: 
  • start flex and load the example program into the on-chip flash (the external RAM does not work at 8MHz)
  • make sure flex is configured to use the on-chip breakpoint for execution breakpoints
  • reset the CPU
  • set an execution break on the start of the FFT routine (in module ffti)
  • start execution and wait for the breakpoint to fire
  • initialise the on-chip timer as per the window display above
  • set an execution break on the return from FFT
  • start execution and wait for the breakpoint to fire
  • read the value of TCNT from the on-chip timer
The TCNT value I got was 0x58DA (22746). Since we used a divisor of 1 each count represents 125ns. Since the TOF bit is noted to be clear we can calculate the execution time as 22746 x 125ns = 2.843250ms

 

Overhead and Accuracy

Using the above procedure to step instructions gives us some idea as to the overhead involved in the timer reading. Clearly it takes some time from the completion of execution of the instruction to the freeze of the timer value. By experimenting with stepping single instructions it would appear that 4 clock counts (at divisor = 1) are added to the actual execution time i.e. timing a single cycle instruction gets us a timer count of 5, a 3 cycle instruction a timer count of 7. This 4 count overhead will only need be taken into account when timing very small code sequences. 
Return to Application Notes Menu Page top of page

Noral -The Company | More Information | Jobs, Vacancies | Distributors | Flex Tools | FREE 68000 Simulator | File Download | Press Releases | Application Notes | Home