Re: [avr-libc-dev] [avr-libc-commit] [2372] * configure.ac (--with-debug-info): New option.
See comments below On Mon Apr 29 2013 05:56:08 PM CEST, Joerg Wunsch j...@uriah.heep.sax.de wrote: === --- trunk/avr-libc/configure.ac 2013-04-29 12:21:04 UTC (rev 2371) +++ trunk/avr-libc/configure.ac 2013-04-29 15:56:07 UTC (rev 2372) @@ -326,6 +326,31 @@ AC_SUBST(AVR_LIBC_USER_MANUAL) AC_SUBST(DOC_INST_DIR) +dnl Let the user decide which debug information to generate. +dnl Default is nothing, suitable for binary distributions of the +dnl compiled library. Alternative options include stabs, dwarf-2, +dnl or dwarf-4. +AC_ARG_ENABLE(debug-info, +[ --enable-debug-info=stabs|dwarf-2|dwarf-4 Enable generation of debugging information], +[case ${enableval} in + yes|dwarf2|dwarf-2) debuginfo=dwarf2 ;; + no) debuginfo= ;; + stabs) debuginfo=stabs ;; + dwarf4|dwarf-4) debuginfo=dwarf4 ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug-info option; should be either stabs, dwarf-2, or dwarf-4]) ;; + esac], [debuginfo=]) + +dnl Decide which debuginfo information to include +case $debuginfo in +) CDEBUG=; ASDEBUG= ;; +stabs) CDEBUG=-gstabs; ASDEBUG=-Wa,-gstabs ;; +dwarf2) CDEBUG=-gdwarf-2; ASDEBUG=-Wa,-gdwarf-2 ;; +dwarf4) CDEBUG=-gdwarf-4; ASDEBUG=-Wa,-gdwarf-2 ;; is the ASDEBUG gdwarf-2 correct for dwarf 4? Hth, wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [avr-libc-commit] [2374] Contributed by Knut Schwichtenberg:
Spotted some typos. I hope it is readable, my phone email client is not the best. On Mon Apr 29 2013 11:06:52 PM CEST, Joerg Wunsch j...@uriah.heep.sax.de wrote: Revision: 2374 === --- trunk/avr-libc/devtools/ioreg.pl 2013-04-29 20:35:36 UTC (rev 2373) +++ trunk/avr-libc/devtools/ioreg.pl 2013-04-29 21:06:52 UTC (rev 2374) @@ -439,7 +439,8 @@ print STDERR $0 version: $VERSION Copyright (c) by Knut Schwichtenberg\n; print STDERR Usage: $0\ [switches] AVR_XML_file\n; print STDERR -h This message\n; - print STDERR -v Version\n; + print STDERR -V Version\n; + print STDERR -v Verbose\n; print STDERR -x path to saxon9\n; print STDERR -o output file otherwise STDOUT \n; } @@ -448,7 +449,7 @@ # Handle the command line #$Getopt::Std::STANDARD_HELP_VERSION=1; -$options = 'hVvx:c:o:'; +$options = 'hVvx:o:'; getopts( $options, \%opts ); if( defined $opts{'h'} ){ HELPMESSAGE(); @@ -541,5 +542,80 @@ } print $trailer; close; +__END__ +=head1 NAME -__END__ +ioreg.pl - Create debug information from Atmel XML files for IO-Ports and EEProm + +=head1 SYNOPSIS + + perl ioreg.pl x.XML + +=head1 DESCRIPTION + +Using GDB and AVaRICE to debug AVR code requies to know the addresses of requires +IO registers! The GDB command x PORTA leads to an unkonwn address unknown +error. Beginning with Atmel Studio 5 well formed XML file are deliverd +as part of the installation. This script converts these XML-files using a +stylesheet into dwarf-2 debug information. To prevent Atmel's debugger from +crashing only dwarf-2 can be used, while GDB could use debug information +up to dwarf-4. Similar to the handling of the IO-addresses the eeprom +start address can be accessed by the lable __eeprom. Label Its type is an CPU +specific specific array of uint8_t. + +This debug information is added to the device specific start-up code of +avr-libc and now allows debugging symbolic +names. +It is possible to use dwarf-4 debug information for the +application and mix it with dwarf-2 of the start-up code. + +=head1 Preconditions + +This script relies on + +=over 3 + +=item * +Atmel's AVR XML files + +=item * +Stylesheet file named findreg.xsl. It has to be located in the same directory as ioreg.pl + +=item * +XSLT processor, either xsltproc or saxon9 + +=back + +If xsltproc is used, it must be in the PATH. Using saxon9 gives a runtime warning which can be ignored. + +=head1 Command line parameter + +The following command line parameter are supported parameters + +=over 5 + +=item h + +Print the help infomation to STDERR + +=item V + +Print the version information to STDERR + +=item v + +Print verbose information to STDERR + +=item x + +Sets the path to saxon9. Default: /usr/share/java + +=item o + +Set the output file otherwise STDOUT is used + +=back + +=head1 Authors + +Knut Schwichtenberg / Joerg Wunsch ___ avr-libc-commit mailing list avr-libc-com...@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-commit ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [avr-libc-commit] [2319] Added experimental function ' void system_tick_i(void) '.
Mike Rice schreef op 2013-03-31 23:05: +__SREG__ = 0x3f +__tmp_reg__ = 0 +__zero_reg__ = 1 + +.globalsystem_tick_i + .type system_tick_i, @function +system_tick_i: + push r1 + push r0 + in r0,__SREG__ + push r0 + clr __zero_reg__ + push r24 + push r25 + push r26 + push r27 + lds r24,__system_time + lds r25,__system_time+1 + lds r26,__system_time+2 + lds r27,__system_time+3 + adiw r24,1 + adc r26,__zero_reg__ + adc r27,__zero_reg__ + sts __system_time,r24 + sts __system_time+1,r25 + sts __system_time+2,r26 + sts __system_time+3,r27 + pop r27 + pop r26 + pop r25 + pop r24 + pop r0 + out __SREG__,r0 + pop r0 + pop r1 + ret + .size system_tick_i, .-system_tick_i I came up with this: push r24 lds r24,__system_time+0 subi r24, (-1) sts __system_time+0,r24 lds r24,__system_time+1 sbci r24, (-1) sts __system_time+1,r24 lds r24,__system_time+2 sbci r24, (-1) sts __system_time+2,r24 lds r24,__system_time+3 sbci r24, (-1) sts __system_time+3,r24 pop r24 ret Which is much less code, less stack, less cpu cycles. The last two are nice for an interrupt. HTH Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructionsin optimized code causes unintended behavior in execution
Weddington, Eric schreef: -Original Message- From: Weddington, Eric Sent: Thursday, June 17, 2010 9:15 PM To: 'Wouter van Gulik'; avr-libc-dev@nongnu.org Subject: RE: [avr-libc-dev] LPM instructionsin optimized code causes unintended behavior in execution As a matter of fact (checking code and instruction set) The code you have in the bug report shows: 5808: f4 91 lpm r31, Z+ Take a long hard look at the hex instruction. Reverse the bytes: 91 F4 The LPM instruction in the instruction set document (page 91) shows this is Form 2 (ii) of the LPM instruction which is LPM, r, Z, which is without the plus sign. Therefore this is not undefined. You've just rediscovered a different bug in binutils. I forgot: Technically the bug cannot be pushed up to the binutils folks, because IIRC this is in the XMEGA patch to binutils. All of the XMEGA patches have not been submitted upstream yet, though we are planning on doing so. It *was* on the WinAVR bug list, but now it's on an internal list. So the patch breaks this? Because it is also broken for an atmega16 (compiled with WinAvr2010) Anyway here you have a simple testcase. Compile the file using: avr-gcc --save-temps -Os main.c -mmcu=atmega16 and disassemble: avr-objdump -h -S -z a.out dump.lss volatile char x,y; void foo(void) { x++; } int main(void) { switch(y) { case 0x00: foo(); break; case 0x01: foo(); break; case 0x02: foo(); break; case 0x03: foo(); break; case 0x04: foo(); break; case 0x05: foo(); break; case 0x06: foo(); break; case 0x07: foo(); break; case 0x08: foo(); break; case 0x09: foo(); break; case 0x0A: foo(); break; case 0x0B: foo(); break; case 0x0C: foo(); break; case 0x0D: foo(); break; case 0x0E: foo(); break; case 0x0F: foo(); break; case 0x10: foo(); break; case 0x11: foo(); break; } } ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructions in optimized code causes unintended behavior in execution
Joerg Wunsch schreef: As Wouter van Gulik wrote: IMHO, the respective code is hand-crafted asm code in avr-libc. Are you sure? The code is about a jump table, is that in avr-libc? Errm, you are right... We should probably file a bug report at binutils as well. gas is excepting an 'illegal' instruction. This could mean gcc/gas also happily generates the undefined LD files? Thomas could you generate a minimum testcase? HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructions in optimized code causes unintended behavior in execution
Wouter van Gulik schreef: Joerg Wunsch schreef: As Wouter van Gulik wrote: IMHO, the respective code is hand-crafted asm code in avr-libc. Are you sure? The code is about a jump table, is that in avr-libc? Errm, you are right... We should probably file a bug report at binutils as well. gas is excepting an 'illegal' instruction. This could mean gcc/gas also happily generates the undefined LD files? I meant instruction instead of files. No coffee yet... Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructions in optimized code causes unintended behavior in execution
- Oorspronkelijk bericht - As Thomas Carsten Franke wrote: I did not restored the NVM CMD because I didn't know that it would has to be. This is correct. We recently added a note to the documentation in the header file avr/pgmspace.h telling that on Xmega devices, all the functions will only work as designed if NVM_CMD is set to 0x00 (NOP). As you had to manually take care to set NVM_CMD to something else before, I think it's only fair to leave the job to the programmer to restore it afterwards. Although true, I rather think this is a GCC bug. The avr instruction documentation says LPM R31, Z+ has undefined results. In the example it was oke to use LPM R31, Z. Since GCC does not know LPM, I think this might be easy to spot in the GCC code or relevant patch. Hth, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructions in optimized code causes unintended behavior in execution
On 17/06/10 10:15, Thomas Carsten Franke wrote: Am 17.06.2010 09:38, schrieb Wouter van Gulik: Wouter van Gulik schreef: Joerg Wunsch schreef: As Wouter van Gulik wrote: IMHO, the respective code is hand-crafted asm code in avr-libc. Are you sure? The code is about a jump table, is that in avr-libc? Errm, you are right... We should probably file a bug report at binutils as well. gas is excepting an 'illegal' instruction. This could mean gcc/gas also happily generates the undefined LD files? Just right now I added a problem report to gcc 4.3.3 version describing the problem. Just for the record the gcc bug id is:44564 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44564 I think this is a nasty bug, but it is hard to recreate the problem. I did a quick scan of GCC but I can't find a reference to a lpm r?, Z+ other than those to __temp_reg__. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] LPM instructions in optimized code causes unintended behavior in execution
- Oorspronkelijk bericht - As Wouter van Gulik wrote: Although true, I rather think this is a GCC bug. The avr instruction documentation says LPM R31, Z+ has undefined results. In the example it was oke to use LPM R31, Z. IMHO, the respective code is hand-crafted asm code in avr-libc. Are you sure? The code is about a jump table, is that in avr-libc? Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
[avr-libc-dev] Re: [avr-libc-commit] [2158] Submitted by Jan Waclawek:
Joerg Wunsch schreef: + +\code +#define cli() __asm volatile( cli ::: memory ) +#define sei() __asm volatile( sei ::: memory ) + +unsigned int ivar; + +void test2( unsigned int val ) +{ + val = 65535U / val; + + cli(); + + ivar = val; + + sei(); +} +\endcode + +compiles with optimisations switched on (-Os) to + +\verbatim +0112 test2: + 112: bc 01 movwr22, r24 + 114: f8 94 cli + 116: 8f ef ldi r24, 0xFF ; 255 + 118: 9f ef ldi r25, 0xFF ; 255 + 11a: 0e 94 96 00 call0x12c ; 0x12c __udivmodhi4 + 11e: 70 93 01 02 sts 0x0201, r23 + 122: 60 93 00 02 sts 0x0200, r22 + 126: 78 94 sei + 128: 08 95 ret +\endverbatim + +where the potentially slow multiplication is moved across cli(), +resulting in interrupts to be disabled longer than intended. There is typo, the texts talks about multiplication instead of divide. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
[avr-libc-dev] Definition of putchar/getchar causes code growth
Hi list, Currently putchar is defined as #define putchar(__c) fputc(__c, stdout) which causes C code like this: putchar(' ') To generate assembler like this: lds r22,__iob+2 lds r23,(__iob+2)+1 ldi r24,lo8(32) ldi r25,hi8(32) call fputc This is 8 bytes (lds == 4 bytes) for loading the stream pointer. If we change this to a real putchar call we would save 8 bytes per putchar call. the putchar call would then load the correct stream: int putchar(int c) { return fputc(stdout, c); } The cycle penalty would be the extra call and return. IMHO losing 7,8 or 10 cycles per call for a gain of 8 bytes per call seems very acceptable to me. Especially if it concerns functions like putchar and friends. Other opinions? Otherwise I will file a bug report. Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [RFC] New eeprom.h
Weddington, Eric schreef: Mainly because this is a total rewrite of the implementation. The API (interface) stays the same. I'm certainly fine with putting the old copyrights back on. I thought the address thingy was taken from Bjoern Haasse's implementation. So that's why I thought he should at least be there. But I am no lawyer, and personally I do not mind. This sounds promising. Do you care to modify the header? I did. See attachment. (if they do not get to the list, please notify me) No guarantees. But for me it saves up to 50 bytes testing read/write pairs per type. The only thing I can't make gcc do in a proper manner is the read block. GCC just uses to many instructions. That is a candidate for a special assembler routine. There is a loop, or should be. The loop is checking the EEWE flag (or equivalent) to make sure that a read or write is possible. And the old code is not disabling interrupts during eeprom write... which is no good! Maybe this was the problem of the report for the tiny13? No, the old code is disabling the interrupts for the write routines. You have to look in the libc/misc/eeprom.S file in the avr-libc source. Right, I forgot about the assembler file... shame on me! Sorry for the fuzz. Wouter /* Copyright (c) 2007 Atmel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* $Id$ */ #ifndef _AVR_EEPROM_H_ #define _AVR_EEPROM_H_ 1 #include avr/io.h #include stdint.h /** \def EEMEM \ingroup avr_eeprom Attribute expression causing a variable to be allocated within the .eeprom section. */ #define EEMEM __attribute__((section(.eeprom))) /* Register definitions */ /* Check for existence of EEPROM peripheral. */ #if E2END == 0 #error Device does not have EEPROM available! #endif /* Check for aliases. */ #if !defined(EEWE) defined(EEPE) #define EEWE EEPE #endif #if !defined(EEMWE) defined(EEMPE) #define EEMWE EEMPE #endif #if !defined(EECR) defined(DEECR) /* AT86RF401 */ #define EECR DEECR #define EEAR DEEAR #define EEARL DEEAR #define EEDR DEEDR #define EERE EER #define EEWE EEL #define EEMWE EEU #endif #if !defined(EECR) || !defined(EEDR) || !defined(EEARL) #ifndef __EEPROM_REG_LOCATIONS__ /* 6-byte string denoting where to find the EEPROM registers in memory space. Adresses denoted in hex syntax with uppercase letters. Used by the EEPROM subroutines. First two letters: EECR address. Second two letters: EEDR address. Last two letters: EEAR address. */ #define __EEPROM_REG_LOCATIONS__ 1C1D1E #endif /* If needed, override the locations defined in the IO headers. */ #ifdef EEPROM_REG_LOCATIONS_OVERRIDE #undef __EEPROM_REG_LOCATIONS__ #define __EEPROM_REG_LOCATIONS__ EEPROM_REG_LOCATIONS_OVERRIDE #endif #define CONCAT1(a, b) CONCAT2(a, b) #define CONCAT2(a, b) a ## b #define HEXNR CONCAT1(0x, __EEPROM_REG_LOCATIONS__) #undef EECR #define EECR _SFR_IO8((HEXNR 16) 0xFF) #undef EEDR #define EEDR _SFR_IO8((HEXNR 8) 0xFF ) #undef EEAR #define EEAR _SFR_IO8(HEXNR 0xFF) #undef EEARH #undef EEARL #define EEARL EEAR #endif /** \def eeprom_is_ready \ingroup avr_eeprom \returns 1 if EEPROM is ready for a new read/write operation, 0 if not. */ #if defined(__DOXYGEN__) # define eeprom_is_ready() #elif defined(DEECR) # define eeprom_is_ready() bit_is_clear(DEECR, BSY) #else # define eeprom_is_ready()
Re: [avr-libc-dev] [RFC] New eeprom.h
Weddington, Eric schreef: Bah! Trying again. Thanks for everyone's patience. Eric Weddington So I got the header and my first consideration in is the copyright... All previous contributers are now gone? I hope this is WorkInProgress. Second why all these hideous define with there nasty \ ? For eeprom read an inline function I came up with this (for E2ND 0xFF) //static inline uint8_t __eeprom_read_byte_address_word(uint8_t*) __attribute__((always_inline)); static inline uint8_t __eeprom_read_byte_address_word(uint8_t* eeptr) { uint16_t __address_word = (uint16_t)(eeptr); uint8_t __result; do{}while(!eeprom_is_ready()); EEARL = __address_word 0xFF; EEARH = __address_word 8; EECR |= 1EERE; __result = EEDR; return __result; } This is plain C, but it's forced to be in this specific order, since all (!) access is to volatile memory. There is no timing constraint on instruction sequence so there is no problem. For -O0 it generates large but valid code. For -O[123] it gives all the same small code For -Os it might give a function call, so I added the always_inline constraint. Then it gives the same results, however it's arguable to leave the inlining to gcc, since it might be smaller (in case of several calls) My C function gives much, much smaller code. GCC gets its hands tide up because of the assembler, it forgets it can recycle registers etc... So I would recommend this C function approach for all read routines. Of course read word could be made more sophisticated using gcc ability to check on constants (__builtin_constant_p), so you could then check for page crossing and write the high address only once. The write sequence is best to be in asm since it needs a special timing and interrupt clearing. One last thing, why is there a loop before every function? In the old code there is no loop (although the documentation state there is!?!). And the old code is not disabling interrupts during eeprom write... which is no good! Maybe this was the problem of the report for the tiny13? HTH Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
RE: [avr-libc-dev] Problem accessing bytes in program space
uart_puts (strcpy_P (buf, (PGM_P)pgm_read_word (sms_keys[num][2]))) I'd expect this to print the numth string starting at the 3 character (it works as expected in non-embedded normal C). Am I doing something cluelessly wrong, or am I tickling a bug in the compiler? I'm using avr-libc-1.4.6 with avr-gcc 3.4.3 (using a newer version of gcc is a bit problematic at the moment...). Well I think you got it little bit wrong. In written quick out version you're now doing this: p = sms_keys[num]; p+=2; //This is not what you want! //You are now pointer to two bytes ahead of sms_keys[num] p = pgm_read_word(p); p = strcpy_P(buf, p); uart_puts(p); While you wanted to do this: p = sms_keys[num]; p = pgm_read_word(p); p+=2; //You want to access bytes 2 of the string p = strcpy_P(buf, p); uart_puts(p); so in your put-all-on-one-line scheme you would get: uart_puts (strcpy_P (buf, ((PGM_P)pgm_read_word(sms_keys[num]))[2] )) I did not test above line, but I hope you get the idea. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
RE: [avr-libc-dev] [RFC] New eeprom.h
Or inline functions defined in a header file. Sheesh. You guys are making comments about *how* I implemented the functionality, not if it *actually works*. Well I would, if I knew where to get the sources... There not on the list, not in the avr-libc bug report. So where can I find them? HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] New release?
It's a bit late to be discussing these issues, or reworded: I wish that discussions like this were done a lot earlier. I'm planning on release WinAVR with GCC 4.2.2. The most major issue that I see right now is GCC bug #29524 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29524 I would like to see a patch for this (even if it is not perfect but works) sometime next week. I tried the code example in the bug report using -lm against 4.2.2 and it then is around 600 bytes Are you aware of this? I tried fixing this by implementing the __clzm in the libgcc.s But I did not succeed, because gcc would still use his own. This is probably because i missed some config somewhere. But I could not find documentation on using the library. Any pointers are well come. I might give it another try this weekend. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [bug #21623] boot.h: Use the z register constraint
Shaun Jackman schreef: Follow-up Comment #2, bug #21623 (project avr-libc): Definitely remove r30 and r31 from the clobber. The spm instruction doesn't clobber the Z register, since it has the same value going out as coming in. If it did modify the Z register, it should be listed with a read/write constraint, as in +z or possibly +z if it's an early clobber. Do you have a small test case for the EEPROM bug you mentioned? I've had no problem, and I'm using both gcc and avr-libc from head. I use both the EEPROM API and my flash patch with no trouble. I'm certainly not against more testing though. The EEPROM problem arises when there are many (IIRC at least 7) 16 bit registers used and need to be saved over a call then gcc fails allocating space for the 16 bit vars. For more details look at this bug report http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31644 In your case however it is totally different. Here the spm instruction needs the Z register. The datasheets (for the Atmega324p and Atmeg8535) states that: Once a programming operation is initiated, the address is latched and the Z-pointer can be used for other operations. So it's save to assume it's not modified. In the EEPROM read word function Z was used as return value but it was not strictly necessary, any arbitrary 16 bit reg was ok. Somehow using Z as output of a assembler piece is causing trouble when having many local values. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] Re: [bug #21410] Incorrect use of 16-bit eepromaddresses in devices with 8-Bit address registers
Eric Weddington wrote: -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] org] On Behalf Of Joerg Wunsch Sent: Wednesday, October 24, 2007 6:28 AM To: avr-libc-dev@nongnu.org Subject: [avr-libc-dev] Re: [bug #21410] Incorrect use of 16-bit eepromaddresses in devices with 8-Bit address registers As Wouter van Gulik wrote: What is the main reason not to build a per-device lib, apart from the time to do such a thing? I quickly scanned the mailing archives but I could only find the build time as a reason. Is this still valid? Basically yes. With the current number of AVRs we are supporting (and Eric adding another dozen or so right now), the build time for the entire avr-libc project could easily reach something like half an hour, which is way too long. I think that argument is bogus. It is only the toolchain distro maintainers and the avr-libc developers that have to eat up that time. I think that is reasonable considering the value of the feature. Besides, we need to get you a faster machine, Joerg. ;-) IMHO, the biggest issue is the amount of developer time needed to make the change, the resulting testing, and the other reason you mention below: If we were to change the model to a per-device library one, we'd also have to think of a good transition scheme, because this library model scheme is hand-wired into the GCC (compiler driver) code. So it's not only we need a new avr-libc but also a new GCC. One possible option for that is to start with avr-libc building per-device *and* per-architecture libraries for quite some time, and only then start modifying GCC. And *that* is the biggest reason why it hasn't been done yet. Coordinating the two projects. Maybe we must make a separation between peripheral drivers and the library functions. There are basically two area's why per device is desirable: different instruction set's (movwmul) And different peripherals requiring different approaches. (I regard eeprom as a peripheral here) The trouble off the different instruction sets is tackled by the architectures. However trying to bundle the peripherals is now breaking avr-libc. At the moment I can only see eeprom as a supported peripheral over all devices. Maybe fuse read support would be peripheral support. I am not pleading to implement all peripherals, just a valid reason not to implement a true per device lib. But merely a per-device-lib-for-the-peripherals. Since the peripheral differ most it seems legal to split it this way. Just my 2 cents. Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [bug #21382] vscanf problem with %s when a width is given
Lars Jonsson schreef: Follow-up Comment #2, bug #21382 (project avr-libc): Ok, good that is is known but I don't really get the concept of private bugs. I don't get this either. Maybe because it's somehow a potential security issue? What is a private bug? And why? HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: [avr-libc-dev] [bug #21382] vscanf problem with %s when a width is given
Joerg Wunsch schreef: As Joerg Wunsch wrote: I disabled the privacy field in the Web form, because I think it doesn't make any sense for the avr-libc deliveries. There have been two other (already closed) bugs with privacy set to Private, so I postum made them public as well. Oke thanks! I allready hoped it was just a mistake. Good thing this feature is now turned off! Thanks for the quick action. Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: AW: [avr-libc-dev] eeprom_read_word causes problems for the compiler
Haase Bjoern (PT/EMM1) schreef: Yes I will try to put together a patch with the minimal changes. I only need to know one thing; can I assume that using this construction: /** \ingroup avr_eeprom Read one 16-bit word (little endian) from EEPROM address \c addr. */ uint16_t eeprom_read_word (const uint16_t *addr) { register uint16_t result asm(r24); //I can specify r24 only __asm__ __volatile__ ( XCALL __eeprom_read_word_ _REG_LOCATION_SUFFIX CR_TAB : +x (addr), =w (result) //Use w restrict to adiw capable registers : ); return result; } I fear that this will not be guaranteed to be correct! The compiler might reorder code and might be tempted to optimize away your result variable so that it could be placed in another register. The dangerous thing is, that your code might work sometimes! I was afraid so, but I look it up in the GCC documentation http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Local-Reg-Vars.html#Local-Reg-Vars This option does not guarantee that GCC will generate code that has this variable in the register you specify at all times. You may not code an explicit reference to this register in the assembler instruction template part of an asm statement and assume it will always refer to this variable. However, using the variable as an asm operand guarantees that the specified register is used for the operand. Also on: http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Explicit-Reg-Vars.html#Explicit-Reg-Vars These local variables are sometimes convenient for use with the extended asm feature (see Extended Asm), if you want to write one output of the assembler instruction directly into a particular register. (This will work provided the register you specify fits the constraints specified for that operand in the asm.) So it seems to me that it used as it was intended. So I think it's legal after all. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
Re: AW: [avr-libc-dev] eeprom_read_word causes problems for the compiler
Haase Bjoern (PT/EMM1) schreef: Yes I will try to put together a patch with the minimal changes. I only need to know one thing; can I assume that using this construction: /** \ingroup avr_eeprom Read one 16-bit word (little endian) from EEPROM address \c addr. */ uint16_t eeprom_read_word (const uint16_t *addr) { register uint16_t result asm(r24); //I can specify r24 only __asm__ __volatile__ ( XCALL __eeprom_read_word_ _REG_LOCATION_SUFFIX CR_TAB : +x (addr), =w (result) //Use w restrict to adiw capable registers : ); return result; } I fear that this will not be guaranteed to be correct! The compiler might reorder code and might be tempted to optimize away your result variable so that it could be placed in another register. The dangerous thing is, that your code might work sometimes! I found even more prove: http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Extended-Asm.html#Extended-Asm Sometimes you need to make an asm operand be a specific register, but there's no matching constraint letter for that register by itself. To force the operand into that register, use a local variable for the operand and specify the register in the variable declaration. See Explicit Reg Vars. Then for the asm operand, use any register constraint letter that matches the register: register int *p1 asm (r0) = ...; register int *p2 asm (r1) = ...; register int *result asm (r0); asm (sysint : =r (result) : 0 (p1), r (p2)); So I think it's perfectly legal to do what I wanted to do. I checked the documentation, this feature is documented back to at least 2.9.5. Did AVR even existed in GCC back then? If not it will not causes a problem for users building avr-libc with an older version of GCC The 2.9.5 documentation: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC96 HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
[avr-libc-dev] Eeprom read word is causing trouble
Hi List, I found that bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31644 is probably more related to avr-libc than gcc. The problem is the eeprom_read_word definition. It returns it's values in r31:r30 instead of the regular r25:r24. This somehow kills the compilers ability to relocate the return variables to the stack. If I change the definition in avr/eeprom.h to something like: uint16_t eeprom_read_word (const uint16_t *addr) { register uint16_t result asm(r24); //Force to r24 (is this valid?) __asm__ __volatile__ ( XCALL __eeprom_read_word_ _REG_LOCATION_SUFFIX CR_TAB : +x (addr), =r (result) // r in stead of z, maybe use w here? :); return result; } then all will compile ok. Of course you I need to change the eeprom_read_word routine to return to 25:r24. Is there any reason why the word is stored in r31:r30? I read Bjorn Haasse's post to the list concerning the new eeprom routine but could not find a reason. Further more it seems to me that eeprom_read_word defintion in eeprom.S can be a true C function if it return's using r25:r24. Then we could turn eeprom_read_word into a real function instead of an inline function that has inline asm that call the function. Apart from the bug I think it's more elegant to return in r25:r24 then in r31:r30. Another thing I noticed, I replaced the r24 with r30 (functionaly the same as =z) I get a different error, one concerning *movhi. This insn is shown in different bug reports, maybe this insn is the cause of the evil? So what is it for? Is it perhaps preventing relocation to RAM? Sorry for asking so many questions. Just want to sort this out. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
RE: [avr-libc-dev] eeprom_read_word causes problems for the compiler
I agree, this whole setup seems strange. Perhaps if you look in the CVS log (you can do it online at the avr-libc project), perhaps there may be some comments as to why it was originally done this way. Note that the EEPROM API was originally written (copyrighted) by Marek Michalkiewicz. Perhaps Marek (CCed) could explain more why it was done this way? AFAIK the EEPROM routines are rewritten from scratch by Bjoern Haase (CCed). The eeprom register addresses changed for a lot devices, there for the old library was not ok anymore. Bjorn did a good job on rewriting it, his post to the list describes all routines in details except the read word. In the CVS log's I see his patch changed made the read word return to r30:r31. But I can't figure out why. I like the idea of your proposed approach, to change the EEPROM routines into C functions. Well we can only do it for the eeprom_read_word. Changing the read_byte function would cause a growth in size. As I said, Bjoern did a good job :D I think the advantage of the inline-C-function-with-inline-assembler-call is the reduced register used. In stead of a call the compiler sees a block assembler which uses the X register and the R30:R31 (or R25:R24 if we change it). But it still does not solve the mystery on using r31:r30. Is there any way that you would be willing to work up an implementation? Yes I will try to put together a patch with the minimal changes. I only need to know one thing; can I assume that using this construction: /** \ingroup avr_eeprom Read one 16-bit word (little endian) from EEPROM address \c addr. */ uint16_t eeprom_read_word (const uint16_t *addr) { register uint16_t result asm(r24); //I can specify r24 only __asm__ __volatile__ ( XCALL __eeprom_read_word_ _REG_LOCATION_SUFFIX CR_TAB : +x (addr), =w (result) //Use w restrict to adiw capable registers : ); return result; } that the compiler will not use r25 for other purposes? Note that this goes inline! More generally is this a sane thing to do? Is there any objection for doing it this way? Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
[avr-libc-dev] eeprom_read_word causes problems for the compiler
Hi List, I found that bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31644 is probably more related to avr-libc than gcc. The problem is the eeprom_read_word definition. It returns it's values in r31:r30 instead of the regular r25:r24. This somehow kills the compilers ability to relocate the return variables to the stack. If I change the definition in avr/eeprom.h to something like: uint16_t eeprom_read_word (const uint16_t *addr) { register uint16_t result asm(r24); //Force r24 (is this allowed?) __asm__ __volatile__ ( XCALL __eeprom_read_word_ _REG_LOCATION_SUFFIX CR_TAB : +x (addr), =r (result)// r in stead of z, maybe use w here? : /* No read */) ; return result; } then all will compile ok. Of course I need to change the eeprom_read_word routine to return 25:r24. Is there any reason why the word is stored in r31:r30? I read Bjorn Haasse's post to the list concerning the new eeprom routine but could not find a reason. Further more it seems to me that eeprom_read_word defintion in eeprom.S can be a true C function if it return's using r25:r24. Then we could turn eeprom_read_word into a real function instead of an inline function that has inline asm that call the function. Apart from the bug I think it's more elegant to return in r25:r24 then in r31:r30. Another thing I noticed, I replaced the r24 with r30 (functionaly the same as =z) I get a different error, one concerning *movhi. This insn is shown in different bug reports, maybe this insn is the cause of the evil? So what is it for? Is it perhaps preventing relocation to RAM? Sorry for asking so many questions. Just want to sort this out. HTH, Wouter ___ AVR-libc-dev mailing list AVR-libc-dev@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-libc-dev