Sida 1 av 1

Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 17 mars 2013, 23:44:59
av jens75
Jag har problem att skicka en pekare till en sträng och sedan läsa innehållet ett tecken i taget. Problemet är att jag inte lyckas läsa ut den char som i detta fall ligger på pos [0].

I main har jag följande:

Kod: Markera allt

int main(void)
{
  lcd_puts("Hej");
  while (1) {;}
  return 1;
}
Funktionen lcd_puts set ut så här:

Kod: Markera allt

void
lcd_puts(unsigned char *line)
{
  if ((int)line[0] == 255) {
    /* HIT KOMMER JAG ALLTID. DVS line[0] är alltid lika med 255 (0xFF) */
  }
}
Några ideer på vad som kan vara fel. Har inte arbetat med avr-gcc innan eller atmega16 heller för den delen, så jag hoppas på att det finns en enkel fix.

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 00:05:59
av adent
Jag kan verkligen inte se något fel... Möjligen skulle jag provat utan (int)-cast, men ska inte spela någon roll...

Ögna igenom denna? Jag hittar inget just, men du skickar inte med all din kod. Kan ju vara andra pekarfel eller vad som...
Prova att skriv en så liten och enkel kodsnutt som bara möjligt, typ som det du klistrade in och se om det funkar. (Med reservation för att det är precis vad du redan gjort :)

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

Sen skulle jag provat att deklarera följande och skicka in i stället, bara på prov.

Kod: Markera allt

unsigned char data[4] = {'H','e','j','\0'};

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 00:21:12
av TomasL
Hmm, du kan väl inte ta en pekare rätt av, och indexera den, det du får är ju adressen till första elementet, du får inte strängen som sådan.
För att förtydliga:

Kod: Markera allt

if ((int)line[0] == 255) {
    /* HIT KOMMER JAG ALLTID. DVS line[0] är alltid lika med 255 (0xFF) */
  }
Ja du skall alltid hamna där, då line innehåller adressen till "hej"-strängen.

i stället

Kod: Markera allt

if (255 ==  *line) {
så bör det bli riktigt.
När du sen skall hantera nästa tecken så ligger det på *(line++)

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 07:40:04
av cyr
line[0] och *line ger väl båda första elementet, likaså är line[1] samma som *(line+1) osv.

Ser inte heller nåt fel, utom att int-casten verkar onödig.

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 07:54:23
av snigelen
Plockar du med .data-segmentet i avr-objcopy? (Eller låter bli att ta bort det).

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 08:22:00
av jens75
Har testat att köra motsvarande kod på vanlig gcc i linux och då fungerar det

Kod: Markera allt

#include <stdio.h>
#include <string.h>

void
lcd_puts(unsigned char *line)
{
  int length = strlen(line);
  printf("length: %d\n", length);
  printf("char: %d\n", (int)line[0]);
  if ((int)line[0] == 255) {
    printf("ALERT"); /* HIT KOMMER JAG ALLTID. DVS line[0] är alltid lika med 255 (0xFF) */
  }
}

int main(int argc,char *argv[])
{
  lcd_puts("Hej");
  return 1;
}
Jag får då som förvämtat utskriften
length: 3
char: 72

Motsvarande kod fungerar inte för mig med avr-gcc. strlen i avr-gcc verkar också ge ett galet värde.

Är inte helt på det klara vad du menar snigelen. Men det låter som om du är något på spåren. Får googla upp det och testa ikväll :D

I Makefilen har jag följande som berör avr-objcopy:

Kod: Markera allt

OBJCOPY=avr-objcopy
rom.hex : demo.out
        $(OBJCOPY) -j .text -O ihex demo.out rom.hex

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 08:26:44
av snigelen

Kod: Markera allt

$(OBJCOPY) -j .text -O ihex demo.out rom.hex
detta funkar inte. Värdet av initierade variabler och sträng-konstanter finns i .data och det kommer inte med. Byt till (ta med bara .text och .data)

Kod: Markera allt

$(OBJCOPY) -j .text -j .data -O ihex demo.out rom.hex
eller (ta med allt utom .eeprom, .lock och .fuses)

Kod: Markera allt

$(OBJCOPY) -R .eeprom -R .lock -R .fuses -O ihex demo.out rom.hex

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 08:49:27
av SvenW
Är lite ringrostig vad gäller AVR och känner inte till om just den aktuella medellen,
men jag vill minnas att om man vill komma åt data som ligger i flashninnet så måste
man använda speciella funktioner. En textsträng hamnar antagligen där.

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 08:57:54
av snigelen
> En textsträng hamnar antagligen där.

Jo det gör den, men den kopieras till SRAM av startup-koden (om det finns något att kopiera, dvs .data är inkluderat) så det behövs inget speciellt för att komma åt strängen.

Vill man ha strängen bara i FLASH får man använda avr/pgmspace.h med PROGMEM och typ pgm_read_byte. (eller använda __flash i avr-gcc 4.7.x, då slipper man pgm_read_byte).

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 09:11:05
av sodjan
Jag misstänkte när jag såg förstainlägget att det just var
någon konflikt mellan flash/RAM för lagring av strängen "Hej".
Var dock osäker så jag struntade i det då.

Men får du inte ut någon assemblerlistning? Det är ju inte mycket
kod och den bör ge svaret på vad som faktiskt händer.

Re: Basalt strängproblem linux Ubuntu / avr-gcc / atmega16

Postat: 18 mars 2013, 22:51:13
av jens75
Vill bara meddela att det fungerar fint med:
$(OBJCOPY) -j .text -j .data -O ihex demo.out rom.hex