Hallo Leute ich habe folgendes Problem.
Ich habe eine Applikation für den LPC2148 geschrieben. Im Debugmodus (
Programm im RAM ) funktioniert alles ohne Probleme. Wenn ich das
Programm ins Flash schreibe, wird die Applikation nicht mehr richtig
ausgeführt, da ständig Interrupts anliegen. Ich habe den LPC mit 60 MHz
am laufen und einen 1 µs TimerInterrupt um meine Appl. Zeitgesteuert
ablaufen zu lassen.
Ich habe natürlich den MAM schon ausprobiert, aber trozdem funktioniert
es nicht. Hat von euch noch jmd eine Lösung ?
Andreas wrote:
> ausgeführt, da ständig Interrupts anliegen. Ich habe den LPC mit 60 MHz> am laufen und einen 1 µs TimerInterrupt um meine Appl. Zeitgesteuert> ablaufen zu lassen.
Lächerliche 60 Zyklen Interruptrate, vergiß es.
Für nen RISC sind 60 Zyklen nur Pinats.
Außerdem macht er erstmal noch ne Menge Getöse bein Betreten und
Verlassen des Interrupts.
Je nachdem, wieviel der Timerinterrupt machen muß, solltest Du nicht
unter 1000 Zyklen gehen, damit das Main und andere Interrupts auch noch
etwas CPU-Zeit abkriegen.
Peter
Andreas wrote:
> ausgeführt, da ständig Interrupts anliegen. Ich habe den LPC mit 60 MHz> am laufen und einen 1 µs TimerInterrupt um meine Appl. Zeitgesteuert> ablaufen zu lassen.
Entweder Timer-Interrupt mit zur Geschwindigkeit des Controllers
passender Rate laufen lassen, oder einen Controller mit zur Timer-Rate
passenden Taktfrequenz verwenden. Alle 60 Takte, also ein Interrupt pro
ungefähr 30 Befehle, ist jedenfalls ziemlich krass.
Rechne mit einer Grössenordnung von 50-150 Takten für einen Interrupt.
ok.... das hab ich mir auch schon gedacht, denn wenn ich die Zeit des
Int nur ein klein wenig größer mache funzt es, meine Arbeitskollegen
meinen das muss funktionieren. Ich brauche auch die kleine Auflösung.
Andreas wrote:
> ok.... das hab ich mir auch schon gedacht, denn wenn ich die Zeit des> Int nur ein klein wenig größer mache funzt es, meine Arbeitskollegen> meinen das muss funktionieren. Ich brauche auch die kleine Auflösung.
Wollen deine Kollegen dich loswerden?
Für solche Raten: für's Zeitkritische den FIQ in Assembler verwenden. In
C dürfte sich alles unter 5-10µs über kurz oder lang rächen.
Und lege den Interrupt-Handler ins RAM. Das ist nun einmal schneller.
Wie kann ich definieren dass der Interrupt Handler im Ram liegt, und wie
funktioniert das mit dem FIQ, gibts da auch ne Liste wo ich die Adressen
der Interrupts eintragen kann ?
Klingt nach vollständiger und bedingungsloser Ahnungslosigkeit über ARM
und deren Interrupts. Sorry, das hier runterzudeklinieren artet mir zu
sehr in Arbeit aus.
Wie man Code in RAM verfrachtet obwohl sonst im ROM gearbeitet wird, das
verrät möglicherweise das Handbuch des Compilers deines Vertrauens.
Wie man einen FIQ Interrupt schreibt, das verrät hoffentlich das
Handbuch des Compilers deines Vertrauens. Und was ein FIQ ist, verrät
ein ARM Handbuch.
Und wo die Interrupt-Vektoren stehen, das verrät das Handbuch (a) von
ARM und (b) vom verwendeten Controller (bei normalen vektorierten IRQs).
Also, wie Du ja schon gemerkt hast, habe ich vorher nie was mit Arm
gemacht, nur mit Atmel, NEC, und TriCore, womöglich habe ich noch einen
oder zwei Typen vergessen. Ich arbeite aber bereits seit 2 Jahren im
Bereich Embedded Hard und Software, deshalb bin ich nicht ganz
Ahnungslos ;-) . Du solltest ja auch nicht alles runterdeklarieren,
sondern eher ein paar Stichworte in den Raum werfen. Ich brauch niemand
der mir meine Arbeit macht, nur jemand der mir hilft wenn er das will
;-)
Ich muss sagen meine Kristallkugel funktioniert ganz gut, ich hab
rausgefunden wie der FIQ funzt, was pro Int ein Bit setzen heisst. Und
wie ich die INTRoutine ins Ram bekomm hab ich auch gefunden. ----> hilft
aber nix.
Wenn du mit dem GCC arbeitest, kannst du das verlagern ins RAM mit
"__attribute__ ((section(.ram)))" machen, wobei "ram" natuerlich ersetzt
werden muss mit deinem namen fuers RAM aus dem Linker.
Andreas wrote:
> ok.... das hab ich mir auch schon gedacht, denn wenn ich die Zeit des> Int nur ein klein wenig größer mache funzt es, meine Arbeitskollegen> meinen das muss funktionieren.
Die ARM haben einen entscheidendeen Unterschied zu vielen anderen MCs,
nach nem Interrupt kann sofort wieder ein Interrupt ausgeführt werden!
D.h. kommen die Interrupts zu oft, wird das Main nicht langsamer,
sondern steht total.
Daher ist es extrem wichtig beim ARM, daß immer reichlich Zeit zwischen
2 Interrupts ist.
Ich stimme daher A. K. zu, vergiß alles kleiner 5-10µs.
> Ich brauche auch die kleine Auflösung.
Was willst Du mit ner kleinen Auflösung, wenn Du keine Zeit hast, damit
zu rechnen?
Ein Interrupt, der nur die 1µs hochzählt, ist ziemlich nutzlos.
Peter
Da fehlt mir was!?
Im Debug von RAM tuts, wenn die Routine aber normal im RAM liegt bei
Ausfuehrung tuts nicht!?
Uebrigens, eine Ausfuehrung aus dem RAM ist nur ca. 5-10% schneller als
vom Flash, vorausgesetzt das MAM ist richtig initialisiert.
Nur zum Spass, nicht fuer die Serie geeignet, dreh doch mal die PLL von
Faktor 5 auf Faktor 6, dann laeuft der Chip mit 72 MHz, sollte er
normalerweisse tun, wenn er nicht gerade in einer heissen Umgebung
sitzt. Falls es dann tut, koennten ASM Optimierungen helfen.
Soweit habe ich versucht zu helfen, jetzt kommen die echten Fragen.
Was um alles in der Welt soll mit einer Taktrate von 1MHz abgefragt
werden? Wenn da tatsaechlich Daten kommen, wer soll sich wann darum
kuemmern was da kam? Also mein Vorschlag bei einer solchen Frequenz
waere Timer-unterstuetzes Polling. Gar nicht in einen Interrupt gehen,
der Micro kann sowieso nichts anderes mehr tun, sondern das
Interrupt-Flag des Timers Pollen und jeweils die Abfrage dann einleiten,
das nimmt den Interrupt Overhead beinahe komplett raus.
Nur so eine Idee!
Robert
p.s. So schicke Interrupts wie beim TriCore wirst Du sonst nirgends auf
irgendwelchen Micros finden. Hat ein Freund von mir designed ;-)
Robert Teufel wrote:
> p.s. So schicke Interrupts wie beim TriCore wirst Du sonst nirgends auf> irgendwelchen Micros finden. Hat ein Freund von mir designed ;-)
Schon mal beim Parallax Propeller reingesehen? Einfach einen der 8 Cores
derart zeitkritische Dinge pollen lassen. Da ist auch eine Zeitauflösung
unterhalb 1µs drin, und zwar deterministisch.
Erstmal genau schauen, ob MAM und alle Zeiteinstellungen/Takte
tatsächlich auch 'schnellstmöglich' eingestellt sind. Das MAM hilft -
sofern richtig in Erinnerung - nur dabei ein paar Speicherworte
vorauszuschauen und diese schnell bereitzustellen, bei Sprüngen
"querbeet" im Flash also nicht das Allheilmittel.
Wenn die Anwendung 'im RAM' läuft aber 'im Flash' nicht
zufriedenstellend, sind die Chancen nicht so schlecht, dass man die
Software so anpassen kann, dass sie aus dem Flash startet aber nur Teile
des Programmcodes 'aus dem Flash' ausgeführt werden. Hinweis betr.
'Auslagerung' zeitkritischer Routinen ins RAM wurde ja schon gegeben.
Wenn es tatsächlich nur der Timer-Interrupt und dessen Behandlung ist
und nicht auch der Rest der Anwendung 'bremst', kann man für die
Interruptbehandlung eine zur 'RAM-Debug-Konfiguration' vergleichbare
Einstellung nachbilden. Beim Start:
- Exception-Vector-Table ins RAM kopieren
- Interrupt-Handler ins RAM kopieren
- Remap aktivieren
Da schon auf FIQ "umgestellt": den FIQ-Handler kann man direkt hinter
den Vector-Table schreiben und spart sich evtl. noch einen Sprung.
Evtl. müssen noch weitere Teile der Anwendung ins RAM ausgelagert
werden, falls nicht nur der Interrupt und dessen Behandlung bremst.
Wie das alles konkret funktioniert? Vgl. Beitrag von A.K. 9:48.
@ A.K. (off topic)
Ich kenne den Propeller nicht, allerdings hat der TriCore auch einen
zusaetzlichen Prozessor drauf, der zeitkritische Transfers erledigt, in
Echtzeit, single cycle bei Geschwindigkeiten > 100 MHz, ein RISC mit
hochspezialisierten Befehlen.
Die TriCore Architektur ist toll aber fuer sehr viele Dinge etwas
kompliziert. Da geht es mir aehlich wie die ewige AVR <-> ARM
Diskussion. TriCore deutlich performanter als ARM7 ARM9 M3 ABER auch
deutlich komplexer. Also wer tolle Interrupt Performance zusammen mit
Timern braucht, die eines Programmierers (Alb)Traum sein koennen, dann
TriCore.
Der Abschuss belibt fuer mich immer noch der Timer-Block mit bis zu 96
Timern und ca. 200 Seiten im Manual ;-) Fuer manche ein Traum, fuer
andere schlafraubend.
Robert
>Der Abschuss belibt fuer mich immer noch der Timer-Block mit>bis zu 96 Timern und ca. 200 Seiten im Manual ;-) Fuer manche>ein Traum, fuer andere schlafraubend.
Ach, das erinnert mich doch wieder an die schönen Zeiten mit der
Programmierung der Motorola TPU, das war auch so ein komplexes Teil...
Hallo Leute.... das erste Problem ist ja schon ne Zeit behoben.... aber
jetzt tauch ab und zu ein neues auf der Abort_Handler ???? Im Dateblatt
hab ich dazu nicht viel gefunden ausser das es einen DataAbortHandler
und einen PrefetchAbortHandler. Wie kann ich rausfinden warum der
Zuschlägt, bzw. wie kann ich das Problem umgehen ?
Andreas wrote:
> Hallo Leute.... das erste Problem ist ja schon ne Zeit behoben.... aber> jetzt tauch ab und zu ein neues auf der Abort_Handler ???? Im Dateblatt> hab ich dazu nicht viel gefunden ausser das es einen DataAbortHandler> und einen PrefetchAbortHandler. Wie kann ich rausfinden warum der> Zuschlägt, bzw. wie kann ich das Problem umgehen ?
Hier gibt's einen längeren Artikel der das erklärt (Testobjekt: LPC2148)
http://www.embedded.com/shared/printableArticle.jhtml?articleID=192202641
Hallo Andreas,
der DataAbortHandler wird dann aufgerufen, wenn ,wie im Datenblatt
beschrieben, man einen Zugriff auf einen "verbotenen" Speicherbereich
durchführt.
Das bedeutet:
Wenn der Aborthandler nur "ab und zu" auftritt, haben wir eine Funktion
die wir nur "ab ud zu" aufrufen, in der der böse Zugriff erfolgt, oder
wir haben ein Zeigerproblem, bei dem die Adressberechnung nur "ab und
zu" danebengeht.
> ...., bzw. wie kann ich das Problem umgehen ?
- keine Zeiger
- keine Fehler bei der Zeigerberechnung
- intensiver Blick auf den Quellcode, unter Zuhilfenahme eines
Kommilitonen (die sehen meist den abgestorbenen Baum im Wald)
- NXP kontaktieren und eine Änderung im Silizium anmahnen, damit alles
was vor der Exception passiert ist, in einem Zwischenspeicher abgelegt
wird (das würde uns allen helfen)
Um was gehts eigentlich in der Aufgabe? Warum muss man denn einen 1us
Interrupt bedienen?