This one’s kinda random
What I’m doing — and pics will follow — is building 1R/2R DACs for the arduino mega board, because it has two ports that have all 8 pins available. As a result I can rapidly write to PORTA and PORTC and get a nice fast output, like a really nice quality pair of sinewaves that are 0-5V, quadrature offset, with down to a 200 microsecond period.
That’s pretty cool.
One of the things I noticed is a weird 40uS blip in the otherwise lovely sinewave, and I tracked it down to how I had the program set up.
So quickly:
loop() {
int a; int sinedata[] = {numbers for one quarter of a sinewave};
for (a=0; a<(length of the sine array); a++)
{ PORTA = 128 + sinedata[a]; //128 offsets it as the output is only 0-5V }
(same thing three more times, to reverse-traverse, invert, and rev-invert the sine series)
}
This results in a beautiful sinewave with a 40uS blip.
However:
loop() {
int a; int sinedata[] = {numbers for one quarter of a sinewave};
while(1)
{
for (a=0; a<(length of the sine array); a++)
{ PORTA = 128 + sinedata[a]; //128 offsets it as the output is only 0-5V }
(same thing three more times, to reverse-traverse, invert, and rev-invert the sine series)
}
}
Does NOT have that little blip. What’s the difference? Just that it no longer runs the initialization step. Well, that’s weird. The Mad Scientist Hut.
So then I did what I should have done in the first place and declared sinedata[] as a static int, and that worked great as well. No blips!
What’s the difference? What’s GCC doing differently between the two? Is it reallocating that array assignment every time? Probably yes, but why?
Well, it’s time to go look.
So you go to (in linux) /tmp/arduino[version] and you’ll find a directory that has the hex file. (It has two, one that includes the bootloader and one that’s raw, in case you’re uploading via a hardware programmer. You want the one without the bootloader.)
You can decompile on linux using objdump. However, the objdump that ships with GCC will shrug at you and say it doesn’t recognize the architecture, even though objdump is supposed to do that. Well, now what. I downloaded binutils-avr to get avr-objdump but it still didn’t know the architecture automatically. Apparently Atmel stuff is fussy.
As a result you have to specify to avr-objdump what AVR family you’re trying to decompile.
Wikipedia has a nice list of the ATTiny devices here:
https://en.wikipedia.org/wiki/ATtiny_microcontroller_comparison_chart
But I haven’t yet found a similar list for ATMega cores, which is really irritating.
https://linux.die.net/man/1/avr-gcc
Seems to indicate that any chip of this general architecture with over 64K of flashmem is of the avr5 dataset.
This works, FINALLY.
avr-objdump -d -j .sec1 -m avr5 [hexfilename].hex gets me a disassembled chunk of code and I can go see what the goofball Arduino IDE is telling gcc to do.