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

Re: GCC fråga (KPIT GNU)

Inlägg av Icecap »

sodjan: Jag har inkluderat "Date_Time.C" och "Date_Time.h" i själva projektet, ÄNDÅ måste jag göra en #include "Date_Time.h" för att få typedet'en och DÅ kommer denna multiple definition.

Jag fattar helt enkelt inte varför man inte kan skapa ett projekt, inkludera de filer (/funktioner) som behövs och kompilera skiten i en samlat klump! Varningerna & felen jag får är ju för att SAMMA fil kompileras fler gångar och det känns inte helt genomtänkt.

Gör jag samma sak i Renesas kompiler är det inget fel någonstans, det fungerar som det ska.

Och med under-fil menar jag en av funktioner som jag lägger till projektet, alltså allt annat än filen som innehåller main-rutinen.

bit96: fungerar inte! Då ska jag köra med dynamisk minnesallokering och det gör jag inte!

Olika projekt kan ha olika behov, någon behöver bara plats för en temperatursensor, andra kan behöva signifikant fler och då vill jag kunde skapa ett projekt och definiera antal sensorer osv. i projektet och ändå inkludera funktionerna utan att behöva kopiera filerna och anpassa dom till varje projekt.

Tar vi 1-Wire® som exempel ska den fungera likadan i kommunikationen oavsett antal sensorer, det enda som kan skilja är antal sensorer och minnet till att hålla deras serienummer.
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 istället för init_one_wire() som internt allokerar och skapar grejer ha en funktion typ info_one_wire() som talar om vad som behövs för att kunna användas.
T.ex. kan den tala om att en sensor kräver si och så många bytes.
Sen får du i ditt huvudprogram skapa detta minne.

Eller helt enkelt skapa en extra fil typ adapt_one_wire.h där du manuellt i varje projekt får redigera denna fil och anpassa till den hårdvara du har.

Eller skapa en massa olika one_wire()-funktioner typ one_wire_1sens(), one_wire_2sens(), one_wire_3sens() osv, och använda de du behöver som då automatiskt plockas ut ur det "enorma" onewirelib. :)

Men eftersom du måste anpassa till olika hårdvara så tror jag att lättaste vägen är att samla allt som just behöver anpassas till hårdvara i en (eller flera) mycket väldokumenterade/kommenterade adapt_*.h-filer och sen kompilera om allt allteftersom.

Det är nog omöjligt att nu skriva ett program som är anpassat för olika hårdvaror som du tillverkar senare.

Snegla lite på CP/M hur det är uppbyggt.
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 »

Hårdvaran är den samma, projekten är olika! Det är ett enda kretskort som kan göra ett antal olika saker, beroende på vad man vill men hårdvaran är den samma. Dock kan saker som om det finns en 433MHz radio, alternativ en XBee alternativ en RN171 WLAN radio på eller inte, om det är XPort på eller inte, om det finns en 12V->5V DC-DC omvandlare eller inte osv.

Display-utgången är också fast medan själva display-modulerna kan variera.

* Ett projekt kan vara en tid & temp-skylt.
* Ett annat kan vara ett textskylt som styrs via en seriell port.
* Ytterligare ett annat kan vara en höjdvarningsstyrning.

Till ett textskylt behöver man inte 1-Wire eller RTC - men det behövs verkligen till ett tid & temp skylt.
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 blir lite generellt, men det borde stämma för vilken utvecklingsmiljö som helst...

> sodjan: Jag har inkluderat "Date_Time.C" och "Date_Time.h" i själva projektet,...

OK, det betyder att utvecklingsmiljön känner till .C filen och kommer sannolikt
att generera MAKE information för att separat-kompilera den. Däremot är det
lite oklart varför .h filen ska "inkluderas i projektet". Normalt inkluderar man .h
filerna via #include direktiv och det är inget mer med det. Jag förstår inte varför
"projektet" behöver veta något om .h filerna !?

> ÄNDÅ måste jag göra en #include "Date_Time.h" för att få typedet'en...

Självklart, det är den ända metoden för att inkludera definitionerna i .h filer!
Hur ska .C filen annars känna till det som finns i .h filen ??

> och DÅ kommer denna multiple definition.

Hm, *om* det nu har något med att .h filerna är med i "projektet" så
skulle jag prova att plocka bort dom därifrån. Det känns inte som det...

Det är fortfarande inte tydligt om du får "multiple definition" från kompileringen
eller från länkningen. Det är viktigt för att förstå var de kommer från, som jag
skrev i förra inlägget.
Nerre
Inlägg: 26725
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: GCC fråga (KPIT GNU)

Inlägg av Nerre »

Icecap skrev: Jag fattar helt enkelt inte varför man inte kan skapa ett projekt, inkludera de filer (/funktioner) som behövs och kompilera skiten i en samlat klump! Varningerna & felen jag får är ju för att SAMMA fil kompileras fler gångar och det känns inte helt genomtänkt.
Du verkar ha missförstått hur det fungerar.

Som jag förstått det (det är i alla fall så det brukar fungera):

De filer du inkluderar i projektet kompileras var för sig och länkas sen ihop av länkaren.

Det är med andra ord meningslöst att inkludera .h-filer, eftersom de ändå inte genererar nån kod.

Du får tänka baklänges:

Ditt program består av flera objektfiler som är ihoplänkade.

Varje objektfil skapas genom att kompilera en .c-fil.

Projektet talar om vilka .c-filer som skall kompileras.


Sen får varje .c-fil inkludera de .h-filer som den "behöver".


På sätt och vis är det där enklare att förstå när man jobbar med makefiler.

En makefil säger ungefär:

- "Programmet" skapas genom att länka ihop "dessa" .o-filer
- En .o-fil skapas genom att kompilera motsvarande .c-fil
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 »

Slutresultatet blir alltså att OM jag vill göra som jag avser kan jag inte inkludera några filer i <projektet> som sådan - förutom main-filen.

Men alla funktioner jag vill använda ska jag alltså dra in via en #include "filnamn.c" och sedan ska det fungera. Ska testa.
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 alla funktioner jag vill använda ska jag alltså dra in via en #include "filnamn.c"...

Nej nej nej... :-)

Alla filer som ska/måste *kompileras* ska med i projektet.
D.v.s (normalt) alla .C filer. De kommer då att kompileras var för sig
till en objekt-fil och sedan och länkas ihop vid länkningen.

Filer som includeras (normalt alla .h filer) includeras vid #include
och behöver (normalt) inte vara kända för övrigt av "projektet".

D.v.s *om* just din miljö är någotlunda normal...
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 »

Är det manualen "KPIT Eclipse User Manual" från denna sida som gäller?
http://www.kpitgnutools.com/ke_getting_started.php

Jag ser att den (på sidan 99) säger "Invoking: Compiler" och "Invoking: Linker".
Efter vilken av dessa är det du får "multiply defined" felen?

Jag ser också att .h filerna ligger i "src" katalogen. Helt OK sannolikt,
den borde vara smart nog för att inte göra något med dom direkt.
D.v.s att försöka kompilera dom eller liknande..
Nerre
Inlägg: 26725
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: GCC fråga (KPIT GNU)

Inlägg av Nerre »

Precis som jag skrev verkar det vara en total förvirring kring hur program "byggs ihop" :)

Om man har hela programmet i en enda .c-fil så är det enkelt, bara att kompilera så får man en .o-fil som innehåller hela programmet. Allt länkaren behöver göra är att placera grejerna på rätt adress i "hex-filen" (det som ska laddas in i uCn).


När man delar upp programmet i flera filer blir det mer komplext.

För att koden i en .c-fil (vi kan kalla den C1) ska kunna anropa en funktion (vi kan kalla den foo()) i en annan .c-fil (C2) så måste funktionen foo() vara deklarerad i C1 (OBS! Deklarerad, inte definierad!). Deklarationen talar om vad funktionen returnerar för typ och vad den tar för parametrar, inget annat. Detta för att kompilatorn ska veta hur den ska skicka med parametrarna och hur den ska ta emot returvärdet.

Ex.
int foo(int bar);

Självklart måste funktionen också vara deklarerad OCH definierad i C2.

För att vara säker på att man har samma deklaration i alla filer så lägger man deklarationerna i .h-filer. Samma .h-fil inkluderas då både i C1 och C2.

Observera att C1 inte "vet" i vilken fil funktionen finns. Den har ingen aning om att funktionen ligger i C2. Det vet inte kompilatorn heller, den vet bara (tack vare defintionen) att det kommer att finnas en funktion foo() som går att anropa.


Sen kompileras bägge dessa filer för sig, C1 kompileras till O1 och C2 kompileras till O2.

Objektfilerna (O1 och O2) innehåller "nästan" färdigkörbar kod. Men en del saker i filerna är inte färdig kod utan ligger där med ett "symbolnamn". För eftersom det är två separata filer som har kompilerats separat så vet kompilatorn inte vilken adress som funktionen foo() kommer att ligga på.

Detta fixar sen länkaren.

Den "kopierar ihop" alla objektfiler (O1 och O2 i vårt exempel) och sen ersätter den alla symbolnamn med korrekt adress (nu när all kod och alla variabler är ihopsamlat så kan länkaren räkna ut vilka adresser alla grejer ligger på).
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 »

Ja, när det gäller funktioner så är det ju ganska enkelt och "rent".
När det gäller andra typer av symboler så har man lite mer att
göra, t.ex variabler typ Date_Time_Set_DTS i Icecap's exempel.

Date_Time_Set_DTS ska *definieras* på ett ställe, sannolikt i samma
.c fil där rutinerna/funktioner som använder den finns.

Sedan behöver den *declareras* med attributet "extern" i alla andra filer
som *använder* denna variabel. Detta görs enklast med en .h fil som
är specifikt avsedd för detta.

Det betyder att man för generella rutiner normalt har två .h filer, en för
inkludering i C2.c självt (och används enbart för C2.c) och en för inkludering i
alla filer som kommer att använda/anropa något som definieras i C2.c.
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 & Nerre: Jag har nu börjat att få ihop det som jag har tänkt mig. Problemet är inte att varje fil kompileras för sig, problemet är att NÄR de gör det finns det ibland andra definitioner som de är beroende av och DOM får jag en massa felmeddelande på.

Jag har därför tagit ett steg tillbaka.

Att ett projekt kan ha en hel del uppstartsjobb kan jag fint ta, det är ju ett engångsjobb. Alltså som t.ex. att ställa in interruptvektorer, skapa variabler osv.

Nu har jag gjort ett par filer som är anpassat just för denna styrenhet. Deras namn är tydliga om detta. Det finns t.ex. en för DS3232 (RTC) och en för 24FC256 (EEPROM). Båda använder IIC-bussen och därför kommer IIC-bus-filen att #definie __IIC_BUS__
Var och en av de enheter som använder IIC-bussen kan sedan kolla om den definition är gjort och om inte inkludera IIC-bus-filen per automatik.

Och det verkar fungera! Förvisso har jag ställd kompilern till att bara visa de första 26 fel men det är ett steg på vägen.

Mitt slutmål ska vara att jag kan starta ett projekt, definiera vilka interrupts som används osv och behöver det EEPROM'en är det bara att inkludera C-filen för 24FC256 och det är klart! Självklart måste main initiera IIC, EEPROM osv. men jag behöver inte kopiera filer och anpassa rutinerna efter varenda projekt - och det är ju mitt mål.
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 »

> Jag har därför tagit ett steg tillbaka.

Ja, det kan ju ofta vara ett steg i rätt riktning... :-)

> DS3232 (RTC)

Antag att du har en fil som heter RTC.c där alla funktionerna och
variablerna som RTC rutinerna behöver finns.

Sen har du kanske en RTC.h där allt som RTC.c behöver definieras.
Denna inkluderas då *enbart* i RTC.c!

Sedan har man ofta en RTC_ext.h (eller något liknande) där allt som
*alla andra* .c filer behöver deklareras (alltså inte definieras), alltså
i de .c filer som ska använda RTC rutinerna.

> och behöver det EEPROM'en är det bara att inkludera C-filen för 24FC256 och det är klart!

Du behöver även sannolikt gör #include på någon ERPROM.h (eller EEPROM_ext.h) också.
Alltså den .h fil där rutiner och variabler i EEPROM.c deklareras för andra .c filer.

Sen så har du ju även (som du skriver) problemet då en C fil använder *både*
RTC och EEPROM och *båda* dessa använder IIC. Där kan #ifdef... behövas för
att undvika "multiple definition..." fel.
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 en fil som utför IIC-funktionerna. Dessa behövs av båda RTC och EEPROM. I den deklarere jag:
#define __CONTROLLER_UNIT_200_IIC_100__

I båda RTC och EEPROM-filen har jag sedan:
#ifndef __CONTROLLER_UNIT_200_IIC_100__
#include "\Workspace\Functions\Controller_Unit_200_IIC_100.c"
#endif // __CONTROLLER_UNIT_200_IIC_100__

Så oavsett vilken jag använder av de två funktioner kommer IIC "igång" först och sedan kompileras resten.

Mitt problem består inte i att göra externa referenser heller, det består i att dessa externa referenser är envägs-referenser!

Jag har min fasta övertygelse om att ett värde som anger en viss parameter aldrig ska anges mer än ett ställe! Om vi tar ett värde som avsätter plats för ett antal 1-Wire® sensorers serienummer som exempel kan ett projekt behöva 20 medan ett annat kan behöva 1.

Om jag då gör en "One_Wire_Def.h" som innehåller:
#define MAX_NUMBER_OF_1WIRE_SENSORS 8
får jag fel efter fel når jag inkluderar den fler ställen! Och DET stör mig!

Det blir conflicting error.
Nerre
Inlägg: 26725
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: GCC fråga (KPIT GNU)

Inlägg av Nerre »

Det är där du gör fel, du kan inte inkludera samma .c-fil i två andra .c-filer. Då kommer att du dubletter av koden och då är det klart länkaren klagar på att det är dubletter. Samma kod kommer att kompileras två gånger, i två olika objektfiler.


Du ska ha en Controller_Unit_200_IIC_100.h där funktionerna deklareras. Den gör du #include av i de .c-filer som ska kunna använda funktionerna i Controller_Unit_200_IIC_100.c.

Sen kompileras Controller_Unit_200_IIC_100.c separat (det sker om den är inkluderad i projektet, men INTE mha #include nånstans).

Då kommer du att få en Controller_Unit_200_IIC_100.o som innehåller koden för funktionerna.

Sen kommer du få en RTC.o och en EEPROM.o. Dessa anropar funktionerna i Controller_Unit_200_IIC_100.o. Länkaren ser till att sätta rätt adresser när det hela slås ihop.

Om jag då gör en "One_Wire_Def.h" som innehåller:
#define MAX_NUMBER_OF_1WIRE_SENSORS 8
får jag fel efter fel når jag inkluderar den fler ställen! Och DET stör mig!
Det är ju samma sak där som med alla andra #defines, du måste "wrappa" den i #ifndef.



Det är viktigt att förstå att #include är bara ett sätt att slippa kopiera och klistra. Många kompilatorer (eller egentligen pre-processorer) kan lämna kvar den källkodsfil som blir efter exekvering av alla makron. Det ger en rätt bra förståelse för hur det fungerar.

Man KAN också prova på att köra alla kompileringssteg manuellt (men då ska man ha ett rätt litet projekt annars blir det mycket att hålla reda på).

http://stackoverflow.com/questions/8527 ... ng-linking

http://codingfreak.blogspot.com/2008/02 ... n-gcc.html
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 »

Nerre: jag HAR redan wrappad .H-filerna!

Att en #include tar in testen i den inkluderade fil är inget nytt för mig, det är vad jag planerar med nu där jag vill ha det till att fungera.
Skriv svar