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 ;-)
Dann sollte dir eigentlich klar sein, dass dies ohne Kenntnis der Entwicklungsumgebung eine einwandfrei funktionierende Kristallkugel voraussetzt.
Nützlich: http://www.arm.com/documentation/books.html: - ARM Architecture Reference Manual - ARM System Developer's Guide
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?
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.