Hallo,
ich bin ein Neuling auf dem ST32F103...
Nun möchte ich folgendes erreichen:
Ich erwarte ein Hardwaresignal auf einer Leitung alle 5 Sekunden. Dies
Signal wird auf der Leitung ein ca. 10 ms langer puls sein, es soll also
ein interrupt generiert werden.
Erfolgt der Puls nicht rechzeitig, möchte ich via timer-interrupt eine
Aktion triggern.
Ich programmiere in ANSI C und (falls es nicht anders geht) in
Assembler.
Hat da jemand Erfahrung und (besser) ein Codebeispiel?
Danke & Gruss
Joe
Schönes Beispiel für eine Gedankliche Oversized-Lösung :)
Also Du möchtest mit einem 72MHz Prozessor eine Sache erledigen, die mit
5s Auflösung etwas tut, das auch noch etw 10ms lang sein darf.
Gehen wir mal vom Worst-Case aus, dass der Core und Code ineffektiv
zusammen arbeiten, weil man als Anfänger die Tricks und Kniffe noch
nicht kennt.
Dann wird ein Befehl in 1/4 der Taktrate laufen.
Du hast also 90Mio Befehle in 5s, und 180000 Befehle in 10ms zur
Verfügung.
Was Du machen möchtest ist am Einfachsten in einem kleinen (Real-Time-)
Operating-System zu erledigen, das Dir Tasks zur Verfügung stellt. Dann
startest Du einen Task, der alle 1ms nachschaut, ob entweder ein Signal
anliegt oder 5s vergangen sind. Dafür braucht man weder Interrupts noch
Timer, ausser dem SysTick-Timer, den Dir aber ein gutes OS sowieso schon
zur Verfügung stellt und den es dann als Zeitbasis für die Tasks
verwendet.
Obiges funktioniert sehr einfach mit Nut/OS in der STM32 Version. Zu
finden unter ethernut.de, Quellen des STM32 branch unter
https://ethernut.svn.sourceforge.net/svnroot/ethernut/branches/devnut_m3n.
Mailingliste und weitere Infos zum wie und wo auf der Webseite.
Gruß, Ulrich
Hallo Ulrich,
es ist ja nicht so, dass die CPU nur dafür da ist, diesen Input zu
überwachen, das ist nur eine von vielen Aufgaben.
Ein OS wird es auf dem System nicht geben. Pollen möchte ich nicht, das
wäre ja Dein Vorschlag.
Nur als Anhaltspunkt, das System muss "nebenbei" (ist eher seine
Hauptaufgabe) noch die Konzentration versch. Gase messen und dies noch
filtern. Das sind einige hundert Messungen pro Sekunde... Die Anwendung
ansich ist eine professionelle, nur ich hab eben auf dem Cortex M3 noch
nie programmiert...
Drum frage ich nach einem Beispiel, wie ich so einen Timeout-timer
aufsetze und eine Interrupt Routine dem system bekannt mache, sprich in
die Interrupt-Tabelle eintrage usw.
Beste Grüsse,
Jörg
Also das ganze klingt wirklich immer noch nach einer Aufgabe, die durch
ein (einfaches) OS erledigt werden sollte.
Die Hauptaufgabe ist ja das Erfassen der Messwerte, was beim CM3 recht
einfach ist, da der ADC per DMA und Abhängig von einem Timer die
Messwerte automatisch im RAM ablegt.
Sind die Sensoren per Datenschnittstelle angeschlossen, so kann auch
dies von einem OS recht einfach verwaltet werden.
Auch in einem OS kann man Timer nutzen, die dann Interrupts auslösen,
oder man kann einen Timer nutzen, der zu verschiedenen Zeiten
verschiedene Tasks aufweckt. Und man kann diese Timer und Tasks mit
verschiedenen Prioritäten versehen, je nachdem, ob es einem Wichtiger
ist, nach genauen Zyklen zu messen oder exakt zu erkennen, ob ein Sensor
verloren ging.
Ich spreche ja nicht von einem OS im Sinne von (uC-)Linux sondern etwas,
dass Dir ein paar Werkzeuge zur Verfügung stellt, damit Du es einfacher
hast die verschiedenen Aufgaben zu paralelisieren.
Schau doch mal nach CooCox, Free-RTOS oder Nut/OS (Ich bevorzuge
letzteres, da ich den STM32 dafür portiert habe :) )
Ich mach damit genau das, was Du tun willst, nämlich Sensoren auswerten,
Grenzwerte überwachen und das ganze per CAN an einen Master senden oder
per Funk übertragen.
Das OS nimmt es Dir schon mal ab, Dich um die Initialisierung zu
kümmern, Speicher anzubinden, Heap und Stack zu überwachen und es stellt
Dir eine ganze Reihe fertiger Schnittstellen (USART, SPI, I2C, ADC...)
und die Ansteuerung von üblichen vorhandenen externen Chips zur Seite
(EEPROM, RTC, Tasten, LEDs...). Das ganze passt in die 64k Varianten der
STM32F103 rein, sogar inkl. eines separat laufenden Bootloaders für CAN.
Für 9 von 10 Sensoren war es zudem möglich mit dem Takt auf 16MHz runter
zu gehen und damit drastisch Strom zu sparen und trotzdem Messzyklen <
1s einzuhalten und ein komplettes CANopen Profil zu bedienen.
Du solltest Dir also in Ruhe noch mal überlegen, ob Du aus einem
fertigen Set schöpfen willst, oder alles (nocheinmal) selber erfinden
musst.
Ps: Nut/OS ist unter BSD Lizenz, die kommerzielle Nutzung ist also ohne
weitere Besonderheiten gestattet. Wir freuen uns aber über jeden
Beitrag, Verbesserung oder Treiber, der beigesteuert wird. Ich setze es
selber kommerziell ein.
Schau halt mal bei ethernut.de, der STM32 Branch ist hier: (SVN)
https://ethernut.svn.sourceforge.net/svnroot/ethernut/branches/devnut_m3n
Hallo Ulrich,
danke für die detaillierte Ausführung.
Es gibt nur ein Problem: Da bereits ein Teil implementiert wurde, OHNE
OS und ich den Teil verwenden soll/muss, bleibt mir leider gar nicht die
Wahl..
Ich muss das ohne OS machen.
Blöderweise gibt es im beisherigen code noch keine Nutzung von
Interrupts oder timern, sonst hätte ich wenigstens dort "kopieren"
können..
Naja - ich werd mich mal durch die Doku lesen müssen..
Danke nochmal und Gruss
Jörg
Für deine Aufgabe bauchst du kein OS und keinen externen Interrupt.
Ein einfacher Timer Interrupt, der alles 5ms ausgelöst wird, reicht aus.
Siehe Pseudocode:
1
#define ALARM_THRESHOLD 1000 // 5sec / 5ms = 1000
2
3
// Timer Interruptroutine, wird alles 5ms aufgerufen
4
voidtimer_isr()
5
{
6
staticuint32counter=0;
7
8
counter++;
9
// Resette den counter wenn am pin ein high gemessen wird
10
if(INPUT_PIN==high)
11
{
12
counter=0;
13
}
14
15
// wenn der counter den grenzwert (hier 5 sec)überschreitet soll die Aktion ausgeführt werden
16
if(counter>ALARM_THRESHOLD)
17
{
18
do_alarm_action();
19
}
20
}
ALARM_THRESHOLD sollte vielleicht größer als 1000 sein, z.B. 1500 würde
7,5 sec bedeuten.
Und den timer interrupt musst du natürlich noch entsprechend
konfigurieren, da kann ich nicht helfen weil noch nie gemacht beim
STM32.
Hi!
Wenn Du Dir bei dem CooCox nicht ganz sicher bist und vielleicht doch
etwas Arbeit sparen willst, dann kannst Du getrost Nut/OS einsetzen.
Als Mitentwickler von Nut/OS kann ich Dir versprechen, dass Du es
kommerziell ohne weitere Verpflichtungen einsetzen kannst. Als Gebühr
nehmen wir gerne Bugfixes, Treiber oder gute Ideen :)
Für CortexM3 und die ganze STM32F10x Familie wäre der devnut_m3n branch
für Dich der richtige. Der trunk wird in den nächsten Wochen umgebaut
und alle neuen Architekturen hinein gemerged. der Branch sollte dabei
stable bleiben, denn ich setze ihn ebenfalls kommerziell ein.
Gruß, Ulrich
Hallo
@Ulrich
Du scheinst Dich ja mit den RTOS'en etwas auszukennen ;-)
Ich suche ein RTOS für den LPC1769, wie sieht es mit Nut/OS hier aus ?
Bei
CooCox scheint es ja einen Build zu geben. Im Moment traue ich mir eine
Eigenportierung noch nicht zu.
Daniel
Hi Daniel,
Leider stehen LPCs bei Nut/OS noch auf der ToDo Liste. Habe auch schon
ein paar Exemplare ARM7 und CortexM3 bei mir herum liegen. Außerdem gab
es in der Mailingliste Meldungen das da Bedarf besteht. Aber bisher
keine Zeit :(
Wenn man etwas C Erfahrung hat ist es aber sehr einfach einen weiteren
CortexM3, wie den LPC17xx zu Nut/OS hinzu zu fügen. Das schwere an der
Portierung ist ja, den Chip erst mal zu initialisieren. Und das geht bei
allen Cortex gleich, dank CMSIS. D.h. Du musst nur eine Funktion
schreiben, die die PLL korrekt startet und kannst dann gleich mit dem
USART weiter machen, damit er sich melden kann.
Das ganz Linkerscripte und Init Schreiben kannst Du Dir sparen und sie
von meinem STM32 kopieren. Wenn es für den LPC ebenfalls ein kompaktes
Header File gibt, in dem alle Peripherie-Register und deren Flags
definiert sind, dann kannst Du auch USARTs und so weiter einfach nur die
Register und Bit-Namen anpassen.
Du darfst Dich da bei allen Dateien bedienen, die stm32_xxx.y heißen,
denn diese habe ich komplett um-/neu geschrieben. Dateien mit
stm32f10x_xxx.y sind noch mehr oder weniger STM-Library und daher an den
STM32 gekoppelt.
Das Einzige, was etwas kompliziert erscheint, wenn man nicht drinn
steckt, ist das nutconfig. Die Scripte anzupasssen, dass eine neue
Chip-Generation, oder ein weiterer Typ einer bekannten Architektur
erkannt wird, ist etwas kniffelig. Auf der anderen Seite haben wir das
im devnut_m3n bereits weiter aufgedröselt, so dass es übersichtlicher
wird.
Ich bin in die CM3 Portierung auch mit Respekt eingestiegen, war aber in
netto 14 Tagen durch. Das schwere war in meinem Fall, die Unterschiede
der neuen Architektur kompatibel mit den bestehenden Strukturen in
Nut/OS zu halten. Nun sollte das Einbinden eines weiteren CortexM3 in
einer Mann-Woche zu machen sein.
Gruß, Ulrich