Forum: Mikrocontroller und Digitale Elektronik FLASH im normalen Addressbereich AVR128DA


von Peter S. (cbscpe)


Lesenswert?

Ich arbeite mich jetzt gerade in die neue AVR128DA MCU Familie ein und 
habe dabei gesehen, dass ein Teil das Flash, nämlich die oberen 32kbyte, 
in den Adressraum der Daten gemapped ist. Das finde ich natürlich sehr 
praktisch habe aber noch nicht herausgefunden wie ich das im Assembler 
"konstruiere", d.h. wie verfahre ich mit den Labels und wie benutze ich 
sie dann im Assembler, bis jetzt ging das ja etwa so

[avrasm]
 .cseg

 ldi  zl, low(2*message)
 ldi  zh, high(2*message)
 ldi  r16, 1
 sts  rampz, r16
 elpm r0, Z
 ...

 .org 0xC000
message:
 .db "Hello World"

[avrasm]

:
von S. Landolt (Gast)


Lesenswert?

Es wird einer der vier 32 KiB-Blöcke des Flash gemapped, in 
NVMCTRL_CTRLB.FLMAP wird eingestellt, welcher.
Sollte jedoch ein Bootloader vorhanden sein, sind die Errata zu 
beachten.

von Jim M. (turboj)


Lesenswert?

Mit C wäre es einfacher: Für ".rodata" wird im Linker Skript eine neue 
Section angelegt, die entsprechende Adressen enthält. Damit entfällt der 
sonst übliche Kopfstand für String Konstanten im Flash.

In Assembler müsste man sinngemäß dasselbe tun, was aber IMO aufwändiger 
wäre als obige traditionelle Lösung, die weiterhin verfügbar bleibt.

Ich sehe in der offiziellen AVR Assembler Doku derzeit noch keine 
direkte unterstützung für "Flash im RAM-Segment" - weder CSEG, noch DSEG 
oder ESEG würden passen.

von S. Landolt (Gast)


Lesenswert?

an Peter S., Beispiel:
1
.org 0
2
    ldi     r16,NVMCTRL_FLMAP_SECTION0_gc
3
    sts     NVMCTRL_CTRLB,r16
4
    ldi     ZH,high(alpha*2 +$8000)
5
    ldi     ZL,low (alpha*2 +$8000)
6
    ld      r16,z
7
    rjmp    alpha_end
8
    
9
alpha:
10
.db "ao"
11
alpha_end:
12
    ...

von spess53 (Gast)


Lesenswert?

Hi

Geht doch ganz einfach:

[avrasm]
ldi r16,byte3(message*2)
out rampz, r16
ldi ZL,byte1(message*2)
ldi ZH,Byte2(message*2)
...

.org 0xC000
message:
 .db "abc"
[{avrasm]

MfG Spess

von c-hater (Gast)


Lesenswert?

spess53 schrieb:

> Geht doch ganz einfach:
[...]

Naja, klar geht das einfach, hat man ja schon immer so gemacht, seitdem 
es AVR mit mehr als 64k Flash gab.

Ist nur nicht das, was der TO wollte, er wollte das Mapping in den 
SRAM-Bereich benutzen. Für den Zugriff auf konstante Strings bringt das 
natürlich eher keinen Vorteil, der Code wird dadurch weder schneller 
noch kleiner. Dazu kommt noch der Mapping-Bug, der die Sache 
verkompliziert, so dass der Code tendenziell sogar größer und langsamer 
werden dürfte.

Die einzige derzeit sinnvolle Anwendung für das Mapping sehe ich beim 
Zugriff auf Arrays von konstante Strukturen mit bis zu 64 Byte Größe. Da 
läßt sich einiges beschleunigen, weil halt auf den gemappten Flash mit 
ldd zugegriffen werden kann, was deutlich fixer vonstatten geht als die 
beim lpm-Zugriff nötige manuelle Addition des Offsets zum Indexregister.

von S. Landolt (Gast)


Lesenswert?

Ein gewisser Vorteil könnte auch die Verwendbarkeit von y (sowie x, wenn 
auch ohne ldd) sein.

von Peter S. (cbscpe)


Lesenswert?

Genau, ich brauch das Mapping um auf verlinkte Strukturen zugreifen zu 
können. Z.Bsp. für den Command Line Parser. Im Moment ist das eher 
aufwändig, weil nur das Z register auf die verlinkten Informationen 
zugreifen kann und man keine Adressierung mit Offset und kein 
Autodecrement hat.

Danke für das Beispiel, das probiere ich gleich mal aus.

Ja leider bietet der avrasm2 überhaupt keine Unterstützung, es ist 
sowieso ein ziemlich einfach gehaltener Assembler. Aber damit muss man 
leben.

von Moby (Gast)


Lesenswert?

Peter S. schrieb:
> es ist
> sowieso ein ziemlich einfach gehaltener Assembler. Aber damit muss man
> leben.

Na Gott sei Dank würd ich mal sagen.
Zu einer einfachen Sprache gehören einfache Tools. Das schätze ich an 
Asm am meisten.

von c-hater (Gast)


Lesenswert?

Peter S. schrieb:

> Ja leider bietet der avrasm2 überhaupt keine Unterstützung, es ist
> sowieso ein ziemlich einfach gehaltener Assembler.

Er hat alles, was nötig ist, um die Unterstützung zu schaffen, nämlich 
recht ordentliche Macro-Fähigkeiten (auch wenn die in einigen Details 
deutlich verbesserungswürdig wären).
Wie auch immer: Mit einem Satz gut durchdachter Macros wird auch die 
Benutzung von gemapptem Flash zum Kinderspiel.

von c-hater (Gast)


Lesenswert?

S. Landolt schrieb:

> Ein gewisser Vorteil könnte auch die Verwendbarkeit von y (sowie x, wenn
> auch ohne ldd) sein.

Richtig. Je nach Problem kann auch dies noch einen deutlichen 
zusätzlichen Vorteil bedeuten. Auch die vom TO erwähnte zusätzliche 
Möglichkeit zum Prädecrement könnte gelegentlich durchaus sehr nützlich 
sein.

Haben wir also festgestellt, dass das Mapping insgesamt sehr nützlich 
sein könnte. Muss jetzt bloß noch MC seine Hausaufgaben machen und den 
Bug beseitigen...

Ich persönlich würde mich schämen, ernsthaft ein Hardware mit einem 
derartig gravierenden Bug auszuliefern. Aber das haben garantiert nicht 
Leute entschieden, die programmieren oder Hardware designen...

von AvrAsm (Gast)


Lesenswert?

Geht so: Daten im Flash ablegen (hier das voreingestellte Segment von 
96-128K) und Adresse im Datenbereich berechnen!

.org $c000

F_DATASTR:  .DB "STRING",$0a
.equ DATASTR    = (F_DATASTR*2)-$10000

Zugriff dann im gemappten Speicher

lds r16,DATASTR ;R16= erstes Zeichen S

oder analog

ldi ZL,low(DATASTR)
ldi ZH,high(DATASTR)
ld r16,Z+

c-hater schrieb:
> ernsthaft ein Hardware mit einem derartig gravierenden Bug auszuliefern

Der Fehler ist spätestens beim DB-Typen Geschichte.

Beitrag #6915441 wurde von einem Moderator gelöscht.
Beitrag #6916404 wurde von einem Moderator gelöscht.
Beitrag #6916483 wurde von einem Moderator gelöscht.
von Jimi H. (jimih)


Lesenswert?

AvrAsm schrieb:
> .equ DATASTR    = (F_DATASTR*2)-$10000

mit einfachen Makros gelöst
1
.macro ldx
2
        ldi     XL,low((@0*2)-$10000)
3
        ldi     XH,high((@0*2)-$10000)
4
.endmacro
5
6
.macro ldy
7
        ldi     YL,low((@0*2)-$10000)
8
        ldi     YH,high((@0*2)-$10000)
9
.endmacro
10
11
.macro ldz
12
        ldi     ZL,low((@0*2)-$10000)
13
        ldi     ZH,high((@0*2)-$10000)
14
.endmacro

Nun braucht man nur noch
1
ldx F_DATASTR

zum Laden der Flash-Adresse schreiben.
Allerdings hat AvrAsm's Variante den Vorteil daß man gleich direkt den 
Inhalt der gewünschten, gemappten Speicherzelle in ein beliebiges 
Register lädt. Man könnte ein solches zwar in den Makros ergänzen, wäre 
dann aber auf ein bestimmtes Register festgelegt.

: Bearbeitet durch User
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.