Forum: Mikrocontroller und Digitale Elektronik ATtiny10 und <avr/pgmspace.h>: Program Space Utilities


von Bernd E. (berecke)


Lesenswert?

Musste gerade bitter feststellen, dass PROGMEM und pgm_read_byte nicht 
mit einem ATtiny10 zusammenarbeiten. Das Programm wird anstandslos 
compiliert, macht aber nicht was ihm vorgegeben wird. Vermutlich kann 
der "Kleine" kein LPM-Befehl. Ich hätte aber eine Fehlermeldung des 
Compilers erwartet, oder mache ich hier einen Denkfehler?
Ohne das PROGMEM-Geraffel läuft es so wie es soll.

von Sebastian R. (sebastian_r569)


Lesenswert?

Datenblatt sagt: Jap. Kein LPM.

von Bernd E. (berecke)


Lesenswert?

Nachtrag: Debuggen mit dem ICE geht auch nicht!

von egberto (Gast)


Lesenswert?

const __flash sollte funktionieren..

Grüße,

Egberto

von egberto (Gast)


Lesenswert?

Auch progmem soll eigentlich funktionieren, ggf. liegt das Problem wo 
anders?

Beispiel progmem mit ATTINY10

https://github.com/electronut/attiny10-rgb-hello/blob/master/attiny10-rgb-hello/main.c

Grüße,

Egberto

von Bernd E. (berecke)


Lesenswert?

Folgende Änderung habe ich gemacht und damit läuft es. Keine Ahnung 
warum. Daten stehen im Flash und werden ins SRAM kopiert. Vermutlich 
sitzt das Problem vor dem Bildschirm ;-) Mit _flash habe ich das nicht 
hinbekommen.

Auszug:
1
// colors
2
const unsigned char nColors = 5;
3
// cyan, magenta, orange, purple, yellow
4
const unsigned char red[]   PROGMEM  = {  0, 255,  255, 127, 255};
5
const unsigned char green[] PROGMEM  = {255,   0,  127,   0, 255};
6
const unsigned char blue[]  PROGMEM  = {255, 255,    0, 127,   0};
7
volatile unsigned char rgb[] = {255, 255, 255};
8
9
...
10
11
// set initial RGB value
12
//  rgb[0] = pgm_read_byte(&red[colorIndex]);
13
//  rgb[1] = pgm_read_byte(&green[colorIndex]);
14
//  rgb[2] = pgm_read_byte(&blue[colorIndex]);
15
  rgb[0] = red[colorIndex];
16
  rgb[1] = green[colorIndex];
17
  rgb[2] = blue[colorIndex];

von Falk B. (falk)


Lesenswert?

Bernd E. schrieb:
> Musste gerade bitter feststellen, dass PROGMEM und pgm_read_byte nicht
> mit einem ATtiny10 zusammenarbeiten.

Wird der überhaupt vom avr gcc unterstützt? Der hat gerade mal 32 Bytes 
SRAM.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bernd E. schrieb:
> Musste gerade bitter feststellen, dass PROGMEM und pgm_read_byte nicht
> mit einem ATtiny10 zusammenarbeiten.

pgm_read_xxx funktioniert nicht auf einem avrtiny, und progmem 
funktioniert anders:  Es kommt zu (extern) Deklarationen (während es 
üblicherweise bei Definitionen steht), und zum Lesen ist kein 
pgm_read_xxx erforderlich (ab GCC v7) bzw. sogar falsch:

http://gcc.gnu.org/gcc-7/changes.html#avr

pgm_read sollte ein Fehler vom Assembler geben:

Error: illegal opcode [e]lpm for mcu avrtiny

und __flash einen Fehler vom Compiler (ebenfalls ab GCC v7):

error: address spaces are not supported for reduced Tiny devices

Aber egal, avrtiny hat ein lineares Speichermodell, und Binutils bildet 
dies auch im Linkerskript ab: .rodata wird nicht mehr ins RAM lokatiert, 
und 0x4000 wird per Linkerskript addiert (für daten in .rodata) und 
nicht durch den Compiler (für Daten in .progmem) (Binutils v2.28).

https://sourceware.org/PR20849

Falls ältere Binutils verwendet werden, kann man einfach ein eigenes 
Linkerskript verwenden, das die Linearisierung ausnutzt, siehe dazu die 
Änderungen im o.g. PR.

Ergo: Auf avrtiny kann man ohne Performance-Verlust auf progmem und 
__flash verzichten, gleiches gilt für die neueren avrxmega3 wie 
ATtiny3216 oder ATxmega3209, die ebenfalls ein lineares Speichermodell 
haben (zumindest an der für die Tools sichtbaren Oberfläche).

von Bernd E. (berecke)


Lesenswert?

Das PROGMEM macht hier irgendwie kein Sinn.

Speicher ohne PROGMEM:
Program Memory Usage :  534 bytes   52,1 % Full
Data Memory Usage :  10 bytes   31,3 % Full

und mit PROGMEM:
Program Memory Usage :  550 bytes   53,7 % Full
Data Memory Usage :  10 bytes   31,3 % Full

von Bernd E. (berecke)


Lesenswert?

Johann L. schrieb:
> pgm_read_xxx funktioniert nicht auf einem avrtiny, und progmem
> funktioniert anders:  Es kommt zu (extern) Deklarationen (während es
> üblicherweise bei Definitionen steht), und zum Lesen ist kein
> pgm_read_xxx erforderlich (ab GCC v7) bzw. sogar falsch:

Danke für die ausführliche Antwort. Ich verwende das AtmelStudio 7. 
Leider kommt bei der Verwendung von pgm_read_byte hier keine 
Fehlermeldung. Na da habe ich wieder etwas dazu gelernt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Wird der überhaupt vom avr gcc unterstützt? Der hat gerade mal 32 Bytes
> SRAM.

Ja. Wie sinnvoll das ist, steht natürlich auf einem anderen Blatt...

Wesentliche Unterschiede:

* Kein __flash, und progmem funktioniert anders, siehe oben.

* Codegenerierung ist nicht wirklich gut, insbesondere wegen der 
reduzierten ISA: Kein LDD / STD (!!!), kein ADIW / SBIW, nur 16 GPRs, LD 
/ ST ist eine 1-Word Instruktion, d.h. kann nicht mehr den ganzen 
RAM-Adressbereich abdecken.

* Die reduzierten LD / ST führen dazu, dass der Speicher nicht mehr 
direkt adressiert werden kann, weil der Compiler die Adressen nicht 
kennt, d.h. zu Compilezeit ist nicht bekannt, ob eine Variable im RAM 
per LD / ST erreichbar ist.  Dazu gibt es eine neue Option -mabsdata 
(Assertion ist dann, dass alle Daten im RAM absolut adressierbar sind) 
und ein neues Attribut absdata für einzelne Objekte.  Hier hat der 
Anwender sicherzustellen, dass die Assertion wirklich erfüllt ist, etwa 
per Linkerskript.  Und Daten im Flash sind eh nur indirekt lesbar (wegen 
des 0x4000 Offsets), also ähnlich wie bei LPM ausschließlich indirekt 
zugreifbar.  Außer ATtiny40 haben alle RAM <= 0x80 Bytes, d.h. -mabsdata 
ist immer erfüllt (wird aber im specs-attiny* nicht automatisch gesetzt, 
weil der Compiler die RAM-Größen nicht kennt).

* Viele Lib-Routinen sind nicht für avrtiny verfügbar, i.d.R. solche, 
die eine Übergabe der Argumente per Stack erfordern würden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.