I have a loop with several conditional branches in it. The loop is supposed to always run the same amount of cycles no matter what branches are taken.
To achieve this I filled the shorter branches with NOP
s (using asm("nop")
) until they were of equal length to the longer branches. This achieved what I wanted.
Now I have a lot more branches and want to automatically balance the branches. I am compiling with avr-gcc.
Is there a way to do this?
As requested: I am using an ATmega 1284p and avr-gcc for my implementation.
Well you didn't specify whether you are coding in asm or in c, since you use branches but you call "asm()"... If using C, you can call millis() at the beginning of your loop, and call it at the end too. You have to calculate the maximum duration of the loop. So subtract the two millis values and compare the difference with the maximum duration of the loop. Yea lilbit confusing, here the code:
#define MAX_DURATION 1000 //let's say 1 second, but you should calculate it
while(yourcondition) {
temp1 = millis();
//do your branches
temp2 = millis();
delay(MAX_DURATION-(temp2-temp1));
}
While if you are coding in asm, you have at first to disable interrupts in order not to have longer loops. Then you can setup a 16bit timer, if your processor has any, with the greatest prescaler and then checking the timer value instead of millis and make a delay function, easily done as:
delay: ;put the millisecond to wait in r17:r16
ldi r18, 200
ldi r19, 26 ;200*26* (3 cicles each little loop) = 1 millisecond of delay with a 16MHz oscillator
mov r20, r17
delay_loop:
dec r19
brne delay_loop
ldi r19, 26
dec r18
brne delay_loop
ldi r18, 200
dec r17
brne delay_loop
mov r17, r20
dec r16
brne delay_loop
ret
Hoping that your instrunction set is similar to mine. Next time specify what code are you using and What processor are you targeting