Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
gkarlsson
PostPosted: Jan 10, 2012 - 04:44 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

I am new to GCC for AVR so my question may seem a bit trivial but is stumping me. I am using an attiny5 and I am trying to access 1 byte of sram - which according to the datasheet I can do with STS/LDS. however the compiler is not generating the correct opcodes. BTW Most of my code is in assembler which is called from C code.

I use the following code to save a byte to $40
ldi r24,0x16
sts 0x40,r24

or in my c function:
asm("ldi r24,0x16");
asm("sts 0x40,r24");

the opcode generated for sts is:
80 93 40 00 which is not correct it should be 16 bit and more like: 80 a8

I have tried using .db 0x80,0x0a8 but the compiler does not seem to understand the .db.

So my question is - how can I directly enter opcodes inline in either C or asm - that way I can work around the compiler bug?
 
 View user's profile Send private message  
Reply with quote Back to top
WrightFlyer
PostPosted: Jan 10, 2012 - 05:18 PM
Hangaround


Joined: Sep 06, 2007
Posts: 129


It sounds more like an avr-as bug in binutils. Are you sure the version you are using has full support for the brain dead tinys?
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 10, 2012 - 05:21 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

I am using AVR Studio 5 - which I guess uses gcc. I have selected attiny5. Everything else works.
 
 View user's profile Send private message  
Reply with quote Back to top
WrightFlyer
PostPosted: Jan 10, 2012 - 05:25 PM
Hangaround


Joined: Sep 06, 2007
Posts: 129


The release notes say something like the brain dead support is "tentative ".
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Jan 10, 2012 - 05:26 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25882
Location: Wisconsin USA

Quote:

Are you sure the version you are using has full support for the brain dead tinys?

Indeed-- see http://www.avrfreaks.net/index.php?name ... ght=tiny10 and linked threads.

Perhaps dig into the new 4.7 and what it contains to see if the support is improved for that family?
http://www.avrfreaks.net/index.php?name ... torder=asc
 
 View user's profile Send private message  
Reply with quote Back to top
WrightFlyer
PostPosted: Jan 10, 2012 - 05:26 PM
Hangaround


Joined: Sep 06, 2007
Posts: 129


The release notes say something like the brain dead support is "tentative ".
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 10, 2012 - 05:32 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

I will give 4.7 a try. If it still fails does anyone have suggestions on entering opcodes directly inline?
 
 View user's profile Send private message  
Reply with quote Back to top
WrightFlyer
PostPosted: Jan 10, 2012 - 05:35 PM
Hangaround


Joined: Sep 06, 2007
Posts: 129


Can you .dw the opcode?
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 10, 2012 - 05:37 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Tried that I get an "unknown pseudo-op: `.dw'" error.
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Jan 10, 2012 - 05:41 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25882
Location: Wisconsin USA

Quote:

Can you .dw the opcode?

If it were me, I'd think "Hmmm--I can hand-assemble this LDS, and make a macro. And for STS, too. But only for the one address space? And how many times will I need to repeat this as I find other gotchas?"

Quote:

brain dead support is "tentative ".

Might be good enough, if the problem areas have been addressed but not yet "proven".

{there are other toolchains with support.]
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 10, 2012 - 05:52 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Tried 4.7 it will not compile for the attiny5.
As I only access the memory in 2 places - one to write one to read. I guess it will be easiest to just insert 2 nops at each place and patch the hex file before writing to the chip.
I will look into the other tools when I get some time.
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Jan 10, 2012 - 06:18 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2640


gkarlsson wrote:
I use the following code to save a byte to $40
ldi r24,0x16
sts 0x40,r24

or in my c function:
asm("ldi r24,0x16");
asm("sts 0x40,r24");

the opcode generated for sts is:
80 93 40 00 which is not correct it should be 16 bit and more like: 80 a8

I have tried using .db 0x80,0x0a8 but the compiler does not seem to understand the .db.
The compiler should not reject any inline assembly.
Does it matter whether you have a leading blank?
A workaround would seem to be *((char*)0x40)=0x16 .
Also, your inline assembly should be a single statement and should indicate that it clobbers r24.
'Tis better to let the compiler pick the register.
asm(" sts 0x40, %0" : : "r" ((char)0x16)));

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 10, 2012 - 06:42 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Setting the pointer directly does work, though 12 bytes - when you only have 512 bytes to work with is expensive. You need to set up the Z register and then transfer indirectly. I could set the register up once but then I might as well use it to store my variable.

Code:
*((char*)0x40)=0x16;
  40:   80 e4          ldi   r24, 0x40   ; 64
  42:   90 e0          ldi   r25, 0x00   ; 0
  44:   26 e1          ldi   r18, 0x16   ; 22
  46:   e8 2f          mov   r30, r24
  48:   f9 2f          mov   r31, r25
  4a:   20 83          st   Z, r18

And of course the inline asm still uses the 32bit sts instead of the 16bit.
 
 View user's profile Send private message  
Reply with quote Back to top
WrightFlyer
PostPosted: Jan 10, 2012 - 08:25 PM
Hangaround


Joined: Sep 06, 2007
Posts: 129


That code looks like -O0 which would be very unwise on a 512 byte chip in C!
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Jan 11, 2012 - 12:03 AM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2640


WrightFlyer wrote:
That code looks like -O0 which would be very unwise on a 512 byte chip in C!
It's gross even for -O0.
I'd have expected four instructions at most.

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Jan 11, 2012 - 08:42 AM
Resident


Joined: Jun 19, 2002
Posts: 950
Location: SF Bay area

Quote:
Tried [.dw to generate the instruction] and I get an "unknown pseudo-op: `.dw'" error.

The gnu assembler uses ".word" rather than ".dw"
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 11, 2012 - 04:32 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Quote:
The gnu assembler uses ".word" rather than ".dw"

Perfect, that works.

Thank you.
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Jan 11, 2012 - 06:08 PM
Moderator


Joined: Jan 23, 2004
Posts: 9820
Location: Trondheim, Norway

Your ticket was forwarded to the tools team this morning, so hopefully they'll be able to figure out a fix for the next release or so.

- Dean Twisted Evil

_________________
Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
lfmorrison
PostPosted: Jan 13, 2012 - 12:10 PM
Raving lunatic


Joined: Dec 08, 2004
Posts: 4719
Location: Nova Scotia, Canada

Dean,

Is this a support ticket about making it easier to enter op-codes as explicit hexadecimal constants inside an inline assembly block (addressing the thread's initial topic)? Or is it a more fundamental support ticket about the fact that the GNU tool chain doesn't know how to automatically handle the different size/encoding of the LDS and STS op-codes used in reduced-core AVRs such as the ATtiny4/5/9/10 and the ATtiny20/40?

- Luke
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 13, 2012 - 01:01 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Quote:
Is this a support ticket about making it easier to enter op-codes as explicit hexadecimal constants inside an inline assembly block (addressing the thread's initial topic)? Or is it a more fundamental support ticket about the fact that the GNU tool chain doesn't know how to automatically handle the different size/encoding of the LDS and STS op-codes used in reduced-core AVRs such as the ATtiny4/5/9/10 and the ATtiny20/40?


I guess IMHO the latter as I opened a ticket for the wrong opcodes being generated for the ATtiny 4/5/9/10. If I had RTFM I would have seen that .byte and .word are used instead of .db and .dw, and this thread would never have existed.

However I think there is a deeper problem with supporting these chips.
Take changing the clock registers we all know that we have to do this:

Code:
CCP=0xD8;
CLKMSR=0x00;

The caveat is that the second instruction needs to occur within 4 clock cycles. The problem is that each command generates 6 ASM instructions (12 bytes). There is no way in which the 2nd instruction will be executed in time. The compiler never generates an 'out' instruction, everything moved to a register memory position uses the z register and st. Don't even get me started on what happens when you define ISR routines.

I rewrote all my functions in ASM to ensure that I was getting the correct code. Someone pointed me towards CodeVisorAVR, I can say that it at least generated what I expected but had a different annoying habit of using the y register to pass parameters to functions. It would also not compile my asm file, it only wants C source files, and I was not feeling up to taking my optimized ASM and converting it back to C.

I do know however what I will be using for my next ATtiny 5 project.

Thanks to everyone for their input, I have managed to complete the project I was working on. I do hope the ATtiny 4-10 chips are supported soon by gcc.
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Jan 13, 2012 - 02:25 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia

gkarlsson wrote:
The caveat is that the second instruction needs to occur within 4 clock cycles.
In this particular case, it's quite unreasonable not to write asm.

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Jan 13, 2012 - 03:26 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62227
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

In this particular case, it's quite unreasonable not to write asm.

Which is how AVR-LibC manages to guarantee most of the 4 cycle sequences. If there's an error here then it's probably actually that AVR-LibC should have code added to cater for this particular sequence.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Jan 13, 2012 - 03:33 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia

Anybody cares to add a feature request to avr-libc's tracker?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
gkarlsson
PostPosted: Jan 13, 2012 - 03:43 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

I don’t think the issue is just this one sequence. As I pointed out it appears as if every assignment of a register in I/O space is done with a store indirect instead of using an out. Point me in the right direction and I will write up the feature request.
 
 View user's profile Send private message  
Reply with quote Back to top
lfmorrison
PostPosted: Jan 13, 2012 - 04:40 PM
Raving lunatic


Joined: Dec 08, 2004
Posts: 4719
Location: Nova Scotia, Canada

When you're talking about an explicit I/O register assignment in vanilla C code, the correct bug tracker would be for the compiler, GCC. Bug: GCC is using sub-optimal rules for code generation.

When you're talking about special timed sequences that are encapsulated within an existing avr-libc hardware abstraction API, then the correct bug tracker would be for avr-libc. Bug: The hardware abstraction API shouldn't depend upon compiler optimization, and therefore should have been written in assembly to begin with, not plain vanilla C.

My crystal ball tells me that in this case, there was no appropriate abstraction API available in avr-libc, so the OP was writing the code directly in vanilla C. So, in all likelihood we're probably dealing with the former case, not the latter.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jan 13, 2012 - 04:53 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62227
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

My crystal ball tells me that in this case, there was no appropriate abstraction API available in avr-libc, so the OP was writing the code directly in vanilla C. So, in all likelihood we're probably dealing with the former case, not the latter.

Luke,

I think it's two layered. Yes there may be a code generation fault in the C compiler and if so it deserves to reported/fixed but if the sequence being attempted was something that many users using that chip would like to be doing on a regular basis then it also deserves a hand crafted piece of Asm in AVR-LibC too that then saves the same wheel being reinvented N thousand times and all the associated issues of folks attempting it at -O0 even if the code generation fault is eventually fixed as it still probably could be made to work at -O0.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Jan 13, 2012 - 05:13 PM
Resident


Joined: Jun 19, 2002
Posts: 950
Location: SF Bay area

gkarlsson wrote:
The compiler never generates an 'out' instruction, everything moved to a register memory position uses the z register and st.

Um, that's not true:
Code:
void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  PORTB = 0;
 12a:   15 b8           out     0x05, r1        ; 5
  pinMode(13, OUTPUT);
 12c:   8d e0           ldi     r24, 0x0D       ; 13
 12e:   61 e0           ldi     r22, 0x01       ; 1
 130:   0e 94 79 01     call    0x2f2   ; 0x2f2 <pinMode>
  PORTB = 0x12; 
 134:   82 e1           ldi     r24, 0x12       ; 18
 136:   85 b9           out     0x05, r24       ; 5
}
 138:   08 95           ret


I'm not sure what you need to do to get C to recognize that some things are usable via the OUT instruction, and certainly inline assembler is a better way to be SURE that things are done with the required cycle. I suspect that your construct:
Code:
*((char*)0x40)=0x16;
was NOT what the compiler would have wanted. (though it does still generate an OUT instruction in the same atmega328 environment as the above example...)
This can probably be chalked up to "half-Tiny" chips support is a bit shaky still."
 
 View user's profile Send private message  
Reply with quote Back to top
gkarlsson
PostPosted: Jan 13, 2012 - 05:59 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Quote:
This can probably be chalked up to "half-Tiny" chips support is a bit shaky still."

I agree, I was only referring to the code being generated for the ATTiny 4 thru 10.

As I have not used any of the other processors yet I cannot make any comments about code being generated for them.
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Jan 13, 2012 - 06:38 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia

I'd say, if lds/sts generates wrong binary, the assembler needs to be fixed first (i.e. it's a binutils bug and should go to binutils's (binutils' ?) tracker).

If I understand it correctly, the compiler deliberately does not generate lds/sts to avoid this bug; so that's the second to be fixed. That should go to gcc's tracker, but there's little point to do that until the first gets fixed.

Then there's an additional issue, as Cliff said, the library should provide prechewed asm code for the critical sequences; however, it also depends on the fixed assembler (OK it may use .byte/.word, but that's crude). That then should go to avr-libc's tracker.

And then there's Atmel's internal tracker, where you already "got a ticket" - except that we don't know for what exactly.

Welcome to the wonderfully organized world of GNU AVR tools.

JW

PS. IIRC Eric Weddington used to maintain one more list of bugs... Smile see sticky at top of this forum
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
SprinterSB
PostPosted: Jan 13, 2012 - 07:43 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

gkarlsson wrote:
I don’t think the issue is just this one sequence. As I pointed out it appears as if every assignment of a register in I/O space is done with a store indirect instead of using an out. Point me in the right direction and I will write up the feature request.
You mean This? http://gcc.gnu.org/PR50448
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
gkarlsson
PostPosted: Jan 13, 2012 - 07:51 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Quote:

Not Really - that code would use a STS which would also need to be fixed. I did try the 4.7 version and it did not resolve the sts issue, I did not check it against the other issues.
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Jan 13, 2012 - 10:15 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

gkarlsson wrote:
Quote:
Not Really - that code would use a STS which would also need to be fixed. I did try the 4.7 version and it did not resolve the sts issue, I did not check it against the other issues.
So why is STS wrong (with respect to compiler proper) when accessing RAM?

What is the sample code where compiler proper genenrates wrong code?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
gkarlsson
PostPosted: Jan 13, 2012 - 10:18 PM
Newbie


Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL

Quote:
So why is STS wrong (with respect to compiler proper) when accessing RAM?

Because the STS it is generating is 32bit not 16 bit. ATtiny 4-10 can only use a 16 bit STS. I was answering in relation to the thread not in general.
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Jan 13, 2012 - 10:28 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

gkarlsson wrote:
Quote:
So why is STS wrong (with respect to compiler proper) when accessing RAM?

Because the STS it is generating is 32bit not 16 bit. ATtiny 4-10 can only use a 16 bit STS. I was answering in relation to the thread not in general.
So it's not a compiler issue, it's issue of binutils and thus of supplier of the distribution (Atmel?)

AFAIK this is a well known error in Atmel fork of GNU AVR tools.

The issue is straight forward to fix for anyone familiar with binutils, so I wonder why Atmel did not supply a fixed version up to now. Or did they?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
lfmorrison
PostPosted: Jan 16, 2012 - 01:24 PM
Raving lunatic


Joined: Dec 08, 2004
Posts: 4719
Location: Nova Scotia, Canada

SprinterSB wrote:
gkarlsson wrote:
Quote:
So why is STS wrong (with respect to compiler proper) when accessing RAM?

Because the STS it is generating is 32bit not 16 bit. ATtiny 4-10 can only use a 16 bit STS. I was answering in relation to the thread not in general.
So it's not a compiler issue, it's issue of binutils and thus of supplier of the distribution (Atmel?)

AFAIK this is a well known error in Atmel fork of GNU AVR tools.

... Keep in mind, though, that there is no solution to this problem at the head of the source tree for the official GNU version of binutils either. In fact, the GNU version of binutils simply doesn't acknowledge the existence of the reduced AVR CPU core in the ATtiny4/5/9/10 and ATtiny20/40 families at all.

Judging by the current state of the latest avr-bintutils patches from the FreeBSD ports system, I would venture to guess that it knows about the ATtiny10 (and its brethren), but it does not correctly implement LDS/STS for those devices either.
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Jan 16, 2012 - 04:13 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

lfmorrison wrote:
SprinterSB wrote:
gkarlsson wrote:
Because the STS it is generating is 32bit not 16 bit. ATtiny 4-10 can only use a 16 bit STS.
[...] it's issue of binutils and thus of supplier of the distribution (Atmel?)

AFAIK this is a well known error in Atmel fork of GNU AVR tools.
... Keep in mind, though, that there is no solution to this problem at the head of the source tree for the official GNU version of binutils either.
Why should there be a solution in binutils? There is not even support of Tiny, so how is anyone supposed to fix bugs that do never occur?

Tiny is implemented in Atmel's private port, so it's up to them to make bug fixes and release tools of reasonable quality. Atmel is independent of binutils or GCC's release cycles and can provide an upgrad at any time; they don't even need to have changes approved by someone else.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
the729
PostPosted: Feb 18, 2012 - 06:33 AM
Newbie


Joined: Feb 18, 2012
Posts: 2


Hi, I patched the 16-bit LDS/STS bug. Hope it helps Smile
http://www.avrfreaks.net/index.php?name ... p;t=117449
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Feb 18, 2012 - 10:41 AM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

theusch wrote:
Perhaps dig into the new 4.7
This is obviously a binutils bug and not a compiler bug. Moreover, neither avr-gcc 4.7 nor binutils 2.23 have support for Tiny. It's all fun of Atmel's private port.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits