www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Datenpaket in Programmspeicher - C


Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Anfängerfrage:

Kann mir jemand sagen, wie man ein Datenpaket im hinteren Teil des 
Progammspeichers eines AVRs (vorliegend M32) unterbringen kann, ohne 
jedes Mal mit einem Hex-Editor hantieren zu müssen?

Bis jetzt habe ich es so gemacht: Programm geschrieben (ca. 4Kb), in 
hex-Datei umgewandelt, mit einem Hex-Editor geöffnet, in den hinteren 
Bereich der hex-Datei die Daten eingefügt (ca. 24Kb), das ganze wieder 
abgespeichert und dann gebrannt. Das ist mir aber auf Dauer zu 
umständlich.
Gibt es die Möglichkeit, die Daten dem C-Programm direkt anzuhängen, 
damit man nicht nach jeder kleinen Programmvänderung die ganze 
Hex-Editor-Operation komplett durchführen muss?

Ich benutze übrigens AVR-Studio.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

In ein C-Array umwandeln (z.B. mit einem Hexeditor wie 
http://mh-nexus.de/en/hxd/) und dann einfach mitcompilieren.

Matthias

Autor: Wayne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Μαtthias W. schrieb:
> Hi
>
> In ein C-Array umwandeln (z.B. mit einem Hexeditor wie
> http://mh-nexus.de/en/hxd/) und dann einfach mitcompilieren.
>
> Matthias

Meinst du damit sowas, wie Wayne geschrieben hat (Array aus Strings im 
Flash-Speicher) oder ist deine Methode einfacher?

Gibt es keine lib, die die Daten aus einer beliebigen Datei beim 
Compilieren direkt 1:1 in den Programmspeicher schreiben kann?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> Gibt es keine lib, die die Daten aus einer beliebigen Datei beim
> Compilieren direkt 1:1 in den Programmspeicher schreiben kann?

Alles was du brauchst, ist in deinem C-File so etwas
....

uint8_t MyData[] PROGMEM = {

   // und hier dann deine Daten, zb in Hex-Form
  0x10, 0x20, 0x30, .....
};

....

und du hast sie in einer Form, dass sie vom C-Compiler mitkompiliert 
werden

Wie kriegst du sie dort hin?
Du brauchst irgend ein Tool welches dir aus deinem Datenfile, diese Form 
erzeugt.
Für einzelne, spezielle Datenformate (Bilder, Sound) gibt es sicherlich 
Programme, die so etwas machen. Für den allgemeinen Fall ... kenne ich 
keines, ausser wie Matthias schon andeutete einen Hex-Editor, der so ein 
Format erzeugen kann.
Aber: Es ist doch keine Hexerei, sich selber so ein Progrmm zu 
schreiben, welches ein beliebiges Datenfile hernimmt und es in ASCII-Hex 
Form wieder ausdumpt. Ist doch nur eine Fingerübung, und ist schneller 
geschrieben, als du in Google suchen kannst

PS:
Man kann das ja im C-File auch so machen
....

uint8_t MyData[] PROGMEM = {
#include "MyData.h"
};

....

und das angesprochene Werkzeug, erzeugt dann den Hex-Dump der Daten in 
eine Datei MyData.h
0x10, 0x20, 0x30, ...
welche dann beim Compilieren vom Compiler eingebunden wird.

Also: ran an die Buletten, einen Daten-Dumper geschrieben.
Man braucht nicht für jeden Mückenfurz "eine fertige Lib". Manchmal 
macht man sich eben seine Hilfs-Werkzeuge am PC selber. Dafür ist man ja 
schliesslich Softwareentwickler und nicht Powerpoint-Zusammenklicker.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir kommt grade noch eine andere Idee:
theoretisch müsste es doch möglich sein, die Daten ein Mal im hinteren 
Teil des Programmspeichers unterzubringen und bei Änderungen des 
Programms immer nur den vorderen Teil des Flash Speichers neu zu 
beschreiben...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:
> Mir kommt grade noch eine andere Idee:
> theoretisch müsste es doch möglich sein, die Daten ein Mal im hinteren
> Teil des Programmspeichers unterzubringen und bei Änderungen des
> Programms immer nur den vorderen Teil des Flash Speichers neu zu
> beschreiben...


Machs richtig und hör auf dir Gedanken über solche Krücken zu machen. In 
der Zeit in der du hier rumlametierst, hättest du schon längst den 8 
Zeiler am PC für ein entsprechendes Hilfs-Werkzeug selber geschrieben.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

oder man nimmt srec_cat und bastellt sich doch die Hexdatei zusammen:
srec_cat myprog.hex -intel my_data.bin -binary -offset 0x3000 -output my_output.hex -intel -address-length=2

oder erzeugt damit den C-Quelltext
rec_cat my_data.bin -binary -output my_c_file.c -C-Array my_var_name -include

Nicht für jeden <zitat>Mückenfurz</zitat> muss man ein eigenes Programm 
schreiben :-)

Matthias

Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du benutzt avr_objcopy wie in diesem Forumsbeitrag gezeigt: 
Beitrag "Re: Binärdatei in C-Quelltext umwandeln" Das hätte den 
Vorteil, das die eingefügten Daten ohne umständliche Verenkungen aus dem 
C-Programm angesprochen werden können und es somit egal ist, auf welcher 
Adresse die Daten im Programmspeicher liegen. Das Einbinden kann man ins 
Makefile einbauen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Μαtthias W. schrieb:

> Nicht für jeden <zitat>Mückenfurz</zitat> muss man ein eigenes Programm
> schreiben :-)

Ja, wenn man natürlich in seinem Werkzeugkasten was passendes vorrätig 
hat, kann die Mücke pfurzen soviel sie will :-)

(Mich hat nur geärgert, dass nach einer knappen Stunde das 'Problem' 
immer noch nicht gelöst ist und anstatt die 10 Minuten für ein 
Hilfswerkzeug zu investieren, lieber über selektives Flashen nachgedacht 
wird)

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und noch einer: Erf. Hilfsprogramm wäre eine "bin2c" wie von Matthias W 
9:35 genannt. Feste Adresse per eigener input-section. Grob in der Art:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>

// linker-option: -Wl,--section-start=.configsection=0x5000

static const uint8_t configvals[] __attribute__ ((section (".configsection"))) = 
  { 0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x00, 0xff, 0xee };

int main(void)
{
  uint8_t i;
  
  for (i = 0; i < sizeof(configvals)/sizeof(uint8_t); i++ ) {
    PORTA = pgm_read_byte(&configvals[i]);
  }
  while(1) { }
}

Vorgehensweise bringt nichts, wenn die Progammiersoftware Chip Erase vor 
Flash-Programmierung auslöst, üblich bei ISP. In einem Bootloader kann 
man jedoch einen Schreibschutz implementieren, der den Bereich nur 
einmalig schreibt, wenn vorher leer.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

SF schrieb:
> Oder du benutzt avr_objcopy wie in diesem Forumsbeitrag gezeigt:
> Beitrag "Re: Binärdatei in C-Quelltext umwandeln" Das hätte den

objcopy ist natürlich auch noch eine Möglichkeit. Leider ist die 
Beschreibung dort für einen AVR nicht ganz vollständig da die Daten bei 
der beschriebenen Methode im .data landen was dazu führt das sie RAM 
belegen was ja nicht Sinn und Zweck der Aktion ist. Der korrekte Aufruf 
wäre:
avr-objcopy -I binary ~/Draft1.asc --binary-architecture avr4 -O elf32-avr --rename-section .data=.progmem.data foo.o

Ich hab mal einen Artikel im Wiki angefangen.
http://www.mikrocontroller.net/articles/Bin%C3%A4r...

Muss jetzt aber mal kurz weg. Ich stell ihn dann heute Mittag fertig.

Matthias

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Danke für die vielen Antworten! Das Projekt läuft nebenher und hat keine 
akute Eile, soll nur in den nächsten Tagen irgendwann fertig werden (bin 
im Moment noch mit was anderem beschäftigt).

Datenformat umschreiben wäre nicht das Problem.

das sieht ja schon mal ganz interessant aus:
>uint8_t MyData[] PROGMEM = {
>
>   // und hier dann deine Daten, zb in Hex-Form
>  0x10, 0x20, 0x30, .....
>};

was für eine lib brauche ich da und wie wird die startadresse der daten 
im flash-speicher festgelegt?

@matthias:
>Ich hab mal einen Artikel im Wiki angefangen.
>http://www.mikrocontroller.net/articles/Bin%C3%A4r...
>
>Muss jetzt aber mal kurz weg. Ich stell ihn dann heute Mittag fertig.
Tolle Idee! Das wäre super!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> das sieht ja schon mal ganz interessant aus:
>>uint8_t MyData[] PROGMEM = {
>>
>>   // und hier dann deine Daten, zb in Hex-Form
>>  0x10, 0x20, 0x30, .....
>>};
>
> was für eine lib brauche ich da und wie wird die startadresse der daten
> im flash-speicher festgelegt?

Das erledigen Compiler und Linker ganz alleine
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Artikel 
http://www.mikrocontroller.net/articles/Bin%C3%A4r... 
ist jetzt mal soweit fertiggestellt. Wer mag kann ja mal drüberschauen 
und Fehler finden und korrigieren.

Matthias

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Μαtthias W. schrieb:
> Artikel
> http://www.mikrocontroller.net/articles/Bin%C3%A4r...
> ist jetzt mal soweit fertiggestellt.

Hi Mαtthias, Danke!

Ok, ich werd das morgen mit dem "Einfügen als C-Array" probieren...

Mir ist allerdings noch nicht ganz klar, wie ich konkret die mit dem 
Hex-Editor erzeugte C-Array-Datei ins Programm einbinde.


>Beim avr-gcc ist noch darauf zu achten das die Daten, falls gewünscht, im 
>Programmspeicher und nicht im SRAM landen.
Und wie macht man das?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> Mir ist allerdings noch nicht ganz klar, wie ich konkret die mit dem
> Hex-Editor erzeugte C-Array-Datei ins Programm einbinde.

Mach die Datei auf. Das ist einfach nur eine Textdatei.
Was steht drinnen?

WEnn du sie von Hand erzeugen würdest, wie würdest du die dann 
einbinden?

>>Beim avr-gcc ist noch darauf zu achten das die Daten, falls gewünscht, im
>>Programmspeicher und nicht im SRAM landen.
> Und wie macht man das?

Ich glaube, das ist jetzt zum 3.ten mal in diesem Post, dass ich dir den 
Link zum AVR-GCC-Tutorial, Abschnitt "Flash-Speicher" poste. Liest du 
den jetzt bitte endlich einmal durch?

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Und wenns geht vom Anfang des Kapitels bis zu seinem Ende. Inklusive der 
Subkapitel. Wenn du dann an Textpassagen kommst, die ziemlich 
offensichtlich nichts mehr mit Flash zu tun haben, kannst du aufhören.
Und nicht einfach nur drüberscrollen. Lesen!

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, das Erzeugen der .c-Datei hat schon mal geklappt, ist ja wirklich 
simpel mit HxD.

>WEnn du sie von Hand erzeugen würdest, wie würdest du die dann
>einbinden?
Ich würde den erzeugten Text per Makieren rüberkopieren, ans 
Programmende packen und dann die Startadresse eintragen. Werde das 
morgen mal testen.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe mittlerweile folgendes Test-Programm geschrieben, um die Daten in 
den Speicher zu bekommen:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>

 
int main()
{
 return 0;
}


PGM_P array[36] PROGMEM = 

{
  0x53, 0x49, 0x44, 0x46, 0x3C, 0xF5, 0x01, 0x00, 0x56, 0x40, 0x53, 0x42,
  0x63, 0x6D, 0x73, 0x20, 0x12, 0x00, 0x01, 0x00, 0x02, 0x03, 0x01, 0x01,
  0x24, 0x53, 0x01, 0x00, 0x23, 0x56, 0x02, 0x00, 0x07, 0x00, 0x09, 0x17
};

Die Daten landen auch im Speicher, aber nicht als uint8_t, sondern als 
uint16_t (=2bytes, hb = 0x00).

Kein Wunder, dass diese Warnung auftritt:
>>warning: initialization makes pointer from integer without a cast


Die Frage ist, wie mache ich dem Programm klar, dass die Array-Daten als 
uint8_t abgelegt werden sollen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> PGM_P array[36] PROGMEM =

Warum PGM_P?


> Die Daten landen auch im Speicher, aber nicht als uint8_t, sondern als
> uint16_t (=2bytes, hb = 0x00).

Ja logisch. Genau das hast du ja geschrieben.
Du hast kein Array von Bytes angelegt. Du hast ein Array von Pointern 
angelegt.

> Kein Wunder, dass diese Warnung auftritt:
>>>warning: initialization makes pointer from integer without a cast

Richtig.
Das ist kein Wunder.
Aber aus einem ganz anderen Grund.

> Die Frage ist, wie mache ich dem Programm klar, dass die Array-Daten als
> uint8_t abgelegt werden sollen?

Sag mal.
Warum streubst du dich so dermassen, endlich einmal einen Blick ins 
Tutorial zu werfen? Klick auf den Link.

Gleich im ersten Abschnitt, in der Übersicht über das Kapitel, wird ein 
Array aus Bytes (uint8_t) ins Flash gelegt
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3 ,70 };

Und? Ist das jetzt so schwer, das auf deine Daten anzuwenden?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> Ich würde den erzeugten Text per Makieren rüberkopieren, ans
> Programmende packen

Wozu?
Mittels #include kann man wunderbar andere Dateien zum compilieren 
einbinden

> und dann die Startadresse eintragen.

Wozu?
Überlass das doch dem Compiler/Linker die Daten irgendwo in den Speicher 
zu packen! Ist doch völlig egal, wo die Daten tatsächlich hinkommen, 
Hauptsache dein Programm kann sie wiederfinden und alles hat zusammen 
Platz im Flash.


Datei:  daten.txt
  0x53, 0x49, 0x44, 0x46, 0x3C, 0xF5, 0x01, 0x00, 0x56, 0x40, 0x53, 0x42,
  0x63, 0x6D, 0x73, 0x20, 0x12, 0x00, 0x01, 0x00, 0x02, 0x03, 0x01, 0x01,
  0x24, 0x53, 0x01, 0x00, 0x23, 0x56, 0x02, 0x00, 0x07, 0x00, 0x09, 0x17

Datei: main.c
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>

const uint8_t pgmDaten[] PROGMEM = {
#include "daten.txt"
};

#define DATEN_SIZE  ( sizeof(pgmDaten) / sizeof(*pgmDaten) )

int main()
{
  uint8_t i;
  uint8_t value;

  for( i = 0; i < DATEN_SIZE; ++i )
  {
    value = pgm_read_byte( &pgmDaten[i] );

    // mach was mit value, also den i-ten Byte aus dem Flash Array

  }

  return 0;
}

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> PGM_P array[36] PROGMEM =
> [...]
> Die Daten landen auch im Speicher, aber nicht als uint8_t, sondern als
> uint16_t (=2bytes, hb = 0x00).
> [...]
> Die Frage ist, wie mache ich dem Programm klar, dass die Array-Daten als
> uint8_t abgelegt werden sollen?

Schau mal, was Du selbst in

   Beitrag "Re: Datenpaket in Programmspeicher - C"

zitiert hast. Welches Zauberwort steht da vor MyData[]?

Und wozu willst Du die "Startadresse" wissen/bestimmen? Du greifst doch 
einfach über pgm_read_byte(&array[i]) drauf zu!

Gruß,

Frank

P.S.
Boah, diese Ignoranz ist unglaublich. Wie es geht, steht doch im 
entsprechenden Tutorial-Kapitel, welches Karl-Heinz schon mehrfach hier 
erwähnt hat. Karl-Heinz hat wahrscheinlich schon ein Stück aus seinem 
Tisch ausgebissen vor Verzweiflung...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:

> erwähnt hat. Karl-Heinz hat wahrscheinlich schon ein Stück aus seinem
> Tisch ausgebissen vor Verzweiflung...

Davon kannst du ausgehen.

Ich dachte ursprünglich, dass man ihm lediglich die Idee eines #includes 
nahe bringen muss und der Rest steht ohnehin mehr oder weniger 1:1 im 
Tutorial. Aber so dermassen das Tutorial ignorieren, ts, ts.
Das ganze ist eine Sache auf 10 Minuten, selbst wenn man noch nie mit 
Daten im Flash gearbeitet hat. Und jetzt gehts schon in die Verlängerung 
des 5.ten Tags.

Edit: Was heißt ignorieren.
Die ganze Vorgehensweise ist in diesem Thread schon am ersten Tag mehr 
oder weniger komplett aufgezeigt worden. Selbst ein Blinder hätte das 
Greifen können.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekenne mich in allen genannten Punkten für schuldig!

Aber bitte trotzdem keine Stücke aus Tischen beißen!!!


Ok, es gibt Fortschritte:

const uint8_t pgmFooByteArray1[] PROGMEM =  { "Datenkram" }

bringt immerhin schon mal knapp 32kb von meinem 60kb großen Datenpaket 
in den Speicher:
>>Build started 31.8.2010 at 10:27:46
>>avr-gcc -mmcu=atmega128 -Wl,-Map=speichi.map speichi.o     -o speichi.elf
>>avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature
>>speichi.elf speichi.hex
>>avr-objdump -h -S speichi.elf > speichi.lss
>>
>>AVR Memory Usage
>>----------------
>>Device: atmega128
>>
>>Program:   32516 bytes (24.8% Full)
>>(.text + .data + .bootloader)
>>
>>Data:          0 bytes (0.0% Full)
>>(.data + .bss + .noinit)
>>
>>
>>Build succeeded with 0 Warnings...
(noch ohne es wie von Karl Heinz vorgeschlagen mit #include "daten.txt"
zu machen, die Idee ist aber super und das wird auf jeden Fall hinterher 
so gemacht!)


Wenn ich allerdings mehr Daten ins Array packe, z.B. 40kb, dann 
erscheint folgende Fehlermeldung:
Build started 31.8.2010 at 10:51:13
>>avr-gcc  -mmcu=atmega128 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char
>>-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT speichi.o
>>-MF dep/speichi.o.d  -c  ../speichi.c
>>../speichi.c:3240: error: size of array is too large
>>../speichi.c:3240: error: expected ',' or ';' at end of input
>>make: *** [speichi.o] Error 1
>>Build failed with 2 errors and 0 warnings...

Ich tippe darauf, dass der K(n)ack bei (32kb + 1b) liegt. Im Tutorial 
finde ich im Zusammenhang "Programmspeicher" nichts dazu (ja, 
reingeguckt).

Nebenbei fällt auf, dass der von mir benutzte Controller ein M644 ist, 
habe ich bei der Projektanlegung korrekt eingestellt und auch noch mal 
überprüft.
Nach dem Built wird aber "avr-gcc -mmcu=atmega128" angezeigt (s.o.). 
Weiß jemand, warum?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

> Ich tippe darauf, dass der K(n)ack bei (32kb + 1b) liegt. Im Tutorial
> finde ich im Zusammenhang "Programmspeicher" nichts dazu (ja,
> reingeguckt).

Das kann schon sein.
Wenn du deinen Mega mit Daten vollpumpst, wirst du auch in eventuell in 
dieses Problem laufen

Beitrag "pgm_read_byte(); --> Nur für Lower 64k Flash (mega128)???"


> Nebenbei fällt auf, dass der von mir benutzte Controller ein M644 ist,
> habe ich bei der Projektanlegung korrekt eingestellt und auch noch mal
> überprüft.
> Nach dem Built wird aber "avr-gcc -mmcu=atmega128" angezeigt (s.o.).
> Weiß jemand, warum?

Keine Ahnung.
Habs gerade bei mir ausprobiert:
Neues Projekt angelegt, C ausgewählt, Mega644 ausgewählt, compiliert.

Der Compiler wird vom AVR-Studio mit

avr-gcc.exe  -mmcu=atmega644 -Wall -gdwarf-2 -Os -std=gnu99 
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP 
-MT dffa.o -MF dep/dffa.o.d  -c  ../dffa.c

aufgerufen. Also alles korrekt.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, Danke für die Antwort! Ich habe grade parallel dazu folgende 
Zeilen verfaßt:




...so, das Problem mit dem "falschen" Prozessor ist jetzt behoben (unter 
"Configurations Optiones" noch mal von Hand eingestellt), der M644 wird 
nun nach dem Compilieren korrekt angezeigt.

Ein Blick auf "Memory Settings" unter "Configurations Optiones" zeigt, 
dass dort der M664 mit einem Flash Size von 0x8000 angegeben ist 
(32.768bytes).
Also kein Wunder, dass das 60kb große Daten-Array nicht passt.

Im Datenblatt findet sich oben die Beschreibung 8-Bit AVR 
microcontroller with 64k bytes flash und weiter unten unter AVR Memories 
"...the flash is organized as 32/64 x 16 ...", was bei mir den Verdacht 
aufwirft, dass der Flash Speicher in zwei Bereiche zu 32kb unterteilt 
ist.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>> Nebenbei fällt auf, dass der von mir benutzte Controller ein M644 ist,
>> habe ich bei der Projektanlegung korrekt eingestellt und auch noch mal
>> überprüft.
>> Nach dem Built wird aber "avr-gcc -mmcu=atmega128" angezeigt (s.o.).
>> Weiß jemand, warum?
>
> Keine Ahnung.
> Habs gerade bei mir ausprobiert:
> Neues Projekt angelegt, C ausgewählt, Mega644 ausgewählt, compiliert.

Hatte vielleicht mit der zu(?) großen Datenmenge zu tun, dass 
automatisch ein größerer Controllertyp eingestellt wurde!?!


>Wenn du deinen Mega mit Daten vollpumpst, wirst du auch in eventuell in
>dieses Problem laufen
>
>Beitrag "pgm_read_byte(); --> Nur für Lower 64k Flash (mega128)???"
Bei einem Speicher >64kb macht die Aufteilung natürlich Sinn, um die 
Speicheradressen handlich zu halten.
Aber beim 644 mit seinen grade mal 64kb wird das auch so gemacht? Gibt 
es da irgendwo im Tutorial einen Hinweis zu, den ich überlesen habe?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:

>> Keine Ahnung.
>> Habs gerade bei mir ausprobiert:
>> Neues Projekt angelegt, C ausgewählt, Mega644 ausgewählt, compiliert.
>
> Hatte vielleicht mit der zu(?) großen Datenmenge zu tun, dass
> automatisch ein größerer Controllertyp eingestellt wurde!?!

Nein.
Mit Sicherheit nicht.

>
> Aber beim 644 mit seinen grade mal 64kb wird das auch so gemacht? Gibt
> es da irgendwo im Tutorial einen Hinweis zu, den ich überlesen habe?

Nein.
Es wird vorausgesetzt, dass jemand der mit derartigen Boliden 
programmiert, weiß was er tut :-)

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Nein.
> Es wird vorausgesetzt, dass jemand der mit derartigen Boliden
> programmiert, weiß was er tut :-)

Na da hab ich mir ja was aufgeladen ;)

Wie würdest du denn (grob umrissen) die 60kb in den Boliden packen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:
> Karl heinz Buchegger schrieb:
>> Nein.
>> Es wird vorausgesetzt, dass jemand der mit derartigen Boliden
>> programmiert, weiß was er tut :-)
>
> Na da hab ich mir ja was aufgeladen ;)
>
> Wie würdest du denn (grob umrissen) die 60kb in den Boliden packen?

auf 2 oder 3 mal und hoffen das der Compiler schon weiß wie das geht :-)

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> auf 2 oder 3 mal und hoffen das der Compiler schon weiß wie das geht :-)

Na das ist doch eine Aussage ;-)

Ich bin dann mal testen (Internetrechner != Programmierrechner) ...

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, es ist genau, wie du gesagt hast, der Compiler weiß anscheinend, wie 
es geht.
:)

Habe die Daten in zwei große Stücke zerhackt und dann geht es.
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdint.h>

const uint8_t pgmDaten1[] PROGMEM = {
#include "dat1.txt"
};

const uint8_t pgmDaten2[] PROGMEM = {
#include "dat2.txt"
};

#define DATEN_SIZE1  ( sizeof(pgmDaten1) / sizeof(*pgmDaten1) )
#define DATEN_SIZE2  ( sizeof(pgmDaten2) / sizeof(*pgmDaten2) )

int main()
{
  uint16_t i;
  uint8_t value1;
  uint8_t value2;

  for( i = 0; i < DATEN_SIZE1; ++i )
  {
    value1 = pgm_read_byte( &pgmDaten1[i] );
    //value1 zum Verwursten

  }

 

    for( i = 0; i < DATEN_SIZE2; ++i )
  {
    value2 = pgm_read_byte( &pgmDaten2[i] );
    //value2 zum Verwursten

  }


  return 0;
}


Ich hoffe, man kann die Einsen und Zweien so an die Variablen anhängen, 
wie im Programm gezeigt, z.B. hier:
value1 = pgm_read_byte( &pgmDaten1[i]
                                 ^da


Wie viele Prozessortakte braucht der Controller eigentlich für diesen 
Befehl "value1 = pgm_read_byte( &pgmDaten1[i] );"?

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bertrand_H schrieb:
> Wenn ich allerdings mehr Daten ins Array packe, z.B. 40kb, dann
> erscheint folgende Fehlermeldung:
>
> Ich tippe darauf, dass der K(n)ack bei (32kb + 1b) liegt. Im Tutorial
> finde ich im Zusammenhang "Programmspeicher" nichts dazu (ja,
> reingeguckt).

Sollte daran liegen das der maximal Arrayindex in C INT_MAX - 1 ist. Das 
ist beim AVR dann 32767.

Matthias

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.