2020-11-22 11:24 PM
Hello everyone, I am trying to measure how much time is used to finish executing a function. I cannot use the timers because it adds some delay to the system. My other option is to use GPIO pins.
To do this, I
SET a pin at the start of the function
RESET a pin at the end of the function
I then use an oscilloscope to measure the on off time of the pin.
In order to turn on and off the GPIO without too much delay, I have used assembly code to ensure just a few instructions are used for enable and disable the GPIO.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //called every 4 us.
{
__asm__ volatile (
//turn on GPIO E2
"LDR R1, =0x40021014;"
"LDR R0, [R1];"
"ORR.W R0, #0x0004;" //only set pin 2
"STR R0, [R1];" //write data to memory
//write data to data memory
"LDR R3, =0xD0007260;"
"LDR R2, [R3];"
"LDR R2,=0xFF000000;"
"STR R2, [R3];" //write data to memory
//turn off GPIO E2
//"LDR R5, =0x40021014;"
//"LDR R4, [R5];"
"AND.W R0, #0xFFFFFFFB;" //only clear pin 2
"STR R0, [R1];" //write data to memory
);
}
However the generated code looks like the image below...
Using this generated code, the GPIO pin to the Oscilloscope produced a pulse with varying width as shown in the image below
From my assembly code above, the pulse width should be more or less identical since I am running the same number of instructions each cycle. But I do not know why I cannot get the compiler to follow the assembly code that I wrote in my C program.
Ultimately, I am trying to achieve a very light code to turn on/off the gpio pin so that I can accurately measure the time taken by a function. The code I am trying to achieve would be like the following
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //called every 4 us.
{
//read GPIO E ODR address
__asm__ (
"LDR R1, =0x40021014;"
"LDR R0, [R1];"
);
//Turn on GPIO E2
__asm__ (
"ORR.W R0, #0x0004;" //only set pin 2
"STR R0, [R1];" //write data to memory
);
//example function
BSP_LCD_DrawPixel(120, 60, LCD_COLOR_BLACK);
// Turn off GPIO E2
__asm__ (
"AND.W R0, #0xFFFFFFFB;" //only clear pin 2
"STR R0, [R1];" //write data to memory
);
}
Lastly, my compiler is set to Optimization Fast and I am using Atollic Truestudio. I only have one Interrupt in the system which is the ADC conversion complete.
If you need any other information, pls let me know. Thanks for reading!
EDIT1: Does anyone know why the compiled Assembly code is not the same as my inline assembly code? I would prefer this part of assembly code to not be touched /modified by compiler optimization while still using the optimize for speed option.
Solved! Go to Solution.
2020-11-23 02:35 AM
Thank you for your quick reply, upon inspection in another datasheet
I have found that the cortex-m4 does support DWT debug. And thank you for your code, it is very helpful for me !
I have successfully read DWT->CYCCNT. Lastly, I need to multiply with 1/MCU Frequency to get the time in seconds.