GCC fråga (KPIT GNU)

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

GCC fråga (KPIT GNU)

Inlägg av Icecap »

Jag har gjort en del program i Renesas egen C-kompiler för M16C och senast RX. Men storleken på resultatet är ju storleksbegränsat till 128kB med RX-delen.

Men det finns ju KPIT GNU-kompilers och jag menar att de är baserat på GCC. Alltså håller jag på att överföra några projekt till denna kompiler - och någonstans tänker jag fel!

I standard-kompilern är det ganska enkelt: inkludera filer när de behövs med #include, sedan dyker de upp i projektlistan per automatik.

Men GCC är ju en aning mer petig... och då undrar jag: om man har ett antal filer som är olika delar av projektet (det har man ju oftast), ska dessa tillfogas projektet eller ska de #inkluderas?

Exempel: Jag har en typdefinition som jag använder till alla seriella portar, denna variabel är Tx, Rx och diverse-buffer som medger att jag kan ha interruptstyrd sändning och mottagning. Då jag använder ett antal UART samtidig har jag en gemensam definition i <projekt>.h och i samma fil deklarerar jag dom sedan till användning.

Men jag har lagt upp varje UART som en egen <UART>.c fil som jag har inkluderat i projektet och då dessa ju måste #inkludera <projekt>.h för att få tillgång till deras arbetsminne strular det sig med en massa annat som är definierat i <projekt>.h.

Så ni som är vana med GCC: vilket setup använder man?
* Ingen #include men alla filer i projektet?
* Eller bara #include?
* Eller den gyllene mellanväg? Som är vad?

Själva C-programmeringen är enkelt (när jag väl har fått alla portar och funktioner att fungera!) och det kan vara att jag helt enkelt är ovan med strikta krav på rätt upplägg i projekt - men är det så är det ju dags att jag lär mig!
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: GCC fråga (KPIT GNU)

Inlägg av sodjan »

Det här känns lite som äpplen och päron.

#include är för att inkludera kod som måste vara med vid
en viss kompilering, det är i princip ingen skillnad mot att
skriva motsvarande kod direkt i filen (där #include används).

Att lägga till en fil i projektet bör endast betyda att make miljön
känner till att den finns och att make kommer att se till att den
kompileras om det behövs. Samt att länkaren kommer att ta med
alla filer i projektet vid länkningen.

Dessa två saker har inget direkt med varandra att göra, och de kan
inte ersätta varandra.

Det här borde gälla all programmering, inte bara med GCC och det är
inte alls någon speciellt för C heller, det gäller alla "språk".
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

sodjan: vi är helt överens och jag har levt med detta sätt att göra projekt på länge - men om jag gör ett nytt projekt och kopierar över filerna från Renesas' kompiler till projektet med KPIT-kompilern blir det errors i mängder!

Ett mycket litet fåtal av dom är fråga om syntax, ett annat fåtal är för att jag använder definitioner som redan finns och då är det ju bara att byta namn, så är det löst.

Men jag har Office_Clock projektet som exempel.
Det finns Office_Clock.c som main-fil samt Office_Clock.h där jag definierar definitioner, konstanter, variabler osv.
Men i t.ex. Display.c måste jag inkludera Office_Clock.h för att den rutin ska få tillgång till bildminnet osv.

Detta ger då ERROR: Conflicting types för 'T_CONFIG'
Detta då den dels finns med i projektet (#include i Office_Clock.c) och dels måste inkluderas i Display.c för att den behöver variabler som definieras där.

Och detta var ett fel, det är tonvis med denna typ fel och det stör mig ganska mycket. Så frågan är:
* Ska jag definiera variabler och konstanter på ett annat sätt?
* eller är det en inställning som står fel?
* eller är det bara så det är och det är dags att be chefen om att köpa en licens till den kompiler som fungerar för mig?

Jag har inte större problem med att skaffa licensen men GCC blir ju bättre och bättre och är det så att mina problem består av att jag är slarvig är det bättre att jag fixar så att jag inte slarvar.
hummel
Inlägg: 2269
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: GCC fråga (KPIT GNU)

Inlägg av hummel »

Inkludera dina h-filer i varje fil som behöver tillgång till dessa.
Men du ska sätta ett skydd for double inclusion i alla dina h-filer enligt följande:

// some_header_file.h
#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
// your code
#endif
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: GCC fråga (KPIT GNU)

Inlägg av johano »

Man bör ju aldrig definiera variabler/funktioner i sina #include-filer, det är att be om problem. Endast deklarationer i headerfilerna och definitioner i .c-filerna.

Behöver en variabel vara synlig från fler .c filer så deklarera den som extern i .h och definiera den i en av .c-filerna

Typ:

Kod: Markera allt

mystuff.h
======

  typedef struct {

    int a;
    char *b;

  } MyStruct;

  void SomeFunction(MyStruct*);

  extern MyStruct MyGlobalData;

mystuff.c
======
  #include "mystuff.h"

  MyStruct MyGlobalData;

  void SomeFunction(MyStruct *p) 
  {
    // ...
  }

someotherstuff.h
==========
void OtherFunc();

someotherstuff.c
==========

  #include "mystuff.h"
  #include "someotherstuff.h"

  void OtherFunc()
  {
    SomeFunc( &MyGlobalData );
  }


för att undvika problem med include-filer som inkluderas fler än en gång kan man lämpligen wrappa dess innehåll med en #ifndef:

Kod: Markera allt

#ifndef __MYINCLUDE__
#define __MYINCLUDE
...

...

#endif
/johan
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

Jag har såklart wrappad alla .H-filer med

Kod: Markera allt

#ifndef __BLA_BLA_h__
#define __BLA_BLA_h__
...
#endif // __BLA_BLA_h__
Men jag får nog se över mina variabeldefinitioner. Tyvärr är det även mina typedef som ger knas och felmeddelanden.
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: GCC fråga (KPIT GNU)

Inlägg av bit96 »

Ett sätt att testa sina *.h-filer är att kompilera dom separat.
De skall ge noll byte, d.v.s. det skall inte bli någon kod utav dom.

Blir det någon kod har man gjort "fel", även om det är bekvämt ibland med kod i *.h-filer. :)
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: GCC fråga (KPIT GNU)

Inlägg av sodjan »

Men då är det mer en .c fil, ingen .h fil... :-)
Inget hindrar att man har gemensam kod i en .c fil
och gör #include på den på ett passande ställe i koden.

> Detta ger då ERROR: Conflicting types för 'T_CONFIG'

"Conflicting types" verkar ofta bero på att man har "fel" ordning
på användningen och definitionen av något. T.ex

main()
{
myfunc(1);
}

void myfunc(a int)
{
...
}

Eftersom användningen av myfunc kommer först (utan prototyp)
så kommer GCC att anta att returvärdet är int, när den senare
definieras till void så får man "Conflicting types". Om myfunc hade
varit av typen int, så hade det fungerat.

Jag gissar att du har något problem med i vilken ordning saker och ting definieras.

Samma sak med:

int myfunc(struct mystru *abc);
struct mystru
{
...
...
}

Det ska vara :

struct mystru
{
...
...
}
int myfunc(struct mystru *abc);

Kanske att 'T_CONFIG' innehåller något som defineras senare?
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

Conflicting types kommer uteslutande av att samma .H-fil inkluderas två (eller fler) ställen!

Är det så att variabeln används innan den är definierat får jag en varning om det istället.

Det konstiga är ju att en kompiler är hur förlåtande som helst medan den nästa är hur kinkig som helst.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: GCC fråga (KPIT GNU)

Inlägg av sodjan »

OK. Hoppas det löser sig i alla fall.
Du får inga "Multiple definition" ?
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

Nu har jag gjort samma sak - fast på ett annat sätt och nu kompilerar koden utan problem. Bara synd att den inte fungerar... *suck*

Men det kom en tanke som jag gärna vill kunde lösa:
Jag har ett kretskort (Styrenhet 2.00) som har ett antal funktioner/anslutningar. Display-data, 1-Wire, EEPROM, RTC, seriella portar osv.
Jag vill gärna kunde göra "fasta" funktioner till projekt som använder detta kretskort. Vissa projekt kommer inte att använda 1-Wire, andra använder inte RTC osv.

Om vi tar 1-wire som exempel, då kanske jag vill reservera plats för kanske 8 sensorers serienummer. Detta är inget problem att göra i 1-wire rutinen/filen. Vill jag spara dessa i EEPROM är det inget problem heller att kommunikera värden mellan 1-wire delen och "main"-programmet. MEN hur gör jag då om jag vill ha t.ex. plats för ett annat antal enheter i minnet?

Själva bytet är enkelt: en definition. I 1-Wire filen kan jag göra:
#ifndef ONE_WIRE_NUMBERS
#define ONE_WIRE_NUMBERS 8 // Set default value
#endif

På detta vis kan jag bara definiera ONE_WIRE_NUMBERS med rätt värde i "main"-programmet och saken är biff - OM 1-Wire rutinen "ser" detta värde under kompileringen. Och nu kommer kruxet:
Då 1-Wire rutinerna/filen ska "färdigodlas" och bara inkluderas (på något vis) i alla projekt vill jag inte att jag ska ändra i 1-Wire filen när den väl är avlusat och fungerande, alltså kan jag inte anpassa en #include "Project/xxx.h" i 1-Wire filen.

Så exakt hur gör man detta? I grunden är det alltså frågan: Hur definierar jag en global definition som läsas in i "underfilerna" innan de kompilerar?
ie
EF Sponsor
Inlägg: 1276
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: GCC fråga (KPIT GNU)

Inlägg av ie »

Vet inte om jag förstår dig rätt, men...

Om du menar att du vill ha funktionerna i ett lib, så funkar det inte, eftersom att de redan är kompilerade. Då måste du göra koden mer generell, så att du kan sätta storleken mjukvarumässigt. Dvs mainprogrammet anropar en init med antal adressposter som argument.

Håller själv på med ett projekt där jag försöker separera programmodulerna så mycket som möjligt. Håller på att bygga moduler för UART, SWUART, EEPROM, 1W, LCD mm. Sen tar jag bara med de som behövs för tillfället. Jag har dock valt att ha en projektgemensam fil, för bl a pin-definitioner.
Användarvisningsbild
Icecap
Inlägg: 26153
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

Nja... jag klarar mig utan att det blir ett lib och jag har ett typisk problem just nu.

Interruptproblemet löste sig (= jag löste det). Istället för att det finns en funktion där man anger en #pragma om att "denna rutin är en interrupt och använder denna vector" måste jag ange det i en fil med en array av functionpointers. Mer jobb men inget problem som sådan.

Jag har funktion för att läsa & skriva den DS3232 (RTC) som kan finnas på kortet. Dallas har ju i deras visdom beslutat att den ska använda BCD-kodning och jag har, i min visdom(?) beslutat mig om att den interna klocka ska vara en unsigned long som räknar sekunder sedan 2010-01-01 0:00:00.

Och nu kommer problemet: för att skriva ut datum och tid är det en del enklare att ha ett antal värden som innehåller år, månad, datum, timme, minut och sekund. För detta har jag en typedef (T_DATE_TIME) som definieras i Date_Time.h. I main-filen deklarerar jag att den ska användas varför jag måste inkludera Date_Time.h.

Men då den även måste inkluderas i DS3232-funktionerna får jag en jäkla massa fel!
En av dom:
C:\WorkSpace\Office_Clock_100\Office_Clock_100\Debug\Date_Time.o: In function `Date_Time_Set_DTS':
C:\WorkSpace\Functions/Date_Time.c:112: multiple definition of `Date_Time_Set_DTS'
C:\WorkSpace\Office_Clock_100\Office_Clock_100\Debug\IIC_DS3232_100.o:\Workspace\Functions/Date_Time.c:97: first defined here

Självklart har jag gjort den vanliga #ifndef __blablabla__/#define__blablabla__ osv.

Det är tydligen så att med GCC fungerar det inte att main-filen använder typedef's från en "under-fil" och det känns ju seriöst fel.
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: GCC fråga (KPIT GNU)

Inlägg av bit96 »

Du kan göra init-funktionern till dina rutiner, t.ex. init_one_wire(div parametrar bl.a. antal sensorer).
Därefter får du kompilera alla dina one-wire-funktioner en och en och därefter stoppa in dom i ett lib, te.x. onewirelib.

I ditt program inkluderar du headerfilen tillhörande onewirelib, te.x. one_wire.h
Bland det första du gör sen är att anropa init_one_wire(...) och sen är det bara att köra.

Vid kompileringen/länkningen kommer endast de funktioner som används att plockas ut ur lib-filen.

Eller, jag kanske inte riktigt är med på vad du söker... :humm:
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: GCC fråga (KPIT GNU)

Inlägg av sodjan »

> från en "under-fil"..

Vad är en "under-fil" ???
Är det en separat-kompilerad fil som länkas till resten "at link-time"?
Eller är det en fil som inkluderas i något annat "at compile-time"?

> ...multiple definition of `Date_Time_Set_DTS'

Vid "link-time" kan man få "multiple definitions" om samma globala symbol
finns i flera av de länkade objektfilerna.

Vid "compile-time" kan man få samma sak om samma symbol definieras
på flera ställen (behöver inte vara global/extern definierad).

> Självklart har jag gjort den vanliga #ifndef __blablabla__/#define__blablabla__ osv.

Det är något som enbart hjälper i faller med "compile-time" varningar.
Det har ingenting med separat kompilerade filer att göra (så klart).
Skriv svar