|
From: | Ewout Boks |
Subject: | Re: [avr-gcc-list] inline assembler problem |
Date: | Sun, 25 Jan 2004 09:58:35 +0100 |
User-agent: | Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.5) Gecko/20031109 |
Theodore A. Roth wrote:
On Tue, 20 Jan 2004, Ewout Boks wrote:That is the inline asm problem I asked Joerg about yesterday. It is an unecessary warning since your code looks perfectly allright. I believe that it has been solved in post 3.3.1 versions of avr-gcc, so update the compiler is your solution.The warning are correct and the posted code will not work as he expects. The reason it won't work is discussed in this FAQ entry: http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/FAQ.html#faq_port_passSince some of you wanted to view the whole testprogram in order to help me track the error I've struggeling with, I post it here. The compiler I'm using is still the avr-gcc-3.3.1. The functions in the code below I did implement in order to have some simple functions to learn from. #include <inttypes.h> #define PORT_A 0x1B #define DDR_A 0x1A #define PIN_A 0x19Change these to: #define PORT_A PORTA #define DDR_A DDRA #define PIN_A PINAuint8_t read(const uint8_t adr) {In order to pass the io reg, it must be done via a pointer, change this to: uint8_t read (volatile uint8_t *adr) {uint8_t p; asm volatile ("in %0, %1" : "=r" (p) : "I" (adr)); return p; }This is impossible. Read the FAQ entry linked above.
I understand that, in order to access the value at the port address, you need to pass the address of the port. The above code is clearly wrong in that respect : one should use the 'ld' mnemonic with the port address loaded into X.
However, I think the following is done clearly wrong by the compiler: (this example comes from the avr-libc FAQ):
7.4.1 GCC asm Statement Let's start with a simple example of reading a value from port D: asm("in %0, %1" : "=r" (value) : "I" (PORTD) : );When I attempt to do this, I first get a complaint from avr-gcc saying that :
avrHardware.c: In function `avrInportByte': avrHardware.c:27: error: parse error before ')' token gmake: *** [avrHardware.o] Error 1For some reason, the assembler has trouble with the 3rd colon in the statement (no clobber list possible ?). When I remove the 3rd colon, I get this:
avrHardware.c: In function `avrInportByte': avrHardware.c:27: warning: asm operand 1 probably doesn't match constraints avrHardware.c:27: error: impossible constraint in `asm' gmake: *** [avrHardware.o] Error 1Now this I clearly call a compiler deficiency/error. The compiler should have no trouble inserting something like:
in r24,0x1b Ewout
uint8_t fastSBI(const uint8_t port, const uint8_t bit) { asm volatile("sbi %0, %1" : : "I" (port), "I" (bit)); } int main(void) { uint8_t port_a = PORT_A; uint8_t ddr_a = DDR_A; uint8_t pin = 3; uint8_t data; data = read(port_a); fastSBI(ddr_a, pin); return 0; } When trying to compile this I get the following errors: inlasm.c: In function `read': inlasm.c:11: warning: asm operand 1 probably doesn't match constraints inlasm.c:11: error: impossible constraint in `asm' inlasm.c: In function `fastSBI': inlasm.c:17: warning: asm operand 0 probably doesn't match constraints inlasm.c:17: warning: asm operand 1 probably doesn't match constraintsI don't think that gcc is lying to you about the "impossible constraint". Ted Roth
[Prev in Thread] | Current Thread | [Next in Thread] |