Strul med AVR (avr-gcc)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
gille
Inlägg: 69
Blev medlem: 28 november 2004, 18:06:09
Ort: Stockholm
Kontakt:

Strul med AVR (avr-gcc)

Inlägg av gille »

Jag har ett problem med min AVR (mega128) jag har ett par rutiner för att skicka ut saker på serieporten:

putc(char ch) lägger ut tecken på serieporten
puts(char *c) lägger ut en sträng:
for(; *c; c++) putc(*c);

att bara köra
putc('M'); putc('a'); .... fungerar
Kör man puts("Mange"); kommer det bara skit ut.
Om man deklarerar en char-array: char str[]={"Mange"}; Så innehåller den inte "Mange" utan skräp.

Jag gissar att någon kompilatorflagga eller att länkstyrfilen är trasig, nån som har några bra tips?
Eller att det bara är något annat som är knäppt...
monstrum
Inlägg: 620
Blev medlem: 13 januari 2005, 05:38:32
Ort: Göteborg

Inlägg av monstrum »

Det har med att vissa strängar lagras i flash. Strängen "Mange" representeras som en pekare, och vissa fall mellanlagrar kompilatorn i ram-minnet och låter då pekaren vara adressen dit. I andra fall avses flash-adressen och råkar efter det tolkas som en ram-adress, vilket gör att bara "skit" kommer ut.
gille
Inlägg: 69
Blev medlem: 28 november 2004, 18:06:09
Ort: Stockholm
Kontakt:

Inlägg av gille »

Okej, låter vettigt.
Hur gräver man fram det som finns i flashen då?

Och hur ser man till så att sakerna man vill ha i ram hamnar i ram?

Jag har en del strukturer som jag inte vill ha i flash, eller som åtminstone måste kopieras ut i ram illa kvickt.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Såhär är det:

Att deklarera:
char str[]={"Mange"}; // hmmm, er du også dansk?
betyder egentligen bara att du deklarerar:
char str[strlen("Mange")+1];

Ska dessa data stå kvar ska den deklareras:
const char str[]= "Mange";
eller
const char * str = "Mange";
Resultatet blir det samma: str pekar på strängen "Mange". I teorin kommer själva strängen då att sparas i flashen (någonstans SKA den ju vara om den är en konstant) och 'str' är då enbart en adress till den sträng.

Hur det är specifikt med AVR vet jag inte men detta är standart C.
gille
Inlägg: 69
Blev medlem: 28 november 2004, 18:06:09
Ort: Stockholm
Kontakt:

Inlägg av gille »

Dansk är jag inte. Men det låter ju vettigt.

Då ska jag bara se till att jag kan läsa ur flashen.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Icecap> Jag håller inte riktigt med. Ditt exempel är givetvis klockrent rätt och genererar en konstantsträng direkt i flashen. Men även gilles exempel borde fungerat. I hans fall är det en initierad strängvariabel och startupkoden till C:n skall initiera den från data i flashen vid boot. Detta skall kompilern ta hand om, eller är det ett undantag i den här miljön?
Rymdninja
Inlägg: 330
Blev medlem: 15 december 2003, 13:41:25
Ort: Göteborg

Inlägg av Rymdninja »

http://www.nongnu.org/avr-libc/user-manual/index.html

Kolla där. Där står hur man läser från flashen.
Se även faq:en på den siten. Där står iaf om hur man sparar i flash..kanske även hur man sparar i ram??

Happy hunting[/url]
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag har testat det sätt i ett annat inbyggnadsmiljö och där fungerar det rakt av inte att deklarera en variabel i RAM och ladda den direkt. Jag har å andra sidan slagit av att konstanter kopieras från flash till RAM så den biten är ju logisk.

Min anledning till att göra detta är att jag, i mina projekter, inte har enorma mängder med RAM, faktisk har jag bara 6Kb utan extern RAM-krets så jag håller hårt i vad som används av minne osv. Dessutom kan ett värde man behöver som konstant skrivas över (vid fel) om det kopieras och används från RAM och jag har ingen overhead eller hastighetsbegränsning i flashen så jag har ett välfungerande sätt utan att slöa ner processorn.

Vad som fungerar gcc (eller vad det är) kan jag inte svara på.

Rent programmeringsteknisk tycker jag att det är fel att deklarera en variabel med ett visst värde, ska det värde stå fast är det en 'const' eller om det är en variabel som ska ha en viss startvärde grejer man det under uppstartssekvensen. Med variabel menar jag i detta fall ändringsbar.

Alltså hade jag (om jag behövde en variabel sträng med ett visst startinnehåll) deklarerat:

Kod: Markera allt

char str[6];
const char * strConst1 = "Mange";
void main(void)
  {
  memcpy(&str,&strConst1,sizeof(strConst1));
  ... // Nog en massa annat grejs
  while(1)
    {
    ... // här kör det av bara fan
    }
  }
Detta sätt hade för mig varit tydligt och klart, båda vad angår variablens typ och vad man sätter som initial sträng.

Men programmeringsstil är ofta personlig...
gille
Inlägg: 69
Blev medlem: 28 november 2004, 18:06:09
Ort: Stockholm
Kontakt:

Inlägg av gille »

Sådär, hittade ett problem.
Länkade tyldigen inte med -mmcu=atmega128... så nu går det lite bättre.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Icecap> Då är vi överens! Har man ställt in att den inte skall intiera saker så gör den förhoppningsvis inte det. Tyckte bara att en standard-C utan andra inställningar borde klara det.

Sedan håller jag inte riktigt med dig ang. sättet att göra initiering. Givetvis är det effektivare och bättre att göra en konstant direkt av det i flashen om den inte skall ändras. Däremot för en initierad variabel så tycker jag det är lika tydligt med direktinitiering. Det lilla extra förtydligande som erhålles av att göra en memcpy tycker jag äts upp av att man kluddar ner koden med extra såna istället. Ser renare och mer rakt på sak utan memcpy.

Det är säkert väldigt personligt och det är så jag är van att jobba.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jovisst kan du ha ett poäng där, anledningen till mitt val är att jag vill ha absolut kontroll över vad som händer. Jag har tillbragt på tok för mycket tid med att debugga saker som blev klarat automatisk för mig, saker jag inte vill skulle hända osv.

Själva memcpy-delen har jag alltid i en separat rutin (void Initialize_Variables(void)) som jag slänger i *.h-filen, funktionen utförs ju antingen dold eller via mitt bevåg och jag hatar att ordna andras problem.

Men jag tror att det är just beroende på person vad man gillar, mitt sätt eller ditt sätt är lika "riktiga"....men de behöver inte passa andra än just oss.

gille: bra att du fick det till att rulla.
Skriv svar