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]
:
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.
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.
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 | ... |
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
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.
Ein gewisser Vorteil könnte auch die Verwendbarkeit von y (sowie x, wenn auch ohne ldd) sein.
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.
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.
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.
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...
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.