|
|
View previous topic :: View next topic |
Author |
Message |
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
Execution time: how to check length of code block |
Posted: Sun Jun 26, 2011 9:39 am |
|
|
I'm looking for a way to measure the code execution time inside the PIC, I'd like to see on the field how much does it take for some routine/procedure to execute, so I can quickly spot slow procedures and inefficient programming blocks.
I'm doing this because I have a timer interrupt, and I need to be sure the code in the main is fully executed and is "idle" waiting for the timer to overflow.
Code: | timer starts
{
potentially
slow
code
}
// wait time
while(flag==1) // sync point, wait for timer interrupt to enable the flag |
I'd like to quantify the "wait time" over here.
_ PIC16F690
_ Internal 8Mhz clock
_ setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
_ set_timer1(65435)
So, overflow events should be 1 every 50us (100*0.5us, correct? - 4 clock cycles for instruction rule).
I started trying to lower/raise pins of the PIC and attaching a LED (naive).. but it's no use, cause the timer is obviously too fast to spot :\
I tried to count instruction following a possible branch of execution.. again, no use, the program is changing path too often, let alone complex instruction (floats).
Any suggestion?
Tnx.
P.S. I don't have a scope :( _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun Jun 26, 2011 11:30 am |
|
|
I would set a pin when the "potentially slow code" is done, and clear the pin when the timing cycle ends. Put a scope on the pin and if the pulse width of this signal gets too narrow you are running out of excess time in your loop. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Sun Jun 26, 2011 1:10 pm |
|
|
SherpaDoug wrote: | I would set a pin when the "potentially slow code" is done, and clear the pin when the timing cycle ends. Put a scope on the pin and if the pulse width of this signal gets too narrow you are running out of excess time in your loop. |
YES! the code is already there (the LED one).
but.. I don't have a scope (wrote before in the final "P.S."), it's just a home project.
Maybe, I could do something with pickit2 and its digital signal probe mode, I'll look what kind of resolution is up to. _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jun 26, 2011 1:23 pm |
|
|
An alternative is to run the code in the MPLAB simulator. Using the Stopwatch function of the Simulator you can measure the execution time and number of instruction cycles. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Fri Jul 01, 2011 3:06 am |
|
|
These are all useful info, but I was looking at something implementable "on the field".
I'm trying now to raise and lower a PIN during the wait period to analyze, then externally I've attached a capacitor where I can measure the voltage across it.
It's not perfect, but I have a rough measure of the wait time (given I know the frequency, given the period I'm analyzing is the ON/OFF period of a pwm signal, and given the cycle is periodic). _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Fri Jul 01, 2011 5:22 am |
|
|
UPDATE
:lol:
In the CCS common asked question guide section there's just the right answer!
How much time do math operations take?
20 mhz PIC16
int8 11.1 [us]
int16 47.2 [us]
int32 132 [us]
float 178 [us]
int8 23.2 [us]
int16 70.8 [us]
int32 239.2 [us]
float 330 [us] _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Sat Jul 02, 2011 3:47 pm |
|
|
Update:
To get the execution time of some instruction, I've resorted to this way:
Code: | enable_interrupts(int_TIMER1);
leap=0;
set_timer1(0);
// Code to analyze
lcd_gotoxy(1,1);
printf(lcd_putc,"%Lu", (val_volt()*30)/61);
// ends here
v1=get_timer1();
disable_interrupts(int_TIMER1);
printf(lcd_putc,"\f%Lu, %u", v1,leap); |
If timer1 overflows, it just increments leap; TIMER1 is set as divide_by_1. So, basically, I'm making the PIC displays the increments made by timer1 - with a 8MHz clock, I get 0.5us resolution, nice, practical and effective :)
(can you confirm to be correct too?) _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Tue Jul 05, 2011 6:36 am |
|
|
Updates.
I'm "somewhat" mapping the execution time of the PIC, result pretty much match the timings given in the guide section.
I was quite satisfied by just 445 [us] to execute int32 += int32*int32, but still didn't understood why my program wasn't functioning properly.. (there's 100ms window interrupt that launch a series of operations).
.. until I forgot that, besides requested operations, there was the timer_0 generating a software pwm :( - a pretty tight one, 10kHz!
Enabled the timer_0 also in the test program, and BANG! the previous operation just jumped to 6246 [us] :|
Let alone printf operations to the 16x2 LCD... (from 3.34[ms] to 280[ms]..). _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Tue Jul 05, 2011 7:21 am |
|
|
The operation didn't change at all. It is just that an interrupt at 10KHz, means 10000*interrupt overhead (typically 60 instructions), so 600000 instructions per second being executed before _anything_ else is done. Either in the interrupt _or_ the main....
Seriously, look again at how this code is done. Could you use the INT_GLOBAL approach (EX_GLINT.C), or have this as the only high_priority interrupt, and again do your own register saving for the minimum number of registers, or do the job using another dedicated PIC (something silly like a 12F675, just generating this signal)?. Savings here will affect your whole functionality.....
Best Wishes |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Wed Jul 06, 2011 6:59 am |
|
|
Yes, you are perfectly right, instructions have to be executed by something/somewhere, they do not come up from thin air.
I was thinking at some solutions, lowering the software pwm, demux the native integrated pwm (or mux, I never get the word right) or as you suggested, have another small PIC (or a TLC5940 - just to name something) to indipendently generate a PWM for me.
Working on :) _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
foxOnTheRun
Joined: 17 Apr 2010 Posts: 43
|
|
Posted: Thu Jul 07, 2011 3:50 am |
|
|
Updates (I'm updating with the intent that this topic could be usefull for other reader in the future):
I have found what was slowing down everything:
Code: | printf(lcd_putc,"%3.2wV", val_v); |
This was taking more than 55ms to execute :\
I substituted it with:
Code: | printf(lcd_putc,"%3Lu0mV", val_v); |
And this is taking circa 5ms to execute :)
The result is the same, expecially regarding the PIC adc which has a resolution/sensitivity of 4mV (5/2014), so it would have been useless to try to compute mV digit - visually it looks good too. _________________ Listen, why don't you relax? Take a pill, bake a cake or go and read the encyclopedia. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|