Gestern ist mir aufgefallen, dass auf dem Trinket M0 eine APA102 LED mit
drauf ist, da ich mit so einem Ding sowieso rumspielen wollte, war das
die Gelegenheit das Trinket M0 mal auszupacken. :-)
Da das Board aber keinen SWD Stecker hat (nur zwei Lötpads),
habe ich etwas im Arduino Framework rumgespielt mit Hilfe von vscode und
PlatformIO.
Der Projekt-Ordner ist durch das PlatformIO etwas aufgebläht, daher
hängt nur die .ino mit an.
Und tolle Dinger diese APA102, der SPI läuft hier gerade so mit 24MHz
vor sich hin.
Als natives Projekt würde der Code um die APA102 LED zu beschreiben
nicht anders aussehen.
Dazu kommen würde noch den Core-Takt auf 48MHz zu stellen und vielleicht
den Systick Timer einzurichten um das Test-Blinken nicht per delay() zu
machen.
Zum Zitieren hänge ich die paar Zeilen auch direkt mit in den Text.
- Was ist jetzt die Frage dazu?
Keine konkrete dazu.
Aber hast Du vielleicht noch mehr solche Beispiele?
Wie könnte man das um DMA erweitern?
- Warum ist das dann nicht unter "Projekte & Code"?
Das ist jetzt als Projekt für sich so etwas dünn und die Idee ist
eigentlich noch mehr solche Schnipsel einzusammeln.
Die Beispiele für ATSAM ohne ASF sind etwas dünn gesäht...
Wenn ein Mod da jetzt anderer Meinung ist, bitte verschieben.
1
#include "sam.h"
2
3
void init_spi(void)
4
{
5
/* configure SERCOM1 MOSI on PA00 and SERCOM1 SCK on PA01 */
6
REG_PORT_WRCONFIG0 =
7
PORT_WRCONFIG_WRPINCFG |
8
PORT_WRCONFIG_WRPMUX |
9
PORT_WRCONFIG_PMUX(3) | /* SERCOM1 */
10
PORT_WRCONFIG_DRVSTR |
11
PORT_WRCONFIG_PINMASK(0x03) | /* PA00 + PA01 */
12
PORT_WRCONFIG_PMUXEN;
13
14
REG_PM_APBCMASK |= PM_APBCMASK_SERCOM1;
15
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID_SERCOM1_CORE; /* setup SERCOM1 to use GLCK0 -> 48MHz */
Das Interesse ist zwar offenbar recht dünn, aber da ich praktisch keine
Beispiele im Netz finden konnte wie man bei den ATSAM den DMA benutzt,
hängt hier mal mein Test-Projekt dazu an.
Das ist immer noch im Arduino Framework, als PlatformIO Projekt.
Bis auf delay() wird allerdings keine Arduino Funktion verwendet und
auch keine Library vorausgesetzt, die eigentliche Funktion wird durch
direktes Beschreiben der Register erreicht.
Das Adafruit Trinket M0 hat eine APA102 LED verbaut, das macht es für
diese Spielerei perfekt.
Wenn da ein SWD Header dran wäre, dann hätte ich ein Atmel Studio
Projekt erstellt.
Die Funktionen init_spi(), init_dma() und apa_dma_write() würden dann
allerdings exakt genau so aussehen.
Ich hatte zwei wesentliche Probleme mit dem DMA.
Das erste war das mir zunächst nicht klar war, wie man einen Transfer
überhaupt anschiebt.
Mit dem Trigger auf SERCOM1 TX sah es für mich zunächst so aus, als
könnte ich den ersten Transfer nicht auslösen.
Der Transfer geht allerdings los wenn man im CHCTRLA Register das ENABLE
bit setzt.
Das zweite war die Quell-Adresse.
Ich bin einfach blind davon ausgegangen, dass die Quell- und die
Ziel-Adresse die Anfangs-Adressen sind von denen aus der DMAC weiter
zählt.
Es sind aber die Adressen an denen der DMAC ankommen soll wenn der
Transfer durch ist - aus welchem Grund auch immer.
"Bits 31:0 – SRCADDR[31:0] Transfer Source Address
This bit group holds the source address corresponding to the last beat
transfer address in the block
transfer."
"Bits 31:0 – DSTADDR[31:0] Transfer Destination Address
This bit group holds the destination address corresponding to the last
beat transfer address in the block
transfer."
In dem Fall Speicher zu Peripherie wird die Quell-Adresse hochgezählt,
die Ziel-Adresse aber nicht.
Nach der Beschreibung würde ich allerdings die Adresse des letzten
Elementes in einem Array angeben und nicht etwa die erste Adresse hinter
dem Array.
Hier noch direkt die schlapp 90 Zeilen zum Zitieren um Fehler
aufzuzeigen oder Fragen zu stellen:
Hier mal ein kleines Beispiel als AS7 Projekt, so ohne AFS.
Ich bin gerade dabei eine Platine mit einem ATSAME51J19A in Betrieb zu
nehmen.
Das lässt sich so aber auch direkt auf den D51 übertragen.
Das sind übrigens Cortex M4F mit 120MHz.
Ich habe einen 16MHz Quarz an XIN1 / XOUT1 angeschlossen, eine Debug-LED
an PA02.
Der wesentliche Teil in dem Projekt ist die init_clock() Funktion.
Der Quarz wird aktiviert, dann eine PLL konfiguriert und schliesslich
der Takt-Generator für den Core auf die PLL umgestellt.
Erwähnenswert ist, die verwendete DPLL0 benötigt einen Takt von 32kHz
bis 3,2MHz als Eingangs-Frequenz.
Es gibt aber einen Vor-Teiler im DPLLCTRLB Register mit dem ich die
16MHz erstmal auf 2MHz runter stelle.
Das ist erwähnenswert, weil das im Atmel-Start verbugt ist, der
Vor-Teiler wird einfach nicht berücksichtigt.
Beim C21 ist mir das auch schon aufgefallen, dort habe ich als ich
anfing mit den ATSAM zu spielen den Quarz-Takt erstmal durch eine GCLK
Unit geschickt um den runter zu teilen für die PLL - das geht auch im
Atmel-Start, ist nur komplett überflüssig.
Zusätzlich etwas lästig war, dass die Register-Namen im Datenblatt nicht
mit denen in den Includes übereinstimmen.
DPLL0CTRLB -> REG_OSCCTRL_DPLLCTRLB0
Wenn man das mit anderen Units vergleicht ist das Datenblatt fehlerhaft.
Hey,
ich benutze ebenfalls die ATSAMs ohne ASF, funktioniert soweit echt gut,
DMA ging auch einfach.
Ich hab allerdings ein anderes Problem, und zwar kann ich nicht von
einem EXTI ein Event zum Retriggern eines TC senden.
Wenn ich vom EXTI ein SW-Interrupt per Event auslöse, komme ich dort
hin, wenn ich das Event das zum Timer gehen soll per Software auslöse,
wird der Timer auch nicht neu getriggert.
Vielleicht hast du dazu ja eine Idee (bin unter GCC unter Linux)
Gruß,
Martin
Keinen Plan, ich kratze da noch an der Oberfläche und das wird auch noch
länger so bleiben, so hemmungslos vollgestopft wie die Dinger sind. :-)
Erstmal war ich froh, dass ich meinen "CAN-Treiber" praktisch ohne
Änderungen vom C21 übernehmen konnte.
Ich habe nur andere Pins und einen anderen Takt.
Jetzt versuche ich gerade den Bootloader zu portieren und habe erstmal
festgestellt, dass der NVMTRL sich doch ganz gut vom C21 unterscheidet.
Neben dem Systick-Timer habe ich gerade mal einen TC im C21 benutzt um
eine Laufzeit-Messung von zwei Funktionen zu machen.
Und zwischendurch hatte ich mal den ADC am C21 konfiguriert um das mal
auszuprobieren, da kam aber bedingt durch meine Platine nur Grütze raus.
Beim E51 bin ich mal gespannt, die A Revision hat noch genug Probleme
und einen Fädeldraht habe ich schon gezogen um VREFA mit VDDA zu
verbinden.
Am C21 bin ich auch noch dran zwei SERCOMs für LIN Master und Slave zu
benutzen, das funktioniert wenigstens so grundsätzlich. :-)
SERCOM als SPI über DMA habe ich dann auch benutzt um vom C21 aus ein
FT813 basiertes Display anzusteuern, ebenso in ersten Tests eines mit
einem BT815.
Eigentlich beschäftige ich mich überhaupt nur mit den Dingern weil die
iso CAN-FD können und als Bonus auch noch gerade Automotive zertifiziert
werden.
Für den E51 habe ich eigentlich noch gar keine Verwendung.
Martin K. schrieb:> Wenn ich vom EXTI ein SW-Interrupt per Event auslöse, komme ich dort> hin, wenn ich das Event das zum Timer gehen soll per Software auslöse,> wird der Timer auch nicht neu getriggert.
Ich bin bei den ATSAMD51 auch "Bare-Metal" unterwegs.
Ist schon viel Arbeit bis da mal was läuft aber wenn man das
Konzept und den CM4F (ARMv7-M Architektur) verstanden hat ist es auch
nicht schwerer wie ein AVR Xmega.
Vielleicht hilft dir das Code-Beispiel weiter.
TC3 (OVF) startet über einen Event den TC2.
TC User Events müssen nicht Synchron sein. (Auskommentierte Zeilen)
TC3->COUNT16.EVCTRL.bit.OVFEO = true;
TC2->COUNT8.CTRLBSET.bit.ONESHOT = true;
TC2->COUNT8.EVCTRL.bit.EVACT = TC_EVCTRL_EVACT_START_Val;
TC2->COUNT8.EVCTRL.bit.TCEI = true;
MCLK->APBBMASK.bit.EVSYS_ = true;
//GCLK->PCHCTRL[EVSYS_GCLK_ID_0].reg = GCLK_PCHCTRL_GEN(GEN_GCLK_192M)
| GCLK_PCHCTRL_CHEN;
EVSYS->Channel[0].CHANNEL.bit.EVGEN = EVSYS_ID_GEN_TC3_OVF;
EVSYS->Channel[0].CHANNEL.bit.PATH =
EVSYS_CHANNEL_PATH_ASYNCHRONOUS_Val;
//EVSYS->Channel[0].CHANNEL.bit.EDGSEL =
EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val;
EVSYS->USER[EVSYS_ID_USER_TC2_EVU].bit.CHANNEL = (0+1); // Channel + 1
Hallo zusammen,
ich hätte auch mal eine Frage zu Atsam ohne ASF. Hantiere aktuell mit
einem Same70 Xplained board rum. Bisher läuft es gut ohne Asf und nur
mit dem Sam DFP aber ich hänge gerade an dem verketten von zwei 16bit
Timern um eine 32bit 150ms timer zu erzeugen. Vieles konnte ich mir
durch Zerlegung der Asf Funktionen und dem Datenblatt gut herleiten,
aber bei 32Bit Timern war dies bisher nicht erfolgreich.
Vielleicht hat ja jemand eine gute Quelle oder kleines Beispiel.
Danke + Grüße
Mike schrieb:> aber bei 32Bit Timern war dies bisher nicht erfolgreich.
Zeig mal, was du schon hast.
Ich habe hier funktionierendes timer chaining, allerdings ist es
proprietärer Code, den ich jetzt nicht 1:1 posten kann. Ich könnte aber
deinen Implementierungsversuch gegen unseren Code vergleichen.
Hmm, ist der SAME70 wirklich so viel anders als der SAMC21?
Beim SAMC21 werden die Timer nämlich automatisch verkettet wenn man den
ersten eines Paares auf 32 Bit einstellt.
Das fängt ja auch schon damit an, dass man nicht jedem Timer einen
eigenen Takt zuweisen kann, sondern das die in Paaren zusammen gelegt
sind.
Rudolph R. schrieb:> Hmm, ist der SAME70 wirklich so viel anders als der SAMC21?
Ja, ist er. Er hat die Dinosaurier-Peripherie von SAM3/SAM4 geerbt.
Seltsam nur dass, obwohl designierter Nachfolger u.a. von SAM4E, dessen
32-bit-Timer nicht übernommen worden sind, sondern wieder die ollen
16bittigen von SAM4S. Aber Verketten von Timern war da trotzdem schon
immer vorgesehen.
SAMC/SAMD haben eine völlig andere Peripherie.
Rudolph R. schrieb:> SAMC21Jörg W. schrieb:> Mike schrieb:>> aber bei 32Bit Timern war dies bisher nicht erfolgreich.>> Zeig mal, was du schon hast.>> Ich habe hier funktionierendes timer chaining, allerdings ist es> proprietärer Code, den ich jetzt nicht 1:1 posten kann. Ich könnte aber> deinen Implementierungsversuch gegen unseren Code vergleichen.
Hi,
erstmal Danke für Eure Feedbacks. Aktuell habe ich noch nichts richtiges
was sinnvoll als Referenz vorzeigbar ist. Klemmt gerade auch noch an ein
paar anderen Ecken. Ich werde aber sobald es codetechnisch was gibt,
dass hier zur Diskussion/Zerfleischung posten :)
@Rudolph, das dachte ich mir nämlich auch, da es zu den MCUs ein paar
sinnvolle AppNotes bzgl. 32Bit Timern gibt, aber leider wie schon
erwähnt, sind die Timer beim e70 anders implementiert.
Grüße
Leider ist das, was Atmel da "Appnote" nennt, mittlerweile fast nur noch
etwas Dokumentation für ihre ASF-"Treiber" und nichts mehr, was einem
zeigt, wie man die Hardware tatsächlich benutzt.
Jörg W. schrieb:> Rudolph R. schrieb:>> Hmm, ist der SAME70 wirklich so viel anders als der SAMC21?>> Ja, ist er. Er hat die Dinosaurier-Peripherie von SAM3/SAM4 geerbt.
Danke, dann werde ich wohl erstmal nicht über den E51 mit seinem 120MHz
M4F hinaus gehen.
Jörg W. schrieb:> Leider ist das, was Atmel da "Appnote" nennt, mittlerweile fast nur noch> etwas Dokumentation für ihre ASF-"Treiber" und nichts mehr, was einem> zeigt, wie man die Hardware tatsächlich benutzt.
Oh ja, den CAN-Treiber für den C21/E51 zu schreiben war auch nicht ganz
lustig.
Zum Glück ist das ein Bosch M_CAN und Microchip damit nicht die einzige
Quelle für Dokumentation.
Was mich noch ein klein wenig stört, ich habe meine Warnings auf
-pedantic gesetzt.
Und beim Rebuild hagelt es erstmal einen Satz Warnungen für das
startup_samc21.c: "warning: ISO C forbids conversion of function pointer
to object pointer type"
Rudolph R. schrieb:> Und beim Rebuild hagelt es erstmal einen Satz Warnungen für das> startup_samc21.c: "warning: ISO C forbids conversion of function pointer> to object pointer type"
Pah. Sowas macht man ja auch nicht – wenngleich es beim ARM keine so
große Geige spielt.
Tja, so lief das zuletzt bei Atmel.
Und Microchip ist da auch nicht besser, dass die die Includes mit den
3.x Packs durch die Mangel gedreht haben - bin ich kein Fan von.
Naja...
Microchip supportet alle SAM auch nur halbherzig.
Auf Fragen nach Assembler bekommt man nur: This was the first question
of this kind and we don't support assembler.
Nice.
Dazu kommt, das viele Datasheets einfach fehlerhaft sind und man selbst
per try & error allies rausfinden muss.
Zur Zeit setzen wir atsamc21, atsaml21, atsame70 und atsams70 ein.
Alle in C und Assembler, weil C und c++ einfach zu wirren Code für
hartes Realtime erzeugen.
Klar kann man Initialisierungen mit C erschlagen, aber wenn es dann
drauf an kommt, nutzt man DMA, Events und Assembler um clocksynchron
arbeiten zu können.
Gern würde ich mich Mal mit anderen austauschen, die die prozis ebenso
benutzen....
Ingolf T. schrieb:> Gern würde ich mich Mal mit anderen austauschen, die die prozis ebenso> benutzen....
Wir benutzen sie (derzeit SAME70, früher SAM4E), aber zu Assembler haben
wir uns bislang noch nicht hinreißen lassen. :) Wir haben auch harte
Timings, aber die Synchronisation erfolgt dann immer mit Timern.
Prinzipiell ist der Assembler ja aber erstmal ein GNU Assembler, oder
was benutzt ihr?
Ja, halt der Gnu Assembler unter Ärmel Studio 7.
Aber der E70 hat 6 Waitstates im Flash...
Also muss man den Code im Ram laufen lassen.
Geht das unter C?
Im Assembler ja.
Mit Taktsynchron meine ich Mainclk synchron.
Im Flash kann ich auch keinen selbstmodifizierenden Code schreiben.
Braucht's aber manchmal. Zeit ist fast immer zu knapp ;-(
Ingolf T. schrieb:> Ja, halt der Gnu Assembler unter Ärmel Studio 7.
Sowas nimmt bei uns glaub' ich niemand. Ich nehme sowieso Emacs, die
Kollegen Eclipse oder inzwischen auch VScode.
> Aber der E70 hat 6 Waitstates im Flash...
Ja, aber auch Cache.
Für Full speed müsste man ohnehin TCM benutzen, machen wir bislang
nicht.
> Also muss man den Code im Ram laufen lassen.> Geht das unter C?
Warum sollte das denn nicht gehen? Das hat doch nichts mit der
Programmiersprache zu tun, sondern nur mit der Organisation der
Linkerscripts und des Startup-Codes (die leider bei ARM so ziemlich
jeder für sich selbst strickt).
Auch dein Assembler assembliert schließlich nicht direkt in den RAM …
> Mit Taktsynchron meine ich Mainclk synchron.
Brauchen wir nicht, unsere Synchronitätsanforderungen beziehen sich auf
die Peripherie.
> Im Flash kann ich auch keinen selbstmodifizierenden Code schreiben.
Sowas habe ich das letzte Mal beim Z80 gemacht / benötigt.
Klar, TCM ist Pflicht.
Den Code kann man nie für RAM compilieren, sondern muss den per Hand
kopieren.
Aber wenn man nur wenige us Zeit hat und einige Filter berechnen muss,
geht es nicht anders, trotz FPU.
OK, ich benutze auch Keil.
Eclipse ist mir zu aufgeblasen.
EMACs schau ich mir Mal an....
Aber so schlimm finde ich die GUI von Atmel gar nicht... ;-)
Ingolf T. schrieb:> Klar, TCM ist Pflicht.
Was mich an TCM stört ist, dass man den nur gleichermaßen auf Daten und
Befehle partitionieren kann. Mir würde es an manchen Stellen völlig
reichen, ihn für die Befehle zu verwenden – bei den Daten muss ich mir
dann sonst erst Konzepte ausdenken, was in dem TCM überhaupt liegt.
> Den Code kann man nie für RAM compilieren, sondern muss den per Hand> kopieren.
Die üblichen Kombinationen von startup/linker script haben dafür schon
Vorkehrungen, da muss man nichts manuell nachhelfen. Einfach die
Funktion als
1
__attribute__((section(".ramfunc")))
markieren (vielleicht gibt es auch einen besser lesbaren Alias dafür,
weiß ich gerade nicht), und sie wird automatisch beim Start kopiert.
> Eclipse ist mir zu aufgeblasen.
Das sind doch aber alle diese großen IDEs, Atmel Studio ist da nicht
anders.
> EMACs schau ich mir Mal an....
Lieber nicht. :) Ist 'ne ganz andere Philosophie. Da muss man
reinwachsen.
Ich mach das aber schon seit mehr als 25 Jahren, und musste seitdem
praktisch meine Gewohnheiten nicht ändern – obwohl sich meine
Aufgabenfelder massiv geändert haben.
Nun, ich programmiere seit 1983 in Assembler oder Maschinencode
(damals). Erst 4bit, dann 8bit, heute 32bit 8 cores (propeller) oder
Arm.
Meist Controller für komplizierteste Regelalgorithmen.
Die Umgebungen sind mir relativ egal, Propeller hat nur Simulator, Debug
so gut wie unmöglich.
Arm ist ganz gut, Dank Segger auch recht gut debugbar.
Was bei ATSam doof ist, man muss alles selber rausfinden.
Bei Microchip als Firma kann ich auch urgent cases öffnen, aber meist
erkläre ich dann dem Support-Mitarbeiter wie es funktioniert.
Manchmal ist der Support auch gut. Zum Beispiel als ich eine Exel Liste
der Pinbelegung wollte, um das Layout schneller zu machen ;-)
Aber es tauchen immer wieder Unstimmigkeiten auf.
Aber des gibt kaum Leute, die die CPUs so richtig nutzen....
Ich habe mir eine Mini-HAL geschrieben - im Anhang (mit Doxygen-Doku)
Das mit der DMA ist so komplex, dass die Routinen eine große
Erleichterung sind. Wichtig ist jedoch, dass man das mit den
Descriptoren verstanden hat.
Ingolf T. schrieb:> Bei Microchip als Firma kann ich auch urgent cases öffnen, aber meist> erkläre ich dann dem Support-Mitarbeiter wie es funktioniert.
First-level support hatte Atmel schon vor Jahren nach Indien
ausgelagert, in der Hoffnung, dass man mit sowas die Aktionäre glücklich
macht.
Der indische Support-Mitarbeiter wird danach bewertet, wie schnell er
die Cases abarbeiten kann. Wenn du wirklich einen Bug findest, dann
musst du ihm folglich so klar wie möglich machen, dass das nicht seine
Schuld ist und er es nur „nach oben“ weiterreichen darf – dann hat er
seinen Anteil am Case getan, und danach geht die Sache zu den
tatsächlichen Chip-Designern in Frankreich oder Norwegen.
Nichts gegen die Inder als solches: aber sie sind einfach räumlich und
logistisch viel zu weit weg von den Entwicklern.
> Nun, ich programmiere seit 1983 in Assembler oder Maschinencode> (damals)
Maschinencode habe ich nur ganz wenig machen müssen, Assembler damals
schon, aber ich war heilfroh, dass man auf CP/M größere Projekte in
Turbo-Pascal bauen konnte. Mein EPROM-Programmer wäre in Assembler
wahrscheinlich ein Mannjahr gewesen, bei schlechterem Featureset. In
Pascal musste man nur, nachdem erstmal alles geht, die innere Schleife
hernach in Assembler umschreiben, danach war das Programm gut und
schnell, und es hat weniger als einen Mannmonat gekostet.
Ich kann den ARM-Assemblercode lesen, bin aber froh drüber, das nicht
selbst schreiben und vor allem pflegen zu müssen.
Das der loader (*flash.ld) eine funktion relocaten kann, ist klar.
Aber der thumb Befehlssatz ist wirklich sehr optimiert und weil es zum
Beispiel keinen Befehl gibt, ein Register mit einem 32bit Direktwert zu
laden, und die meisten bedingten Sprünge nur short gehen, muss der Code
sehr optimiert geschrieben werden und man muss wissen, wo Daten liegen
und auch Springtabellen anlegen etc. Jeder unnötige Befehl ist ein Takt
zuviel.
Weil wir gerade bei __attribute( sind, wo gibt es denn eine Liste aller
möglichen Attribute? Bei gnu-Assembler gibts einige erklärt, aber nicht
alle.
Bei ARM gibt es auch gute Doku, leider finde ich auch dort nicht alles.
Kann aber auch daran liegen, das ich es einfach nicht finde. Problem ist
immer, etwas zu suchen, von dem man nicht weiß, wie es heißt. Und wenn
ich weiß, wie es heißt, brauche ich es nicht mehr zu suchen :-)
Was mir fehlt ist ein gutes Tutorial zum Assembler und Debugger.
Teilweise ist es nicht möglich, einen Breakpoint hinter ein Label zu
setzen. Warum das so ist, habe ich noch nicht herausgefunden. Mal klappt
es, mal nicht. Hängt scheinbar vom Allignment ab.
Ebenso sind die Prozessoren innerhalb einer Serie (ATSAMC21, D21, L21)
teilweise extrem verschieden. Das geht mit der PLL los und endet bei der
DMA, die z.B. beim L-Typ die Deskriptoren im LPRAM braucht.
Dazu kommt, das man bei Microchip die Doku scheinbar "global" hält. Z.B.
ob ein TCC nun 2 oder 4 CC-egister hat, merkt man erst bei einem
Hardfault() :-)
Im Handbuch steht halt nur "..bis zu 4 CC[]".
Und wenn man den ersten Prototyp baut, muss man sich für ein Pinout
entscheiden, da man den Prozessoren keine Pinmatrix geschenkt hat. Das
Aussuchen der Pins ist extrem aufwändig und Fehlerbehaftet. Eigentlich
weiß man erst, wenn man den Code fertig hat, welche Pins man benutzen
kann. Dann muss man eh den Prototyp noch mal routen :-)
Schön wäre es, wenn man wirklich mal ein Board "sticky" machen könnte,
und jeder schreibt seine erkannten Anomalien bzw. Tricks rein, damit man
nicht immer stundenlang suchen muss.
Das Programmieren des eigentlichen Problems geht am schnellsten. Am
längsten dauert es jedesmal, herauszufinden was nun wieder anders ist...
Ingolf T. schrieb:> Jeder unnötige Befehl ist ein Takt zuviel.
Bist du sicher, dass du nicht irgendwelchen Gespenstern hinterherjagst?
Weil:
> Was mir fehlt ist ein gutes Tutorial zum Assembler und Debugger.
In den meisten Anwendungen besteht keine Notwendigkeit, Assembler zu
verwenden - für das gesamte Projekt schon garnicht. Mikrooptimierungen
kann der Compiler in aller Regel besser und zuverlässiger durchführen
als der Mensch, wenn das Problem nicht äußerst scharf abgegrenzt ist.
Und selbst, wenn es dir wirklich auf die Takte ankommt, weil du in
Echtzeit einem VGA-Signal hinterherlaufen willst - warum nimmst du dann
nicht einfach den nächstschnelleren Prozessor?
Davon abgesehen... ja, ich habe einen SAM3X auch bare-metal programmiert
- an der Universität, nicht für die Realität. Bis auf absolute Ausnahmen
sehe ich darin keinen Nutzen.
Ingolf T. schrieb:> Bei gnu-Assembler gibts einige erklärt, aber nicht alle.
Der Quelltext deiner speziellen Version sollte die Eigenheiten alle
kennen. Ansonsten halte ich mich eher an die Dokumentation zu GCC und
LD, wo einige Dinge auftauchen.
Ingolf T. schrieb:> Bei ARM gibt es auch gute Doku, leider finde ich auch dort nicht alles.
Meiner Erinnerung nach findet sich bei ARM hauptsächlich Dokumentation
zur ARM-Toolchain, die sich in den Feinheiten deutlich von der GNU-Welt
unterscheidet.
> Bist du sicher, dass du nicht irgendwelchen Gespenstern hinterherjagst?> Und selbst, wenn es dir wirklich auf die Takte ankommt, weil du in> Echtzeit einem VGA-Signal hinterherlaufen willst - warum nimmst du dann> nicht einfach den nächstschnelleren Prozessor?
Weil es in der Serienfabrikation auch auf jeden Cent ankommt.
VGA wäre noch harmlos.
Oft hat man nur einige us Zeit und muss da viele Dinge berechnen. Im
Detail kann ich da nichts erzählen, wegen viel Geheimhaltungsklauseln
der Kunden.
Deswegen kann man in offenen Foren auch keine Hilfe erwarten. Und der
Support ist halt nicht sooo gut.
Ingolf T. schrieb:> Oft hat man nur einige us Zeit und muss da viele Dinge berechnen.
Es ist aber auch meine Erfahrung, dass gerade Rechnungen der Compiler
oft besser hinbekommt, als man sich das selbst im Assemblercode
abbrechen könnte – auch bei Mikrosekunden. Das Byte Flash kostet im
Allgemeinen sowieso viel weniger als die Ingenieursstunden, die man
aufwänden muss, um ebendieses Byte einzusparen.
So viel Magie ist ja an der Assemblerprogrammierung hier sowieso nicht
dran, zumal es ein typischer RISC-Prozessor ist.
Ingolf T. schrieb:> Weil es in der Serienfabrikation auch auf jeden Cent ankommt.
Naja, die meisten, die solche Fragen stellen, jagen Gespenstern
hinterher, deswegen frug ich nach.