UNBELIEVABLE Olimexino software glitch

Thread Starter

mikewax

Joined Apr 11, 2016
181
OK here's something that i doubt anyone has seen before. here's a routine to toggle pin D12 off and on using the Arduino 1.6.12 IDE and an Olimexino 328. I'm using assembly code to do it because this method is the fastest way to toggle a pin. the instruction "asm ( "out 0x05, r21 \n" );" executes in a single clock cycle.
Code:
int x; // toggle pin 12 at .5Hz

void setup() {
asm (
"ldi r20, 0 \n" //load register r20 with 0
"ldi r21, 16 \n" //load register r21 with 16
: : : "r20","r21" //compiler directive to reserve the two registers
);
pinMode(12,OUTPUT); // port B, pin 4
}

void loop() {
if (x%8 == 0) x = 0;
asm ( "out 0x05, r21 \n" ); //write '0' to portB
delay(1000);
asm ( "out 0x05, r20 \n" ); //write '10000' to portB
delay(1000);
}
you'll notice that the statement "if (x%8 == 0) x = 0;" is completely extraneous, it's only there for the purpose of demonstration.
the UNBELIEVABLE part is that when i replace the number 8 in that statement with a 9 or larger number, the output on pin 12 stops working.
it would be nice if someone else could test this on a 328 to see if they get the same result.
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
Are you able to get as assembly output for your c source ?
What happens if you comment out that line ?
What happens if x is initialised to 7 or 9 ?
- i don't know how to do that.
- if i strike that line the code works
- if it's 7 it works and if it's 9 it won't
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
To me it seems a bit weird as x doesn't seem to referenced apart from that line.
Where did you get the snippet from....I'm intrigued as to why x has an affect.
Is there a debugger you can use to keep a watch on the vars ? x surely shouldn't be messing with r20 or r21;
no i don't have any kind of debugger, just the arduino IDE.
this piece of code is the most reduced and simplified version of a glitch i discovered while debuging a larger olimex program that i've been writing. pin 12 wasn't working and this turned out to be why. but of course i have no idea how.
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
Hope you had a long cool drink after finding that, sounds like a right PITA.
check this out. at the bottom of my code i have this:
Code:
  current = 0;
  for(z=1; z<7; z++) {
    current = current + analogRead(currentSense);
    delay(5);
    }
  current = current/4;
if i change the 4 to a 5 or a 6, the processor crashes when it gets to that statement. i don't think i'm in Kansas anymore.
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
I think it may be doing division by shifting bits.
yeah.... like the two problems might be related. division by 6 requires an extra register to calculate. and so does it when i do "x%9" but not when i do "x%8".
maybe the calculation is overlapping the r20 or r21 register. that's a possible explanation.
hmmm..... THANX, that was a damn good idea. i'm gonna sleep on it and check the atmega data sheet in the morning.
 

dannyf

Joined Sep 13, 2015
2,197
UNBELIEVABLE Olimexino software glitch
it is not Olimexino glitch. It is your software glitch.

the issue was pointed out a while back: generally, there is no assurance that those registers wouldn't be used by the compiler for something else. So it is entirely possible that its context was destroyed when it come to the two asm statements.

you can confirm that by restoring the context of r20/21 just before the two asm statements and the output will come back.
 

spinnaker

Joined Oct 29, 2009
7,835
I have no idea what the above post means except your issue was pointed out in the second post. x is never initialized. There is nothing "
UNBELIEVABLE" about that other than you did not see the obvious.

Have you tried looking at the assembler that C gives you? You not be getting any benefit from making your code harder to read. It is worth the time to look at that and you will get an education in how the C compiler assembles your code.

I have yet to program on the Arduino but a number of MCUs need an infinite while loop so code does not exit. You might want to check on that.

And I find it hard to believe you do not have a debugger. If you don't then get another IDE.
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
I have no idea what the above post means except your issue was pointed out in the second post. x is never initialized. There is nothing "
UNBELIEVABLE" about that other than you did not see the obvious.
Have you tried looking at the assembler that C gives you? You not be getting any benefit from making your code harder to read. It is worth the time to look at that and you will get an education in how the C compiler assembles your code.
I have yet to program on the Arduino but a number of MCUs need an infinite while loop so code does not exit. You might want to check on that.
And I find it hard to believe you do not have a debugger. If you don't then get another IDE.
thanx for the opinion, Forrest, but i'm afraid your sense of humor is a tad too sophisticated for this poor moron.
Shakespeare couldn't have done it better.
you're telling me what's obvious and-
you can't even read my code and recognize the fact that the value (or lack thereof) of x has nothing to do with the problem.
you're telling me what's obvious and-
you think that i don't realize that "x could be anything" like i'd be smart enough to be able to use a web browser if i was that stupid.
you're telling me what's obvious and-
you think my code is hard to read
you're telling me what's obvious and-
you don't know what "void loop()" means. you think that it's running once and exiting.
you're telling me what's obvious and-
you actually think that "x could be anything" IS THE OBVIOUS SOLUTION, and then you talk down at me as if I'm an ignoramus
you find it "hard to believe" that i don't have a debugger, and you're the one who wouldn't know Shakespearean irony if it slapped you in the face.
no, as a matter of fact, i don't have a debugger. i've written plenty of arduino programs and never needed one.
for your information, "x" is not just two little lines on a screen, it's actually a symbol, with meaning, like the other little squiggly lines that i posted at the top of this page. it's called "C", it's called language, written communication.
O and yeah, i know what you're thinking and yeah, i did go back to my code and give x a value, and guess what, Forrest....
 
Last edited:

Thread Starter

mikewax

Joined Apr 11, 2016
181
it is not Olimexino glitch. It is your software glitch.
the issue was pointed out a while back: generally, there is no assurance that those registers wouldn't be used by the compiler for something else. So it is entirely possible that its context was destroyed when it come to the two asm statements.
you can confirm that by restoring the context of r20/21 just before the two asm statements and the output will come back.
i thought i did have assurance that those registers would be available. according to C syntax, the registers r20 and r21 constitute the so-called "clobber" list, which means that gcc will reserve them for my use. i've written other routines using these registers without any problem. if i have to restore them every time then they're of no use.
 

dannyf

Joined Sep 13, 2015
2,197
i did go back to my code and give x a value,
the value of x has no impact here, because in an otherwise correct code, it doesn't change the flow of the execution.

according to C syntax,
there is no "C syntax" that will reserve a register (ie preventing its use by other code). I think the attribute "register" is deprecated in gcc-avr.
 

Thread Starter

mikewax

Joined Apr 11, 2016
181
the value of x has no impact here, because in an otherwise correct code, it doesn't change the flow of the execution.
i know i was just responding to a very strange post by someone who doesn't know it.
there is no "C syntax" that will reserve a register (ie preventing its use by other code). I think the attribute "register" is deprecated in gcc-avr.
according to https://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Extended-Asm.html the syntax goes:

"asm volatile ("movc3 %0,%1,%2"
: /* no outputs */
: "g" (from), "g" (to), "g" (count)
: "r0", "r1", "r2", "r3", "r4", "r5");"

and the rxes are clobbered registers. it says "When the compiler selects which registers to use to represent input and output operands, it does not use any of the clobbered registers. As a result, clobbered registers are available for any use in the assembler code."
 
Top