avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Initilizing complex const arrays : syntax ?


From: Anton Erasmus
Subject: Re: [avr-gcc-list] Initilizing complex const arrays : syntax ?
Date: Sun, 18 Sep 2005 21:20:35 +0200

On 18 Sep 2005 at 19:55, Vincent Trouilliez wrote:

> Thanks guys for the help,
>
>
> I appear to have one last little problem about this :
>
> if I do as David did, that is declare my array in main.c, then it
> works fine. If I declare the array in ui.h ("ui" stands for User
> Interface in my case), and include ui.h in main.c, then it's good too.
> However if I do as intended, that is, create an ui.c file which will
> contain functions that make use of the array defined in ui.h,
> well.....in this case main.c and ui.c compile fine, but the linker
> will fail sadly :-/
>
> $make
> avr-gcc -O -g -Wall -ffreestanding -mmcu=atmega32 -c main.c
> avr-gcc -O -g -Wall -ffreestanding -mmcu=atmega32 -c ui.c
> avr-gcc -o object.elf -O -g -Wall -ffreestanding -mmcu=atmega32
> -Wl,-Map,object.elf.map -Wl,--section-start=.eeprom=00810001 main.o
> ui.o ui.o(.progmem.data+0x0): multiple definition of `param_list'
> main.o(.progmem.data+0x0): ~/avr/Projects/test2/main.c:3: first
> defined here make: *** [object.elf] Error 1
>
>
> I can't make sense of the error messages.
> I did notice that it does link fine, if I comment out the "include
> ui.h" in ui.c, but you just all taught me the other day to always
> include foo.h at the top of foo.c, when writing a module, which makes
> sense since modules are compiled independently so need their .h file
> to be complete. So I am lost again...
>
>
> Regards,
>
>
> --
> Vince
>
>
>
> The complete test program is as follows, can't make it simpler :
>
>
> main.c
> ------
>
> #include "ui.h"
>
> void main (void){
>
> }
>
> ui.c
> ----
> #include "ui.h"
>
>
> ui.h
> ----
>
> #include <avr/pgmspace.h>
>
> //data type for one engine parameter
> struct param {
>  char desc[11];                                  
>  char unit[4];
>  char format[6];
> };
>
>
> extern const struct param __ATTR_PROGMEM__ param_list[] = {
>  { "Throttle", "  %", "%2d" },
>  { "Eng. Speed", "RPM", "%4d" },
>  { "M. A. T.", " °C", "%2d" },
>  { "M. A. P.", "Bar", "3.2f"}
> };
>

You need to define the actual variable once, and then need an extern
directive for the other modules. You can do the following. There are
variantions on this, but I found this to be clear and easy to mix initalised
and unitialised global variables.

In ui.c do the following


#define UIC_M
#include "ui.h"
#undef UIC_M


In ui.h do the following:


#include <avr/pgmspace.h>

//data type for one engine parameter
struct param {
  char   desc[11];                                  
  char   unit[4];
  char   format[6];
};


#ifdef UIC_M

const struct param __ATTR_PROGMEM__ param_list[] = {
  { "Throttle", "  %", "%2d" },
  { "Eng. Speed", "RPM", "%4d" },
  { "M. A. T.", " °C", "%2d" },
  { "M. A. P.", "Bar", "3.2f"}
};

#else

extern const struct param __ATTR_PROGMEM__ param_list[] ;

#endif


This way the global variable will be defined in the ui module, while any other
module that includes the ui.h file will get the extern reference to the variable
defined in the ui module.

Regards
  Anton Erasmus

--
A J Erasmus

reply via email to

[Prev in Thread] Current Thread [Next in Thread]