Re: [avr-gcc-list] avr-gcc-4 TinyOs
Bob Paddock wrote: If you are interested in State Machines check out the Ragel State Machine Compiler. http://www.cs.queensu.ca/~thurston/ragel/ I've used it with GCC and AVR's for years. I have looked at it, but it doesn't support the Harel/UML-style hierarchical state machines that I tend to end up with. Instead of a generator, I use a framework that has been ported to the AVR (I did the first AVR port that I know of, but it has also been done by the guy who wrote it). See the Quantum Framework at: http://www.quantum-leaps.com/ This framework supports event queueing, may be set up to be preemptive, is well documented, and is pretty light-weight in terms of code size and speed (and very light-weight in RAM usage). There is a light version of it called QP-Nano that is quite appropriate for the smaller AVRs (say the AVR45). http://www.quantum-leaps.com/products/index.htm#QP-nano AVR port at: http://www.quantum-leaps.com/avr/index.htm The QDK-nano AVR-GCC is dual-licensed (GPL/commercial), so depending on your needs you should be able to find something that fits. Price is reasonable. It's royalty-free. Ned Konz ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] avr-gcc-4 TinyOs
Domenico Arenga wrote: I'm a student of the university of Pisa, Italy. I would want to know if it is possible to use avr-GCC 4 on tinyOs. Excuse the disturbance, and thanks thousands. The extensions to the compiler that the TinyOS people did to support the state machine constructs would be hard (as I recall, anyway) to do with straight GCC. Certainly you can use avr-GCC on the *hardware* but that's apparently not what you were asking. Ned Konz ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] avr-gcc-4 TinyOs
[mistakenly sent to avr-chat initially] Arnim Littek wrote: Ned Konz [EMAIL PROTECTED] 16/10/2007 2:21 a.m. Domenico Arenga wrote: I'm a student of the university of Pisa, Italy. I would want to know if it is possible to use avr-GCC 4 on tinyOs. Excuse the disturbance, and thanks thousands. The extensions to the compiler that the TinyOS people did to support the state machine constructs would be hard (as I recall, anyway) to do with straight GCC. You're making some interesting noises here. Do you have any pointers to what they've done over and above, say, function pointers? Like many projects that wanted to extend the C (or C++) language, they started with GCC. They added interface wiring, native state machine constructs, and probably other things that I don't recall. See: http://www.tinyos.net/ http://nesc.sf.net http://lecs.cs.ucla.edu/Resources/testbed/testbed-motes.html ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] C and AS programs - compiled together
Grzegorz !Kubik wrote: I would like to align 256B buffer at the RAM address 0xXX00 - to use 8-bit buffer pointers. Well, IMHO there's an .align pseudo-op. This is potentially wasting up to 255 bytes of RAM then. Agree. But my task is to reuse existing assembler program (that has 8-bit pointers for simplicity and speed), so waisting some RAM is acceptable. How are you getting 8-bit pointers to work in avr-gcc? .align is from assembler side. C declarations look more convenient for me. But I found in: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Attribute-Syntax.html#Attribute-Syntax that: ...for example, the usage of `aligned' and `noreturn' attributes given above is not yet supported What is and what is not supported? Anyway, reading linker manual may be necessary ;-( I would prefer simple example of aligning 256B buffer to 0xXX00 address in RAM... The linker manual is not large. It's probably easiest to define a section starting on the appropriate boundary (using a custom linker file), and then tell the compiler to put the buffer into that section. -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Bit-wise structure and unions
bitUBRR18 0 #define bitUBRR19 1 #define bitUBRR110 2 #define bitUBRR111 3 /* multi-bit fields */ /* UBRR1 ($CC) (page 193) -- / */ typedef union UBRR1_t { uint16_t asWord; struct { uint16_t bUBRR10 :1; uint16_t bUBRR11 :1; uint16_t bUBRR12 :1; uint16_t bUBRR13 :1; uint16_t bUBRR14 :1; uint16_t bUBRR15 :1; uint16_t bUBRR16 :1; uint16_t bUBRR17 :1; uint16_t bUBRR18 :1; uint16_t bUBRR19 :1; uint16_t bUBRR110 :1; uint16_t bUBRR111 :1; uint16_t bReserved4 :1; uint16_t bReserved5 :1; uint16_t bReserved6 :1; uint16_t bReserved7 :1; } b; struct { uint16_t fUBRR1 :12; uint16_t :1; /* Reserved4 */ uint16_t :1; /* Reserved5 */ uint16_t :1; /* Reserved6 */ uint16_t :1; /* Reserved7 */ } f; } UBRR1_t; #define UBRR1_sfr (*(volatile UBRR1_t *) (0xCC)) /* single bits */ /* bit numbers */ /* multi-bit fields */ #define UBRR1 UBRR1_sfr.f.fUBRR1 -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] AVR-GCC Ubuntu Help
Andre Gustavo Degraf Uchoa wrote: Hi, I am using Linux Ubuntu 6.06, and I am Trying to install the lasted version avr-libc under such plataform, but I am having some Errors messages. I have created an special paste called /tool to install the binutils, avr-gcc, and the avr-libc. I am interested on the lasted version of avr-libc due to the devices supported are Atmega2560 an 2561. My pc is an i686-pc-linux-gnu. Binutils version is 2.17, gcc compiler version is 4.0.3, the avr-libc version is 1.4.5 When I make the ./configure for avr-libc I receive such message: configure: error: Wrong C compiler found; check the PATH! But I check the path and is all right, I don't understand where is the error. Thank your attention What arguments are you giving to configure? Specifically, what value are you providing for --host? It should be --host=avr as I recall. -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Patching EEPROM image for production
dimax un wrote: Hi Folks, I'm trying to find clean solution for the following system problem. I have configuration structure in EEPROM: struct VPD_t { char sn[10]; char id[20]; }VPD EEPMEM; While linking I generate EEPROM image in lets say VPD.eep file. For production purposes I need to burn every product with different sn and id. So I have to patch VPD.eep all the time. I'm trying to make a script that has VPD.eep sn and id on it's input and generates VPS_sn.eep with patched sn and id on it's output. Why not just program it in two (or more) pieces using a single script? Unchanging VPD.eep programmed first; doesn't program the area for the SN and ID numbers. Then generate the SN/ID on the fly and burn it into the right place. You can reserve space in your main program for it and know where it is by using a named linker section for it and using the section pragma to place it in the right place. avrdude is good for this. -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Patching EEPROM image for production
dimax un wrote: Hi Folks, I'm trying to find clean solution for the following system problem. I have configuration structure in EEPROM: struct VPD_t { char sn[10]; char id[20]; }VPD EEPMEM; While linking I generate EEPROM image in lets say VPD.eep file. For production purposes I need to burn every product with different sn and id. So I have to patch VPD.eep all the time. I'm trying to make a script that has VPD.eep sn and id on it's input and generates VPS_sn.eep with patched sn and id on it's output. Why not just program it in two (or more) pieces using a single script? Unchanging VPD.eep programmed first; doesn't program the area for the SN and ID numbers. Then generate the SN/ID on the fly and burn it into the right place. You can reserve space in your main program for it and know where it is by using a named linker section for it and using the section pragma to place it in the right place. avrdude is good for this. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Jmp'ing to address / 2?
Stuart Whelan wrote: Hi Folks, I am using gcc 3.4.4 and avr-libc 1.4.4 on win32 I have been using the CodeVision compiler for a long time, but have decided to port my projects to gcc-avr. My application jumps to the bootloader on receipt of jump to bootloader command, but the jmp I am using seems to be doing strange things. I cut it done down to the smallest test: main() { asm volatile(jmp 0x1c00::); } And compiled it with: avr-gcc -mmcu=atmega16 -o foo.obj foo.c And the jmp command comes out as: 96: 0c 94 00 0e jmp 0x1c00 __stack+0x17a1 Now if I read that correctly, it is jmp'ing to 0e00, not 1c00.. I notice that 0e00 is 1c00/2... Jumps are to word addresses. You can't jump to an odd address, so call/jmp (at the processor level) are in terms of words (not bytes). When I step through this in the debugger, the program counter does indeed jump to 0e00, not 1c00. That's correct. The GNU toolchain (avr-gcc and avr-as, anyway) uses byte addresses. The AVR uses word addresses for program memory (which is more than 1 byte wide). Compare the code generated for the following jump: typedef void (* funcptr) (void); goto *(funcptr)0x1c00; // a gcc extension; should do what you want: a4: e0 e0 ldi r30, 0x00 ; 0 a6: fc e1 ldi r31, 0x1C ; 28 a8: 09 94 ijmp -- Ned Konz http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] AVR-
Khusro wrote: I am trying to build the latest GCC snapshot for the WinXP platform using MinGW. I get the error in the log below. The system is looking for bison which I don't have. Then it is looking for gengtype-yacc.h which does exist in the latest snapshot directory I check out using SVN. Why not just get Bison? It looks like the gengtype-yacc.[ch] files are generated using Bison. Here's a partial listing of my gcc/ directory: neds_mini:gcc $ ls -latr gengtype* these were original: -rw-r--r-- 1 ned ned 81280 Jun 24 2005 gengtype.c -rw-r--r-- 1 ned ned5256 Jun 24 2005 gengtype.h -rw-r--r-- 1 ned ned7359 Jun 24 2005 gengtype-yacc.y -rw-r--r-- 1 ned ned 15493 Jun 24 2005 gengtype-lex.l these were generated: -rw-r--r-- 1 ned ned2584 Feb 28 00:40 gengtype-yacc.h -rw-r--r-- 1 ned ned 50985 Feb 28 00:40 gengtype-yacc.c -rw-r--r-- 1 ned ned 139164 Feb 28 00:40 gengtype-lex.c Thanks, -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Two interrupts one function?
Trampas wrote: I have two external interrupts connected to a quadature encoder, I do the same operations when either interrupt pin is changed. I was wondering if it was possible to have one ISR that is called from both interrupts. If so how do I do it? Seems like this would work (jump from the second handler to the first). Look at the definition of ISR(), EMPTY_INTERRUPT(), and _VECTOR() /* avr-gcc -Os -mmcu=atmega128 -Wa,-ahlsd=twoisrs.lst -o twoisrs.elf twoisrs.c */ #include avr/io.h #include avr/interrupt.h // defines __vector_1 ISR(INT0_vect) { // do your thing here... } // or use whatever interrupt number you need to: void INT1_vect(void) __attribute__ ((signal, naked)); void INT1_vect(void) { __asm__ __volatile__ (jmp __vector_1 ::); } int main(void) { } Thanks, -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Two interrupts one function?
Ned Konz wrote: Trampas wrote: I have two external interrupts connected to a quadature encoder, I do the same operations when either interrupt pin is changed. I was wondering if it was possible to have one ISR that is called from both interrupts. If so how do I do it? Seems like this would work (jump from the second handler to the first). Look at the definition of ISR(), EMPTY_INTERRUPT(), and _VECTOR() Here's a version with a macro called ALIAS_VECTOR() to hide much of the ugliness: /* * Shows how to share a single ISR between two or more interrupts, * using a jmp instruction to get from the secondary interrupt(s) to the primary code. avr-gcc -Os -mmcu=atmega128 -Wa,-ahlsd=twoisrs.lst -o twoisrs.elf twoisrs.c */ #include avr/io.h #include avr/interrupt.h // Syntactic sugar: #define ALIAS_VECTOR(fromName,toNum) \ void fromName(void) __attribute__ ((signal, naked)); \ void fromName(void) \ { \ __asm__ __volatile__ (jmp __vector_ #toNum ::); \ } // defines __vector_1 ISR(INT0_vect) { // your code here } // defines __vector_2 (INT1_vect) to jump to __vector_1 (INT0_vect) ALIAS_VECTOR(INT1_vect,1) int main(void) { } Thanks, -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] C++ and aggregates in flash memory
I'm using C++ with avr-gcc 4.1 (and also with 4.2-pre). I've noticed that if I put constant structs in flash memory (simple aggregates: no virtual functions, constructors, destructors, private, or protected) that I get some very stupid constructors that then clobber my I/O registers before main(). This even happens when I'm using the optimizer. For instance, when I declare the structs like this: struct DeviceSettings { volatile uint8_t *csPortAddress; //! pointer to PORTC or PORTG uint8_t csBitMask; //! mask for CS signal on port uint8_t csPolarity:1;//! active level of CS signal uint8_t cpol:1; //! setting for CPOL uint8_t cpha:1; //! setting for CPHA uint8_t dord:1; //! setting for DORD (data order) ClockRate clock:3; //! SPI2X:SPR1:SPR0, SPI_ClockRate uint8_t :1; //! unused }; extern const struct AllDeviceSettings { DeviceSettings display, leds, gainPot, trimPot, dac1, dac2, atod, dataflash, sdCard; } PROGMEM spiDeviceSettings; and then define them like this: const AllDeviceSettings PROGMEM spiDeviceSettings = { /* .display */ { /* .csPortAddress */ atmega128::PORTC, /* .csBitMask */ DISP_CS.mask(), /* .csPolarity */ 0, /* .cpol */ 0, /* .cpha */ 0, /* .dord */ 0, /* .clock */ SPI_CLOCK_1_92_M }, /* .leds */ { /* .csPortAddress */ atmega128::PORTC, /* .csBitMask */ LEDS_CS.mask(), /* .csPolarity */ 0, /* .cpol */ 1, /* .cpha */ 1, /* .dord */ 0, /* .clock */ SPI_CLOCK_7_68_M }, // 7 more of the same kind of struct definition ... }; that I get the following kind of very silly global constructor code (which gets called before main()): __static_initialization_and_destruction_0(int, int)(): f26: sbiwr24, 0x01 ; 1 f28: breq.+2 ; 0xf2c f2a: ret f2c: subir22, 0xFF ; 255 f2e: sbcir23, 0xFF ; 255 f30: brne.-8 ; 0xf2a f32: ldi r24, 0x35 ; 53 f34: ldi r25, 0x00 ; 0 f36: sts 0x0096, r25 f3a: sts 0x0095, r24 f3e: ldi r19, 0x01 ; 1 f40: sts 0x0097, r19 f44: sts 0x009A, r25 f48: sts 0x0099, r24 f4c: ldi r18, 0x02 ; 2 f4e: sts 0x009B, r18 f52: sts 0x009E, r25 f56: sts 0x009D, r24 f5a: ldi r18, 0x04 ; 4 f5c: sts 0x009F, r18 f60: sts 0x00A2, r25 f64: sts 0x00A1, r24 f68: ldi r18, 0x08 ; 8 f6a: sts 0x00A3, r18 f6e: sts 0x00A6, r25 f72: sts 0x00A5, r24 f76: ldi r18, 0x10 ; 16 f78: sts 0x00A7, r18 f7c: sts 0x00AA, r25 f80: sts 0x00A9, r24 f84: ldi r18, 0x20 ; 32 f86: sts 0x00AB, r18 f8a: sts 0x00AE, r25 f8e: sts 0x00AD, r24 f92: ldi r24, 0x40 ; 64 f94: sts 0x00AF, r24 f98: ldi r24, 0x65 ; 101 f9a: ldi r25, 0x00 ; 0 f9c: sts 0x00B2, r25 fa0: sts 0x00B1, r24 fa4: sts 0x00B3, r19 fa8: sts 0x00B6, r25 fac: sts 0x00B5, r24 fb0: sts 0x00B7, r19 fb4: ret Note that the addresses 0x0095 through 0x00b7 that it's trying to write to are actually addresses in *flash* (which are already initialized in the object file in the .text section), but the generated code actually clobbers various registers in I/O space instead. Here's what it is trying to initialize: 0095 g O .text 0024 spiDeviceSettings and of course it's already set up correctly in the ROM image, in the .text section: 0095 spiDeviceSettings: 95: [EMAIL PROTECTED]@ a5: ...F...F...A b5: ...A Is there some easy way around this problem? Thanks, -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] C++ and aggregates in flash memory
Joerg Wunsch wrote: Ned Konz [EMAIL PROTECTED] wrote: const AllDeviceSettings PROGMEM spiDeviceSettings = { /* .display */ { /* .csPortAddress */ atmega128::PORTC, Btw., no need to write the field names as comments. I know; this started out as C99 code that actually used the field initializer syntax, and it was easy to keep the field names by using an editor macro. I suppose that the definition of this structure could, in fact, go back into a C file (I wonder if that would cure the problem for now). Is there some easy way around this problem? Are you incidentally volunteering as C++ maintainer for AVR-GCC and avr-libc? :-) I was trying not to. I am working on a C++ library for the AVRs, though. I'd say file a bug report for GCC, though I'm afraid there won't be anyone to work on this. I don't really have time to get familiar with GCC; I suspect that I'll end up having to do something like editing the resultant assembly output, object files or linker scripts somehow for the time being. I was just hoping that someone had an idea about why the global constructor mechanism was being used for something that didn't need it, but I realize that GCC doesn't know about different kinds of memory spaces. Thanks, -- Ned Konz [EMAIL PROTECTED] http://bike-nomad.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Suggestion
On May 1, 2006, at 12:56 PM, Royce Pereira wrote: Hi, On Tue, 02 May 2006 01:07:29 +0530, Joerg Wunsch [EMAIL PROTECTED] wrote: Royce Pereira [EMAIL PROTECTED] wrote: Can I get the same in my AVR-GCC .lst, .lss etc output files thru my makefile ? Even though Ned already showed you a way, I'm curious: what additional information would gain that that is not already present in the file timestamp(s)? OK, the timestamps are referring to the end of Sometimes I never know if the generated file was from the compiling I just did or from a previous compiling. By looking at the time- stamp, I know if it's been generated 1 minute ago, it's fresh. But if it still has last weeks time stamp after compiling, then uh-oh! It's just something I got used to with SDCC, coz sometimes some error messages were not being redirected to my editor window, so that was the only way to check if the compiling was successful. Of course, one can check the file creation date via explorer, but this is convenient, and also the time stamp wont change inadvertently. I think that probably the best bet is to have a properly written Makefile; Make is very good at looking at timestamps and comparing them. Why would you have to? -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Suggestion
On Apr 29, 2006, at 11:59 PM, Royce Pereira wrote: Hi, I am using besides AVR-GCC, SDCC(freeware mcs51 compiler). The latter generates the following lines at the start of every output, which I find very useful - the date time actually: 1 ; 2 ; File Created by SDCC : FreeWare ANSI-C Compiler 3 ; Version 2.5.4 #1145 (Nov 4 2005) 4 ; This file generated Sun Apr 30 12:19:30 2006 5 ; Can I get the same in my AVR-GCC .lst, .lss etc output files thru my makefile ? Sure... just postprocess the files to add a header. Attached is a Perl script that adds such a header. Run it with Perl's -i flag (as shown below) if you use an operating system that for some reason does not allow you to run arbitrary scripts using the shebang (#!) mechanism. Otherwise, just mark it as executable and remove the perl -i from the examples below. Of course, I don't know what your Makefile looks like, but here's some examples of how you can use the script in your Makefile. You can run it after you generate each of the output files: %.o: %.c avr-gcc -g -Wa,-ahlds=$*.lst -o $@ -c $ perl -i timeStampHeader $*.lst Or you can run it after you generate all the output files: all: $(PRG).elf perl -i timeStampHeader $*.lst $*.lss Or you can use it as part of a pipeline: %.lss: %.elf avr-objdump -S $ | perl -i timeStampHeader $@ Enjoy, -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] timestampHeader Description: Binary data ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] More on C macros vs. C++ templates
On Apr 28, 2006, at 7:06 AM, Dave Hylands wrote (in response to a message from dimax un): WOW. I will definitely study your message. It will take time to all of us. But my scepticism was not about templates but about writing embedded code in C++ instead of C/Assembler/InlineAssembler. Interesting what would you get if you would write one more example in plain good C. I pasted some circular buffer code that I did. In C C++, I used macros in C, and in C++ I used a template. I did a bunch of analysis, and the C++ is very close in size to the C one. The biggest size differences are all related to how unit8_t's get promoted to ints. The C++ version is also missing a bit of functionality but it would be easy to add. I think at the time I didn't fully appreciate what was affecting the size and could probably get the C++ one to be as small as the C one now that I understand whats going on. OK, here's a modified version of yours that generates the same size object file using GCC 4.1.0 (actually, the C++ version is 2 bytes larger because of a bad register allocation choice, but who's counting?). If you uncomment the commented-out constructor in the C++ version, it becomes 36 bytes larger (108 vs. 72 bytes) because of the global constructor/destructor mechanism. In this case, of course, the constructor is not necessary for a static CBUF object, as the indices need to start at 0 anyway. Here's how it looks when you uncomment the constructor and run avr-nm -C --size-sort --print-size testc*.elf testc.elf: 00800060 0042 B myQ 008e 0046 T main testcpp.elf: 00ba 000e t global constructors keyed to myQ 00a6 0014 t __static_initialization_and_destruction_0(int, int) 00800060 0042 B myQ 00c8 0048 T main So you see that main() is only 2 bytes larger in the C++ version. I also made the C interface parameterizable for IndexType and EntryType, added the missing functions to the C++ version (though I'm not sure that they should be public at all), and added some comments. -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] templateDemo.tar.gz Description: GNU Zip compressed data ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Re: Device fuses
On Apr 27, 2006, at 11:31 PM, dimax un wrote: WOW. I will definitely study your message. It will take time to all of us. But my scepticism was not about templates but about writing embedded code in C++ instead of C/Assembler/InlineAssembler. Interesting what would you get if you would write one more example in plain good C. Remember too that you can combine inline assembly language macros with C++ templates if you want. I'm not sure about access to template parameters, etc. but it should work AFAIK. -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Re: Device fuses
; case 'd': case 'D': DDRD = ~m_bit; m_preg = PIND; preg = PORTD; break; } if (fPullup) *preg |= m_bit; // enable pull-up resistor else *preg = ~m_bit;// disable pull-up resistor } /* returns true if pin is reading high, else false */ bool IN::IsHigh() const { return *m_preg m_bit; } /* checks for button press; if not pressed, returns false; else waits for release (including debouncing both press release) */ bool IN::WasPressed() const { extern TIMER timer; if (IsOpen()) return false; timer.WaitMs(msDebounce); while (IsClosed()) ; timer.WaitMs(msDebounce); return true; } So this code takes three extra bytes of RAM (in addition to the three hardware registers DDRx, PORTx, and PINx) per input port. And every access requires looking at all of those bytes (dereferencing a pointer, masking with a value from RAM). But why? There's no way to change m_preg or m_bit once you've constructed this object, so there's no real point in keeping those things in RAM. Especially when you look at how these are used: all of the IN objects are globals, and there's no passing of pointers to these things during runtime (after construction; some global constructors get passed IN or OUT object pointers). And there are no virtual functions here (though of course templates work well with virtual functions) so we don't need vtables. And I'm pretty sure that, even with duplicated code snippets from template expansion, the total ROM consumption would be less, as well. Likewise, it's trivial to do compile-time asserts using templates for template parameters (like 0 = pin = 7 above). No reason for a run- time check when those parameters are compile-time constants! The attached .cpp file shows the two styles; the OLD_STYLE is the above (trimmed down to just the I/O part) and the templates are a quick demo of the same. You can compile it both ways (depending on the definition of the OLD_STYLE macro) and compare the resultant code. Note that: * the OLD_STYLE includes functions that aren't called, because they were in the source file. This forces library writers to break up their source files to one function per file, more or less. * using templates, only the functions that are called are instantiated. * the template code is much smaller: textdata bss dec hex filename 1188 0 121200 4b0 test-old.elf (1985-style C++) 320 0 4 324 144 test-new.elf (with templates) * The compiler seems to reserve 1 byte of RAM for each object anyway if you have a constructor for the class, even if you don't use it for anything (see the 4 bytes in the .bss section for test-new above). However, without constructors, the templates for I/O registers don't take any RAM at all. Try it for yourself! -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] [1] As I see it, Embedded C++ was a fear-motivated standard. Two major fears are apparent to me: - the fear (shared by the managers of development organizations in big companies) of what the average- and below-average programmers might do (and of the training budget required to keep them from doing it) - the fear by some of the compiler vendors that they might actually have to spend money updating their compilers before they were ready to do so test.cpp Description: Binary data ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] -fwhole-program ate my ISR!
[also posted to avr-libc-dev list] On Apr 21, 2006, at 10:23 AM, Bernd Trog wrote: For the more recent versions of gcc you might try the -fwhole- program and -funit-at-once options. I have read reports that this is good for some percent of code size, but I have no experience with it. I think thats avr-gcc -combine -fwhole-program *.c -Os ... Does this work for you? Interesting. I just built avr-libc 1.4.4 (thanks Joerg!) and tried a little test program. Unfortunately, the optimization is a bit too aggressive: it removed my ISR completely! I found that adding __attribute__ ((used)) before the ISR() definition kept this from happening. I think we need to add the used attribute to the definitions of ISR () etc. to allow for -fwhole-program... Try compiling this program with and without ADD_USED defined, like this, and you'll see the difference. === // avr-gcc -g -mmcu=attiny45 -fwhole-program -Os -o xx1a.elf xx1.c // avr-objdump -S xx1a.elf xx1a.lst // avr-gcc -g -mmcu=attiny45 -DADD_USED -fwhole-program -Os -o xx1b.elf xx1.c // avr-objdump -S xx1b.elf xx1b.lst // #include avr/io.h #include avr/iotnx5.h #include avr/interrupt.h volatile unsigned char uc; #ifdef ADD_USED __attribute__ ((used)) #endif ISR(INT0_vect) { uc++; } int main(void) { for (;;) ; } === -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Using PORTB with variables, PORTB = var
On Apr 22, 2006, at 2:29 AM, [EMAIL PROTECTED] wrote: On Sat, 22 Apr 2006 08:30:33 +0200 Lars Noschinski [EMAIL PROTECTED] wrote: * [EMAIL PROTECTED] [EMAIL PROTECTED] [2006-04-22 08:09]: How can I use the PORTB constant with variables? eg: while (1) { var = 1; PORTB = var } This will work. But after seven iterations (if var is (u)int8_t), var will be 0. That is what I'm trying to acheive. I'd like to be able to do it with variables like I do above, but it doesn't seem to work. Once I replace var with an actual number, it works as expected. The problem lies probably elsewhere. OK. This is some brief code... This works as expected. int main() { DDRB = 255; while (1) { int var=1; while (var != 0) { PORTB = var; var = 1; } } return 0; } This example doesn't, and I don't know why... I know it's specific to C, so that's why I'm asking here... int var 1; // the problem is that int is both signed and 16-bits wide; you want // an unsigned 8-bit value. And I assume you meant to have an = sign in there. // Better to use: unsigned short var = 1; void blink() { PORTB ^= var; // LED on // assuming you have an LED per pin and the low 8 bits of var are not zero, that'd work. sleep(50); PORTB = 255; // LEDs off sleep(50); } void change() { var = 1; // the way you have it written, this would toggle each of the pins of PORTB once. // is that what you're getting? // The problem is that when var gets to 128, it next becomes 256, which is all // 0s in the low 8 bits, so it won't affect your LEDs. The sequence would be: // 1, 2, 4, 8, 16, 32, 64, 128,as intended // 256, 512, 1024, 2048, 4096, 8192, 16384, -32768,// which won't work // 0, 0, 0, ... // which clearly won't work // better to do this (assuming var is 8 bits): var = 1; if (var == 0) var = 1; } int main() { DDRB = 255; PORTB=255; while (1) { blink(); change(); } return 0; } This doesn't work as expected... not sure why. It's always better to say *what it does do*, and *what you expected*, rather than doesn't work as expected if you want people to help you. I would like to keep the functions if possible, I'm thinking it has something to do with scope perhaps? It's hard to tell why you would like to keep the functions. You're probably in a better position to say why g. -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] Re: Device fuses
On Apr 21, 2006, at 11:18 PM, Björn Haase wrote: Anton Erasmus [EMAIL PROTECTED] wrote: Wouldn't it be worthwhile to add a method of specifying device fuses in the C or assembler source file ? I think something similar to the way the EEPROM and PROGRAM memory is handled. something like: That would not be difficult at all. One could agree on the name of some section that contains data for the fuses and the lock-bits. One would do something like: #define SET_FUSE_BITS(F1,F2,F3,L) unsigned char fuses[4] __attribute___ ((section (.fuses))) = {F1,F2,F3,L}; The more time-consuming thing would be to teach your favorite programming tool to actually use the data in the .elf file. Not at all... #!/bin/bash myprogram=$1; shift avr-objcopy -j .fuses -O binary ${myprogram} fuses.bin avrdude -p atmega128 -U lfuse:w:m:$(od -A n -t x1 -j 0 -N 1 fuses.bin | tr -d ' ') avrdude -p atmega128 -U hfuse:w:m:$(od -A n -t x1 -j 1 -N 1 fuses.bin | tr -d ' ') avrdude -p atmega128 -U efuse:w:m:$(od -A n -t x1 -j 2 -N 1 fuses.bin | tr -d ' ') avrdude -p atmega128 -U lock:w:m:$(od -A n -t x1 -j 3 -N 1 fuses.bin | tr -d ' ') -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Using PORTB with variables, PORTB = var
On Apr 22, 2006, at 9:20 AM, Matthew MacClary wrote: Here is how I would implement your program. I apologize in advance since I don't have a board available to try the code on. I hope that the main ideas are apparent, even if I didn't squash all the bugs. Here's a version of Matthew's code that will compile correctly (had to change the names of sleep() etc.); using avr-gcc 4.1.0 it compiles to 142 bytes with the compilation options given below. /* avr-gcc -g -mmcu=atmega8 -fwhole-program -Os -o xx2c.elf xx2.c avr-objdump -S xx2c.elf xx2c.lst */ /* default 1MHz internal oscillator */ #define F_CPU 100 #include avr/io.h #include util/delay.h inline void blink(volatile uint8_t * const port, uint8_t mask) { *port = ~mask; // LEDs on _delay_ms(500); // milliseconds *port = 255;// LEDs off _delay_ms(500); // milliseconds } inline void change(uint8_t * const var) { *var = 1; if (! *var) *var = 1; } int main() { uint8_t led_mask = 1; DDRB = 255; // PORTB as outputs PORTB = 255;// LEDs off while (1) { blink(PORTB, led_mask); change(led_mask); } return 0; } -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] avr-gcc 3.4.3 confused about function pointers
On Apr 16, 2006, at 2:55 PM, John Regehr wrote: Compiling like this: avr-gcc -Wall -mmcu=atmega128 -Os foo.c gives a program that icalls to a bad address. On the other hand, compiling the same program with -O instead of -Os results in correct code. The problem occurs when the Z register is loaded with the address of foo(). In the buggy (-Os) version, the literal address of foo() is loaded, rather than the address shifted right by one bit position. With -O the compiler gets it right. I'd appreciate hearing about it if there's a patch for this or if the bug is known to be fixed in later versions. Under avr-gcc 4.1.0 both foo and stuff get optimized out (well, they both end up empty): 32.global foo 34foo: 41 0895 ret 43/* function foo size 1 (0) */ 45.Lscope0: 49.global stuff 51stuff: 58 0002 0895 ret 60/* function stuff size 1 (0) */ 62.Lscope1: 66.global main 68main: 73 0004 C0E0 ldi r28,lo8(__stack - 0) 74 0006 D0E0 ldi r29,hi8(__stack - 0) 75 0008 DEBF out __SP_H__,r29 76 000a CDBF out __SP_L__,r28 80 000c 0E94 call stuff 83 0010 80E0 ldi r24,lo8(0) 84 0012 90E0 ldi r25,hi8(0) 86 0014 0C94 jmp exit 88/* function main size 10 (4) */ If you force foo to be called (for instance, passing a pointer to back [0], after declaring back as volatile) then the compiler is clever enough just to call foo(), rather than using a pointer. You'll have to come up with a test program that's cleverer than that. I did notice that for the expression (foo + 1) it used a byte increment, rather than a word increment (which seems wrong to me). void foo(volatile struct bar *b) { ca: fc 01 movwr30, r24 b-yyy = (void*)0; cc: 11 82 std Z+1, r1 ; 0x01 ce: 10 82 st Z, r1 d0: 08 95 ret 00d2 stuff: } void stuff(void) { d2: cf 93 pushr28 d4: df 93 pushr29 d6: cd b7 in r28, 0x3d ; 61 d8: de b7 in r29, 0x3e ; 62 da: 28 97 sbiwr28, 0x08 ; 8 dc: 0f b6 in r0, 0x3f; 63 de: f8 94 cli e0: de bf out 0x3e, r29 ; 62 e2: 0f be out 0x3f, r0; 63 e4: cd bf out 0x3d, r28 ; 61 volatile struct bar back[2]; void (*p) (volatile struct bar *) = foo; back[0].aaa = (void *) (foo + 1); e6: 8b ec ldi r24, 0xCB ; 203 questionable! e8: 90 e0 ldi r25, 0x00 ; 0 ea: 9c 83 std Y+4, r25; 0x04 ec: 8b 83 std Y+3, r24; 0x03 int i; for (i = 0; i 6; i++) { back[0].aaa = back[0].yyy; ee: 89 81 ldd r24, Y+1; 0x01 f0: 9a 81 ldd r25, Y+2; 0x02 f2: 9c 83 std Y+4, r25; 0x04 f4: 8b 83 std Y+3, r24; 0x03 .. etc .. } (*p) (back[0]); 11e:ce 01 movwr24, r28 120:01 96 adiwr24, 0x01 ; 1 122:0e 94 65 00 call0xca foo 126:28 96 adiwr28, 0x08 ; 8 128:0f b6 in r0, 0x3f; 63 12a:f8 94 cli 12c:de bf out 0x3e, r29 ; 62 12e:0f be out 0x3f, r0; 63 130:cd bf out 0x3d, r28 ; 61 132:df 91 pop r29 134:cf 91 pop r28 136:08 95 ret -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] big string into the ROM
On Apr 10, 2006, at 10:57 PM, drvdrv wrote: avr-gcc linker.txt -mmcu=atmega128 text.o s6b1713.o menu.o pgmmem. o main.o-o abc.elf E:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin \ld.exe:linker.txt:17: warning: redeclaration of memory region 'text' E:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin \ld.exe:linker.txt:18: warning: redeclaration of memory region 'data' E:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin \ld.exe:linker.txt:19: warning: redeclaration of memory region 'eeprom' E:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin\ld.exe: region text is full (abc.elf section .text) make: *** [abc.elf] Error 1 I don't understand because the text.o is not so big to fill the whole ROM. If you're passing in a full linker script, you have to use the -T flag so that the standard one isn't used. So it'd be something like: avr-gcc -Wl,-T,linker.txt text.o s6b1713.o menu.o pgmmem.o main.o - mmcu=atmega128 -o abc.elf -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Variable __data_end variable not passed through to linker for use in __heap_start?
On Apr 9, 2006, at 8:41 PM, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Hi all: I am running winavr 2006*, on an atmega128 with 32k of XRAM mapped to 0x8000-0x. I would like the .bss memory section to be allocated by the linker in the internal RAM, while I'd like the .data section and the __malloc_heap_start to both be in XRAM. .bss being in IRAM is not really negotiable, and I'd much prefer .data to live in XRAM, due to the larger size of that section. Unfortunately, the makefile I'm using doesn't seem to want to allocate the __malloc_heap_start variable to the __data_end. I've tried adding the following options, with no success: LDFLAGS += -Wl,--section-start,.bss=0x800100 \ -Wl,--section-start,.data=0x808000) \ -Wl,--defsym,__heap_start=__data_end \ -Wl,--defsym,__heap_end=0x80 \ The problem I have is that any memory I allocate with malloc ends up in the internal RAM, straight after .bss. However, if I hard-code the __heap_start variable (to, say, 0x809000), I have no problems - the malloc'ed memory is allocated in XRAM. This is a less than ideal situation, obviously, however I don't seem to be able to pass through the __data_end variable into the __heap_start (and onwards to __malloc_heap_start). Anyone run into this before, and/or any suggestions?? Sure: why not just define a custom linker script? It's quicker than all that command-line stuff anyway. Anyhow, seems like someone was complaining that the command-line args didn't work anyhow. Try the attached. It results in: .data 0x008080000x6 0x00808000PROVIDE (__data_start, .) 0x00808002__malloc_heap_start 0x00808000__malloc_heap_end 0x00808004__malloc_margin 0x00808006_edata = . 0x00808006PROVIDE (__data_end, .) 0x00808006PROVIDE (__heap_start, .) .bss0x008000600x4 0x00800060PROVIDE (__bss_start, .) 0x0080__heap_end = 0x80 -- Ned Konz [EMAIL PROTECTED] xx.x Description: Binary data xx.c Description: Binary data ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] specific SRAM locations.
On Apr 8, 2006, at 1:56 PM, Dave Lamont wrote: I need to allocate specific SRAM locations to some global variables. The quantities in these reserved SRAM locations are passed from the microprocessor back to a computer. My previous compiler allowed me to specify as follows int sat_bearing @0x180; or struct x {int a; char c; } alfa @0x185; That's not Standard C, but there are at least three ways that I can think of that you can do this: * Do what the avr-libc folks do, and make the name a #define for an anonymous object (what in C++ would be referred to as a reference): #define sat_bearing (*(int *)(void*)(0x180)) #define alfa (*(struct x*)(void*)(0x185)) then you can say things like: sat_bearing = 30; alfa.c = 'f'; * Use a custom linker script that specifies these locations explicitly, and use an extern statement in C: (linker) alfa = 0x800185; sat_bearing = 0x800180; (c) extern int sat_bearing; extern struct x alfa; * use a custom linker script that names the interesting sections and use the GDB attribute((__section__)) on the variables. I forget the exact syntax for this, but you basically just have fixed-address sections (defined inside the SECTION directive in your linker definition file) that you then use to refer to from C: int sat_bearing __attribute__((__section__=myAttribute)); -- Ned Konz MetaMagix embedded consulting [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Program Listing With C Comments
On Mar 31, 2006, at 2:05 PM, Albert Pion wrote: How do I get a program listing with my C source code included as comments? I've tried about everything I can think of (including the --Wa,-alhd option) but have been unable to get it to work. Attached is a Ruby (http://www.ruby-lang.org) script to post-process the output of avr-objdump into a legal assembly language program with C program text as asm comments. Its output looks like this: .text .global __bad_interrupt .func __bad_interrupt __bad_interrupt : .weak __vector_default .set__vector_default, __vectors XJMP__vector_default jmp 0x0 __heap_end SerialCommandProcessor_setCurrentObject: ; (0x00ca) ;; /* SerialCommandProcessor functions --- */ ;; ;; void ;; SerialCommandProcessor_setCurrentObject (SerialCommandProcessor me, IOObject obj) ;; { movwr30, r24 ;; me-currentObject = (obj == NULL) ? me-topObject : obj; cp r22, r1 cpc r23, r1 brne.+4 ; SerialCommandProcessor_setCurrentObject+0xc (0xd6) ldd r22, Z+2; (0x02) ldd r23, Z+3; (0x03) std Z+1, r23; (0x01) st Z, r22 ret Run it like so: avr-objdump -S myProg.elf | ruby simplifyListing.rb myProg.asm -- Ned Konz [EMAIL PROTECTED]#!/usr/bin/ruby # takes output of avr-objdump and turns it into real assembly code. # Ned Konz [EMAIL PROTECTED] # Sat Apr 1 08:55:32 PST 2006 # :beginning, :ccode, :asmcomment, :code $state = :beginning def outputLine(line) case line when /^;;\s/ if $state == :beginning line.sub!(/^;*\s*(.+)/, ;;\t/* \\1 */) else $state = :ccode end when /^;/ $state = :asmcomment when /^\s*$/ if $state == :ccode || $state == :beginning line = ;; end else $state = :code end line.sub!(/\t;\s*([^;]*)\s*;\s*(.*)/, \t; \\1 (\\2)) if $state != :beginning line.sub!(/;\s*([a-f0-9]{8})\s*$/, ; (0x\\1)) line.sub!(/;\s*(0x[a-f0-9]{2,8})\s*$/, ; (\\1)) puts line end ARGF.each do | f | f.each_line do | line | line.sub!(/(0x[a-z0-9]{2,4})\s+([^]+)/, \\2 ; \\1) line.sub!(/\tcall\t0x /, \tcall ) line.sub!(/\tjmp\t0x /, \tjmp ) line.sub!(/; 0x[0-9a-f]+ /, ; ) line.sub!(/^([^]+):/, \\1 :) case line # asm directive when /^\s+(\.\w+|vector|XJMP)(\s+.*)?/ outputLine line # asm label when /^\s*(\w+)\s*:$/ outputLine #{$1} : # line number (-l option to avr-objdump) when /^(\/.*):([0-9]+)$/ puts #line #{$2} \#{$1}\ $state = :code # label when /^([0-9a-fA-F]{8}) ([^]+)/ outputLine #{$2}: ; #{$1} # instruction when /^\s+[0-9a-fA-F]{1,4}:\t([0-9a-fA-F]{2}\s){2,} *\t/ outputLine line[22 ... -1] # instruction, no opcodes when /^\s+[0-9a-fA-F]{1,4}:\t*\t/ outputLine line[5 ... -1] # table when /^\s+[0-9a-fA-F]{1,4}:\t([0-9a-fA-F]{2}\s)[^\t]+$/ outputLine line[10 ... -1] # blank line when /^\s*$/ outputLine # C code else outputLine ;;\t + line end end end ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] New FreeBSD avr-gcc-devel 4.1.0 port fails to build
On Mar 27, 2006, at 1:17 PM, Joerg Wunsch wrote: (2) How does it compare with avr-gcc-3.4.6 code size, i.e., using -Os optimization? In a large project I'm doing in my day job, it's been the first time a more recent compiler version finally reduced the code size again (after all the 3.x versions gradually increased the average code size). The saving wasn't overwhelming though, about 5 %, but given that IAR used to be about 10 % better on average, we've at least regained half of that. ;-) I just did a Portfile for Darwinports based on your freebsd port; comparing with my 4.0.2 version, the 4.1.0 version is a tiny bit larger (24 bytes out of 20K or so) in a couple of cases. Don't know why. This may be considerably smaller than the 3.4.x range, though. -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] alignment of vtable is greater than maximum object file alignment?
I routinely get warnings like this when I compile classes with virtual functions (using avr-gcc 4.1.0): avr-gcc -c -mmcu=atmega128 -I. -Wp,-M,-MP,-MT,qhsm_ini.o,-MF,.dep/ qhsm_ini.o.d -fno-exceptions -ggdb - DQ_SPY -I../../../../include - I../../../../ports/avr/qk/g++ -I../../../source -I. -Os -funsigned- char - funsigned-bitfields -fpack-struct -fshort-enums -Wall - Wa,-adhlns=./spy/qhsm_ini.lst ../../../source/ qhsm_ini.cpp -o spy/qhsm_ini.o /Users/ned/src/quantumFrameworkCPP/qep/avr/qk/g++/../../../../include/ qep.h|258| warning: alignment of 'QHsm::vtable for QHsm' is greater than maximum object file alignment. Using 1 Is this a problem? Is there some way to shut these up (other than post-processing the gcc output)? Thanks, -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] PROGMEM and C++?
I'm trying to put instances of a class into ROM, and am having problems with the compiler blowing up. Should the following be OK? /* avr-g++ -mmcu=atmega128 -fno-exceptions -c -o romproblems.o romproblems.cpp romproblems.cpp:21: internal compiler error: in set_mem_attributes_minus_bitpos, at emit-rtl.c:1539 Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions. avr-g++ (GCC) 4.0.2 Problem happens with any setting of -O flag and with or without -fno-exceptions flag */ #define PROGMEM __attribute__((__progmem__)) struct ROMVar1 { int const val; ROMVar1(int const init) : val(init) { } }; ROMVar1 PROGMEM rv1b(123); -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
[avr-gcc-list] __attr_const__ attribute and strlen_P() and friends
I'm sure this is a stupid question, but I was wondering... I noticed that in the avr-libc header pgmspace.h that there are declarations including: extern size_t strlen_P(PGM_P) __ATTR_CONST__; /* program memory can't change */ extern size_t strnlen_P(PGM_P, size_t) __ATTR_CONST__; /* program memory can't change */ where __ATTR_CONST__ is defined as __attribute__((__const__)) Now, it says in the GCC 4.0 manual about function attributes in the section about const that: -- const Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the pure attribute below, since function is not allowed to read global memory. Note that a function that has pointer arguments and examines the data pointed to must not be declared const. Likewise, a function that calls a non-const function usually must not be const. It does not make sense for a const function to return void. -- Of course, strlen_P() *does* have pointer arguments, and *does* examine the data pointed to (though only in a read-only way). Is it a problem that it is declared const, considering the above? And if I was using the self-programming flash capabilities of the AVR would this be a problem? -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] How to determine which interrupt fired?
On Feb 11, 2006, at 7:44 PM, Rick Mann wrote: I have a simple app that only defines the UART0 receive interrupt handler for an ATmega128. I can set that it's getting called in gdb (and because its code is executing), but then something happens and my code jumps to the top of main. I'm assuming some other interrupt/ reset is occurring, but I can't figure out what it is. Any suggestions on how I can determine this? Thanks! Most interrupts have associated flag bits. As far as restart reasons, look at the section in the datasheet on the MCU Control and Status Register - MCUSR (under System Control and Reset). There are flags for each of the reset sources. They note: To make use of the reset flags to identify a reset condition, the user should read and then reset the MCUCSR as early as possible in the program. If the register is cleared before another reset occurs, the source of the reset can be found by examining the reset flags. You might also want to: * verify that the reset pin is tied directly to Vcc (at least for testing) * verify that you have good bypassing close to the processor * set the startup time to maximum * try disabling the brown-out reset (via the BODEN fuse) * ensure that the watchdog timer is disabled (via the WDTON fuse) * try running your JTAGICE at its slowest rate (just in case you happen to have a slow clock) -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Bad code generated when using volatile keyword/-O0 opt?
On Feb 11, 2006, at 10:43 PM, Rick Mann wrote: Generating code for an ATmega128. I've boiled this down to a pretty simple case, I think. In the following code, if compiled with -Os, if d is made volatile, then it never seems to get past execution in the first delay loop. If it's not volatile, it works correctly. If I compile with -O0, neither volatile nor non-volatile works (same failure mode). I started experimenting with -O0 (and the volatile keyword) to try to make sure gdb was in sync between source and assembly. With the volatile keyword, the .lst files shows this for the first loop: --- 17:main.c d = kD; 100 .stabn 68,0,17,.LM4-main 101 .LM4: 102 0016 2983 std Y+1,r18 103 .L3: 18:main.c while (d--); 104 .stabn 68,0,18,.LM5-main 105 .LM5: 106 0018 8981 ldd r24,Y+1 107 001a 8150 subi r24,lo8(-(-1)) 108 001c 8983 std Y+1,r24 109 001e 8981 ldd r24,Y+1 110 0020 8F3F cpi r24,lo8(-1) 111 0022 D1F7 brne .L3 19:main.c --- And without volatile: --- 99 0014 8FEF ldi r24,lo8(-1) 100 .L3: 17:main.c d = kD; 18:main.c while (d--); 101 .stabn 68,0,18,.LM4-main 102 .LM4: 103 0016 8150 subi r24,1 104 0018 F0F7 brcc .L3 --- Not sure if this is a bug, but it sure seems like it to me. Let me know what other info you might need. Why does it seem like a bug? Is this your entire program, or might there be an interrupt handler that's trashing one or another registers or memory locations? -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] object file break up
On Feb 11, 2006, at 2:47 PM, Ning Xu wrote: I am thinking of breaking a big avr object file into a set of smaller object files. Is it possible in theroy? does anyone know any tool out there that does this? If it's big because there's lots of functions in it, just edit the source so you have lots of little source files instead of one big one. Then use the librarian (avr-ar) to maintain a library with the object files compiled from the new smaller source files. If your big object file is big because it's one huge function, the tool to use is called an editor. Refactor the one huge function so that it's several smaller ones, and apply the above strategy. -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Timer0 problem on AVR butterfly
On Feb 10, 2006, at 3:28 PM, Dave wrote: Hello All, I'm having trouble with timer0 on my AVR butterfly. I'm trying to start the timer right before a routine and read it once the routine is done. I'm hoping to print the counted ticks on the LCD, but haven't had luck at all. The following is my code: TCCR0A = 1; // system clock frequency will be used TCNT0 = 0; // initial value for timer myRoutine(); t = TCNT0; LCD_putc(0, t); // write t on digit 0 Is there something wrong with my code? Are there any examples you can direct me to? Thank you. Well, what's t declared as? I assume that it's compatible with TCNT0 (which is an 8-bit register). In fact, it's hard to tell what exactly the problem is with just that snippet. Also you don't say how you've been unlucky. What happened? What did you observe? What steps did you take to test your ideas as to what might be wrong? Of course, a LCD_putc() will just put a character whose code is the same as the reading of TCNT0 on the display. And that assumes that there is a character that corresponds to that code. If you want to see a number, you'll have to do some more work. And remember that this will only measure time delays up to 255 * the clock period. I forget what the Butterfly clock is running at, but You might want to use Timer1 (though the stock Butterfly code uses it), as it's 16-bits. I assume you've googled for avr butterfly gcc to find resources. One I've found helpful is http://www.siwawi.arubi.uni-kl.de/ avr_projects/#bf_app -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] avr-gcc (GCC) 3.4.5 Bug: copying structure through pointer will destroy the pointer
On Feb 5, 2006, at 11:54 PM, [EMAIL PROTECTED] wrote: there is a bug in avr-gcc (GCC) 3.4.5, that comes with the latest WinAVR distribution (20060125). The avr-gcc (GCC) 3.4.3, that comes with WinAVR 20050214 does NOT contain this bug. The bug exists with and without optimization (I tried -O0 and -Os) If you try to copy a structure with *struct_pointer = struct; the struct_pointer gets destroyed. The assembler code generated seems to add one structure length foreach copied byte to the pointer. Looks OK with avr-gcc 4.0.2 avr-gcc (GCC) 4.0.2 -O0 49:main.c *rx_tel_in_ptr++ = RXtemp; 126.LM8: 127 0052 8091 lds r24,rx_tel_in_ptr 128 0056 9091 lds r25,(rx_tel_in_ptr)+1 129 005a 9D83 std Y+5,r25 130 005c 8C83 std Y+4,r24 131 005e EC81 ldd r30,Y+4 132 0060 FD81 ldd r31,Y+5 133 0062 FF83 std Y+7,r31 134 0064 EE83 std Y+6,r30 135 0066 80E0 ldi r24,lo8(RXtemp) 136 0068 90E0 ldi r25,hi8(RXtemp) 137 006a 9987 std Y+9,r25 138 006c 8887 std Y+8,r24 139 006e 98E4 ldi r25,lo8(72) 140 0070 9A87 std Y+10,r25 141.L7: 142 0072 E885 ldd r30,Y+8 143 0074 F985 ldd r31,Y+9 144 0076 0080 ld r0,Z 145 0078 8885 ldd r24,Y+8 146 007a 9985 ldd r25,Y+9 147 007c 0196 adiw r24,1 148 007e 9987 std Y+9,r25 149 0080 8887 std Y+8,r24 150 0082 EE81 ldd r30,Y+6 151 0084 FF81 ldd r31,Y+7 152 0086 0082 st Z,r0 153 0088 8E81 ldd r24,Y+6 154 008a 9F81 ldd r25,Y+7 155 008c 0196 adiw r24,1 156 008e 9F83 std Y+7,r25 157 0090 8E83 std Y+6,r24 158 0092 9A85 ldd r25,Y+10 159 0094 9150 subi r25,lo8(-(-1)) 160 0096 9A87 std Y+10,r25 161 0098 EA85 ldd r30,Y+10 162 009a EE23 tst r30 163 009c 51F7 brne .L7 164 009e 8C81 ldd r24,Y+4 165 00a0 9D81 ldd r25,Y+5 166 00a2 885B subi r24,lo8(-(72)) 167 00a4 9F4F sbci r25,hi8(-(72)) 168 00a6 9093 sts (rx_tel_in_ptr)+1,r25 169 00aa 8093 sts rx_tel_in_ptr,r24 -Os 49:main.c *rx_tel_in_ptr++ = RXtemp; 110.LM7: 111 0038 8091 lds r24,rx_tel_in_ptr 112 003c 9091 lds r25,(rx_tel_in_ptr)+1 113 0040 FC01 movw r30,r24; z reg 114 0042 A0E0 ldi r26,lo8(RXtemp) ; x reg 115 0044 B0E0 ldi r27,hi8(RXtemp) 116 0046 28E4 ldi r18,lo8(72) 117.L6: 118 0048 0D90 ld r0,X+ 119 004a 0192 st Z+,r0 120 004c 2150 subi r18,lo8(-(-1)) 121 004e E1F7 brne .L6 122 0050 885B subi r24,lo8(-(72)) 123 0052 9F4F sbci r25,hi8(-(72)) 124 0054 9093 sts (rx_tel_in_ptr)+1,r25 125 0058 8093 sts rx_tel_in_ptr,r24 -O2 49:main.c *rx_tel_in_ptr++ = RXtemp; 110.LM7: 111 003c F901 movw r30,r18 112 003e A0E0 ldi r26,lo8(RXtemp) 113 0040 B0E0 ldi r27,hi8(RXtemp) 114 0042 88E4 ldi r24,lo8(72) 115.L6: 116 0044 0D90 ld r0,X+ 117 0046 0192 st Z+,r0 118 0048 8150 subi r24,lo8(-(-1)) 119 004a E1F7 brne .L6 120 004c 285B subi r18,lo8(-(72)) 121 004e 3F4F sbci r19,hi8(-(72)) 122 0050 3093 sts (rx_tel_in_ptr)+1,r19 123 0054 2093 sts rx_tel_in_ptr,r18 -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Memory Size Report
On Feb 5, 2006, at 12:44 PM, Peter Harrison wrote: I am using the current WinAVR 20060125 A program compiled with this shows a memory usage report in the compiler output stream. It looks like this: AVR Memory Usage Device: atmega32 Program: 24392 bytes (74.4% Full) (.text + .data + .bootloader) Data: 2733 bytes (133.4% Full) (.data + .bss + .noinit) My first question is why the .data segment shows as being counted twice. Does this represent the code space needed to store the initial values as well as the RAM space they will take up? Yes. But only for explicitly initialized globals/statics. When I look at the map file I see these lines for the .data section: .data 0x00800060 0x4ec load address 0x5a5c 0x00800060PROVIDE (__data_start, .) *(.data) .data 0x00800060 0x141 gnumaximus.o 0x00800060menusize .data 0x008001a10xb maze.o .data 0x008001ac0x2 motors.o 0x008001acwallTrackRight 0x008001adwallTrackLeft .data 0x008001ae 0x39e setup.o *(.gnu.linkonce.d*) 0x0080054c. = ALIGN (0x2) 0x0080054c_edata = . 0x0080054cPROVIDE (__data_end, .) If I take out some lines with static strings (like sprintf(blah) lines), both the amount of RAM used and the size of the .data section decrease. These strings only need exist in flash memory so what can I do? Why do they seem to be counted twice and where are they really stored? Look at the avr-libc manual; there are provisions for both defining static constants in flash, as well as versions of the stdlib and stdio functions that deal with strings that will work with strings in flash. Look at the documentation for avr/pgmspace.h For instance, #include avr/io.h #include avr/pgmspace.h const char s1[] = abc; /* will take up both RAM and flash */ const char PROGMEM s2[] = def /* will take only flash, but you have to use different functions to access it */ then: char myBuffer[30]; /* in RAM */ sprintf(myBuffer, s1); /* but */ sprintf_P(myBuffer, s2); -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] AT90CAN128 support
On Feb 2, 2006, at 1:37 PM, Rob Prowel wrote: OK. So I'm sure someone has already brought this up but I'm new to the list so I have to ask. Is anyone working on adding support for the AT90CANxxx chips to avr-gcc, specifically under the UNIX/Linux platform? It seems to support the at90can128 (which I think is the only one of the family currently available). Here's what happens on my Mac when I ask my gcc what it supports: neds_mini:~ $ avr-gcc --target-help Target specific options: -msizeOutput instruction sizes to the asm file -mshort-calls Use rjmp/rcall (limited range) on 8K devices -mno-tablejumpDo not generate tablejump insns -mtiny-stack Change only the low 8 bits of the stack pointer -mcall-prologues Use subroutines for function prologue/ epilogue -mno-interrupts Change the stack pointer without disabling interrupts -mint8Assume int to be 8 bit integer -mmcu=Specify the MCU name -minit-stack= Specify the initial stack address There are undocumented target specific options as well. AVR options: -mmcu=[avr-name] select microcontroller variant [avr-name] can be: avr1 - AT90S1200, ATtiny1x, ATtiny28 avr2 - AT90S2xxx, AT90S4xxx, AT90S8xxx, ATtiny22 avr3 - ATmega103, ATmega603 avr4 - ATmega83, ATmega85 avr5 - ATmega161, ATmega163, ATmega32, AT94K or immediate microcontroller name. -mall-opcodesaccept all AVR opcodes, even if not supported by MCU -mno-skip-bugdisable warnings for skipping two-word instructions (default for avr4, avr5) -mno-wrapreject rjmp/rcall instructions with 8K wrap-around (default for avr3, avr5) Known MCU names: avr1 avr2 avr3 avr4 avr5 at90s1200 attiny10 attiny11 attiny12 attiny15 attiny28 at90s2313 at90s2323 at90s2333 at90s2343 attiny22 attiny26 at90s4433 at90s4414 at90s4434 at90s8515 at90s8535 at90c8534 at86rf401 attiny13 attiny2313 atmega603 atmega103 at43usb320 at43usb355 at76c711 atmega48 atmega8 atmega83 atmega85 atmega88 atmega8515 atmega8535 atmega16 atmega161 atmega162 atmega163 atmega165 atmega168 atmega169 atmega32 atmega323 atmega325 atmega3250 atmega64 atmega128 atmega645 atmega6450 at90can128 at94k no emulation specific options. And it looks like avr-libc also knows about them (well, at least the at90can128) too: neds_mini:~ ned$ find /sw/share/avr/ -iname *can* /sw/share/avr/avr/include/avr/iocan128.h /sw/share/avr/avr/include/avr/iocan32.h /sw/share/avr/avr/include/avr/iocan64.h /sw/share/avr/avr/include/avr/iocanxx.h ... /sw/share/avr/avr/lib/avr5/crtcan128.o neds_mini:~ ned$ fink info avr-libc Information about 5329 packages read in 9 seconds. avr-libc-1.4.0-1: AVR LIBC for GNU GCC GNU binutils This is AVR-LIBC. It is a C library implementation for use with GNU GCC and GNU binutils for development of programs for Atmel's AVR mirocontrollers . Maintainer: Matthias Ringwald [EMAIL PROTECTED] neds_mini:~ ned$ fink info avr-gcc Information about 5329 packages read in 2 seconds. avr-gcc-4.0.2-2: GNU GCC for ATMEL AVR micro controllers . Web site: http://gcc.gnu.org/ . Maintainer: Matthias Ringwald [EMAIL PROTECTED] I compiled my own, of course. -- Ned Konz [EMAIL PROTECTED] ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Getting avr-gcc 4.02 to recognize new devices
On Dec 5, 2005, at 9:50 AM, Bernd Trog wrote: --- Ned Konz [EMAIL PROTECTED] wrote: What am I missing? Patching the binutils? Ah... wonder where I can find a corresponding patch. Suggestions? Whats the output of avr-as --target-help? Known MCU names: avr1 avr2 avr3 avr4 avr5 at90s1200 attiny10 attiny11 attiny12 attiny15 attiny28 at90s2313 at90s2323 at90s2333 at90s2343 attiny22 attiny26 at90s4433 at90s4414 at90s4434 at90s8515 at90s8535 at90c8534 at86rf401 attiny13 attiny2313 atmega603 atmega103 at43usb320 at43usb355 at76c711 atmega48 atmega8 atmega83 atmega85 atmega88 atmega8515 atmega8535 atmega16 atmega161 atmega162 atmega163 atmega165 atmega168 atmega169 atmega32 atmega323 atmega325 atmega3250 atmega64 atmega128 atmega645 atmega6450 at90can128 at94k Thanks, Ned ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] inline assembler, ijmp, X-Register
Ben Mann wrote: Have you tried it just using a 'vanilla' C function pointer? Although I don't use the 128 I had the impression that avrlib did this for you. But he wants to jump, not call... ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] possible compiler/optimizer problem (?)
Gary Douglas wrote: Not sure if this is a bug, or if what I'm trying to do is just incorrect C syntax. Regardless, the compiler doesn't warn about the following: [snip] value != value;//This is the problem line - always true [snip] If I change it to this it works: [snip] value = (!value); //This works... [snip] Are these not fundamentally the same? No. value != value; is just a Boolean expression (which should always be false, but since its value is not used, the compiler probably throws the test away); it's not an assignment. What probably is confusing is that C provides some composite operator/assignment operators: += -= *= /= = |= ^= %= = = but != is one of the test operators that happen to end in '=': != == = = -- Ned Konz ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list