On Fri, Feb 15, 2013 at 01:16:27AM +0100, Georg-Johann Lay wrote: > Jonathan Geisler schrieb: > > I'm encountering a strange error with avr-gcc 4.6.3 and 4.7.2 using > > the timer interrupt. The code I'm using is attached. As you can see, > > I was trying to tie in to the Arduino environment (with Eclipse) so > > that I could help my students wean off that set of functions to being > > able to use the hardware directly. > > > > When I set up the library, I encountered a strange error and was able > > to trace it back to this simple program that sets up the timer with a > > prescalar of 1024 and then increments an unsigned long counter when > > that timer overflows. When the counter reaches a specific value, I > > toggle the built-in LED on the Arduino board connected to PORTB. > > > > The strange behavior is that if I initialize the counter to 0, the > > code doesn't work--appearing to hang. If I initialize the counter to > > 1, everything works perfectly. I have verified that if I make a > > similar change to the Arduino libraries that the original code begins > > to work properly. > > > > I'm not sure what the exact error is since I can use the Arduino > > environment on my machine without a problem, but when I try to compile > > it through Eclipse it gives me this error. I'll include the build log > > as an attachment in case particular compiler/linker flags are triggering > > the error. > > When you change count in the ISR and read it in main, the read must be > atomic. Otherwise, you may see glitches and phantom values. > > It atomic access does not help, you can compare the code generated with > your Eclipse setup and with your Arduino setup.
The atomic accesses didn't help. I didn't include that originally because the Arduino doesn't include them. For my C code, they appear to be identical. I didn't compare the extra code added by the linker. > You cal also check the generated assembly whether or not it is as you > expect. If so, your problem is somewhere else. The asm code for my C code appears to be correct. That is what is so perplexing to me. Note that the test code is a distillation of what the Arduino environment does and it quite succinct, but displays the error quite reliably. > You could also supply a test case that can be compiled and reproduced. > > To get a test case, add -v -save-temps to the compiler options and > recompile. Then post the console output of the compiler and the .ii file. Here is the console output. I'm attaching the .ii file and the .cpp file used for the compilation. [227] jgeisler:~/classes/enp341 % avr-g++ -Wall -Os -ffunction-sections -fdata-sections -fno-exceptions -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"main.d" -MT"main.d" -c -o test.o test.cpp -v -save-temps Using built-in specs. COLLECT_GCC=/usr/x86_64-pc-linux-gnu/avr/gcc-bin/4.7.2/avr-g++ Target: avr Configured with: /var/tmp/portage/cross-avr/gcc-4.7.2/work/gcc-4.7.2/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/avr/gcc-bin/4.7.2 --includedir=/usr/lib/gcc/avr/4.7.2/include --datadir=/usr/share/gcc-data/avr/4.7.2 --mandir=/usr/share/gcc-data/avr/4.7.2/man --infodir=/usr/share/gcc-data/avr/4.7.2/info --with-gxx-include-dir=/usr/lib/gcc/avr/4.7.2/include/g++-v4 --host=x86_64-pc-linux-gnu --target=avr --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --without-ppl --without-cloog --enable-lto --enable-nls --without-included-gettext --with-system-zlib --enable-obsolete --disable-werror --enable-secureplt --disable-multilib --disable-libmudflap --disable-libssp --disable-libgomp --with-python-dir=/share/gcc-data/avr/4.7.2/python --enable-poison-system-directories --enable-checking=release --disable-libgcj --disable-libquadmath --enable-languages=c,c++ --enable-shared --disable-threads --disable-bootstrap --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.7.2 p1.0, pie-0.5.3' Thread model: single gcc version 4.7.2 (Gentoo 4.7.2 p1.0, pie-0.5.3) COLLECT_GCC_OPTIONS='-Wall' '-Os' '-ffunction-sections' '-fdata-sections' '-fno-exceptions' '-mmcu=atmega328p' '-D' 'F_CPU=16000000UL' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-c' '-o' 'test.o' '-v' '-save-temps' /usr/libexec/gcc/avr/4.7.2/cc1plus -E -quiet -v -MMD test.d -MF main.d -MP -MT main.d -D F_CPU=16000000UL test.cpp -mmcu=atmega328p -Wall -ffunction-sections -fdata-sections -fno-exceptions -Os -fpch-preprocess -fno-rtti -fno-enforce-eh-specs -fno-exceptions -o test.ii ignoring nonexistent directory "/usr/lib/gcc/avr/4.7.2/include/g++-v4" ignoring nonexistent directory "/usr/lib/gcc/avr/4.7.2/include/g++-v4/avr" ignoring nonexistent directory "/usr/lib/gcc/avr/4.7.2/include/g++-v4/backward" ignoring nonexistent directory "/usr/lib/gcc/avr/4.7.2/../../../../avr/sys-include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/avr/4.7.2/include /usr/lib/gcc/avr/4.7.2/include-fixed /usr/lib/gcc/avr/4.7.2/../../../../avr/include End of search list. COLLECT_GCC_OPTIONS='-Wall' '-Os' '-ffunction-sections' '-fdata-sections' '-fno-exceptions' '-mmcu=atmega328p' '-D' 'F_CPU=16000000UL' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-c' '-o' 'test.o' '-v' '-save-temps' /usr/libexec/gcc/avr/4.7.2/cc1plus -fpreprocessed test.ii -quiet -dumpbase test.cpp -mmcu=atmega328p -auxbase-strip test.o -Os -Wall -version -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-enforce-eh-specs -fno-exceptions -o test.s GNU C++ (Gentoo 4.7.2 p1.0, pie-0.5.3) version 4.7.2 (avr) compiled by GNU C version 4.5.4, GMP version 5.0.2, MPFR version 3.0.1-p4, MPC version 0.8.2 warning: MPFR header version 3.0.1-p4 differs from library version 3.1.1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (Gentoo 4.7.2 p1.0, pie-0.5.3) version 4.7.2 (avr) compiled by GNU C version 4.5.4, GMP version 5.0.2, MPFR version 3.0.1-p4, MPC version 0.8.2 warning: MPFR header version 3.0.1-p4 differs from library version 3.1.1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 5e7b521416cf40df37e35c64e8937dd8 COLLECT_GCC_OPTIONS='-Wall' '-Os' '-ffunction-sections' '-fdata-sections' '-fno-exceptions' '-mmcu=atmega328p' '-D' 'F_CPU=16000000UL' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-c' '-o' 'test.o' '-v' '-save-temps' /usr/libexec/gcc/avr/as -mmcu=atmega328p -mno-skip-bug -o test.o test.s COMPILER_PATH=/usr/libexec/gcc/avr/4.7.2/:/usr/libexec/gcc/avr/4.7.2/:/usr/libexec/gcc/avr/:/usr/lib/gcc/avr/4.7.2/:/usr/lib/gcc/avr/ LIBRARY_PATH=/usr/lib/gcc/avr/4.7.2/:/usr/lib/gcc/avr/4.7.2/../../../../avr/lib/ COLLECT_GCC_OPTIONS='-Wall' '-Os' '-ffunction-sections' '-fdata-sections' '-fno-exceptions' '-mmcu=atmega328p' '-D' 'F_CPU=16000000UL' '-MMD' '-MP' '-MF' 'main.d' '-MT' 'main.d' '-c' '-o' 'test.o' '-v' '-save-temps' [228] jgeisler:~/classes/enp341 % -- Jonathan Geisler --
#include <avr/interrupt.h> #include <util/atomic.h> void setup() { TCCR0A = 0; TCCR0B = 5; TIMSK0 = 1; sei(); DDRB |= 0x20; } volatile unsigned long count = 0; // bad executable if initialized to 0!!! void loop() { ATOMIC_BLOCK(ATOMIC_FORCEON) { if (count > 50) { PORTB ^= 0x20; count = 0; } } } ISR(TIMER0_OVF_vect) { ++count; } int main() { setup(); while (1) { loop(); } }
# 1 "test.cpp" # 1 "<command-line>" # 1 "test.cpp" # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/interrupt.h" 1 3 # 38 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/interrupt.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 1 3 # 99 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/sfr_defs.h" 1 3 # 126 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/sfr_defs.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/inttypes.h" 1 3 # 37 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/inttypes.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/include/stdint.h" 1 3 4 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 1 3 4 # 121 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 3 4 typedef signed int int8_t __attribute__((__mode__(__QI__))); typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); typedef signed int int16_t __attribute__ ((__mode__ (__HI__))); typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); typedef signed int int32_t __attribute__ ((__mode__ (__SI__))); typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); typedef signed int int64_t __attribute__((__mode__(__DI__))); typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); # 142 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 3 4 typedef int16_t intptr_t; typedef uint16_t uintptr_t; # 159 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 3 4 typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; # 213 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 3 4 typedef int8_t int_fast8_t; typedef uint8_t uint_fast8_t; typedef int16_t int_fast16_t; typedef uint16_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; # 273 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/stdint.h" 3 4 typedef int64_t intmax_t; typedef uint64_t uintmax_t; # 4 "/usr/lib/gcc/avr/4.7.2/include/stdint.h" 2 3 4 # 38 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/inttypes.h" 2 3 # 77 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/inttypes.h" 3 typedef int32_t int_farptr_t; typedef uint32_t uint_farptr_t; # 127 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/sfr_defs.h" 2 3 # 100 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 222 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/iom328p.h" 1 3 # 223 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 432 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/portpins.h" 1 3 # 433 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/common.h" 1 3 # 435 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/version.h" 1 3 # 437 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/fuse.h" 1 3 # 239 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/fuse.h" 3 typedef struct { unsigned char low; unsigned char high; unsigned char extended; } __fuse_t; # 440 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/lock.h" 1 3 # 443 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/io.h" 2 3 # 39 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/avr/interrupt.h" 2 3 # 2 "test.cpp" 2 # 1 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/util/atomic.h" 1 3 # 42 "/usr/lib/gcc/avr/4.7.2/../../../../avr/include/util/atomic.h" 3 static __inline__ uint8_t __iSeiRetVal(void) { __asm__ __volatile__ ("sei" ::: "memory"); return 1; } static __inline__ uint8_t __iCliRetVal(void) { __asm__ __volatile__ ("cli" ::: "memory"); return 1; } static __inline__ void __iSeiParam(const uint8_t *__s) { __asm__ __volatile__ ("sei" ::: "memory"); __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iCliParam(const uint8_t *__s) { __asm__ __volatile__ ("cli" ::: "memory"); __asm__ volatile ("" ::: "memory"); (void)__s; } static __inline__ void __iRestore(const uint8_t *__s) { (*(volatile uint8_t *)((0x3F) + 0x20)) = *__s; __asm__ volatile ("" ::: "memory"); } # 3 "test.cpp" 2 void setup() { (*(volatile uint8_t *)((0x24) + 0x20)) = 0; (*(volatile uint8_t *)((0x25) + 0x20)) = 5; (*(volatile uint8_t *)(0x6E)) = 1; __asm__ __volatile__ ("sei" ::: "memory"); (*(volatile uint8_t *)((0x04) + 0x20)) |= 0x20; } volatile unsigned long count = 0; void loop() { for ( uint8_t sreg_save __attribute__((__cleanup__(__iSeiParam))) = 0, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) { if (count > 50) { (*(volatile uint8_t *)((0x05) + 0x20)) ^= 0x20; count = 0; } } } extern "C" void __vector_16 (void) __attribute__ ((signal,used, externally_visible)) ; void __vector_16 (void) { ++count; } int main() { setup(); while (1) { loop(); } }
signature.asc
Description: Digital signature
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list