Forum: Mikrocontroller und Digitale Elektronik Synchronisation zwischen Interrupts - Infineon XC166


von Gerald (Gast)


Lesenswert?

Hi,

wie kann ich für den XC166 zwei Codeabschnitte die in 2 Interrupts 
laufen synchronisieren? Gibts dafür eine elegante Lösung?

Lg

von Gerald (Gast)


Lesenswert?

sorry ich brauche eine synchronisation zwischen main loop und interrupt!

von MultiTask (Gast)


Lesenswert?

Verwechselst du Interrupt und Task?

Beschreibe mal deine Aufgabenstellung, da gibts vielleicht bessere 
Ansätze.

von Gerald (Gast)


Lesenswert?

ich hab eine interrupt routine (timer 2) in der zyklisch spi sequenzen 
gesendet werden...
in der main loop sende ich auch spi sequenzen...
beides mal wird ssc0 verwendet...

im moment sperre ich den interrupt von timer 2 wenn ich in der main loop 
die spi sequenzen senden muss...reicht das?

von Falk B. (falk)


Lesenswert?

@  Gerald (Gast)

>im moment sperre ich den interrupt von timer 2 wenn ich in der main loop
>die spi sequenzen senden muss...reicht das?

Dann verpasst du aber ggf. Timerinterrupts. Macht du in dem 
Interrupt noch andere Dinge?

MFG
Falk

von Gerald (Gast)


Lesenswert?

der interrupt wird doch nur verzögert? ein paar counter werden im 
interrupt hochgezählt und halt eine spi sequenz abgesendet...

ich muss aber synchronisieren!

von Falk B. (falk)


Lesenswert?

@  Gerald (Gast)

>ich muss aber synchronisieren!

Na dann mach das doch, siehe Artikel Interrupt.

von TManiac (Gast)


Lesenswert?

Sorry, aber ich würde behaupten, dass deine grundsätzliche 
Software-Architektur nicht durchdacht ist.

Jedes Hardwaremodul (das benutzt wird) sollte durch ein Softwaremodul 
abstrahiert werden. Das wird zum Beispiel durch Dave erledigt. Der 
Zugriff auf diese Softwaremodule kannst du frei implementieren auch wenn 
sie Dave vorgebaut hat. Wenn das Modul von mehreren "Usermodulen" 
genutzt wird, musst du dich entscheiden ob du synchrone oder asynchrone 
Zugriffe brauchst. Zum Beispiel würde ich, so bald da eine ISR zugreift 
nur asynchrone Zugriffe implementieren, so muss die ISR nicht warten bis 
wie in deinem Fall, das Senden abgeschlossen ist. Für einen asynchronen 
Zugriff brauchst du einen "Auftragsbuffer" und wie du den umsetzt, da 
gibt es hunderte Möglichkeiten.

Aber noch was Grundsätzliches:
ISR sollten niemals auf andere Hardware zugreifen als zu welcher sie 
gehöhren. Sowas gehört immer ins Hauptprogramm, zB als Tasks. Die ISR 
sollte nur dem Hauptprogramm "sagen" das es jetzt was zu tun hat.
(und Tasks lassen sich in der C166 Familie bequem per Software 
Interrupts umsetzen, inkl Priosierung)

Gruß,
TManiac

von Gerald (Gast)


Lesenswert?

warum soll ich nicht warten bis das senden fertig ist? wenn ich einen 
aktuellen sendevorgang abbreche dann bekomme ich ja spi pakete die 
unvollständig/kaputt sind!?

ich soll alle 250us +-25us eine 4 bit spi sequenz zyklisch 
absenden...bei 40MHz ist das ziemlich zeitkritisch...

durch was wird eine auslösung des interrupts eigentlich verzögert? im 
moment verwende ich für diesen timer interrupt level 15...nur die spi 
und pec haben 16...da spielt doch nur die anzahl und größen der 
variablen sowie die zeitdauer die der interrupt gesperrt wird eine 
rolle?

im moment erstreckt sich die zeitdauer in welcher ich den interrupt 
deaktiviere vom initialisieren des spi, absenden sowie empfangen der spi 
sequenz. diese zeit ist im moment max. 23us (bei 32 bit spi kommandos)! 
spi baudrate = 5 MBaud

von TManiac (Gast)


Lesenswert?

Ich habe nicht gechrieben, dass du den Sendevorgang abbrechen sollst. 
Ich schrieb, dass das Senden asynchron laufen soll. Das heißt deine 
Interruptroutine ruft nur die Funktion "Sende_Irgendwas()" auf. Die 
Funktion kehrt sofort zurück in die ISR. Das Senden selber läuft eben 
nicht im Interrupt-Kontext, sondern, zum Beispiel in einer Task oder 
eben einer SPI-SendeInterrupt (wie du willst).

Aber 250microsekunden Sende-Zyklus ist schon recht knackig. Ist das 
wirklich notwendig? 5Mbaud SPI klingt für mich recht fix (was nichts zu 
sagen hat, da bei mir SPI nur für den EEPROM notwendig ist) In diesem 
Fall würde ich das Senden aber per PEC umsetzen (hab ich selber noch 
nicht gemacht)

Außerdem verstehe ich nicht warum die Main und der Timer auf die gleiche 
SPI zugreifen müssen. Ok du greifst auf den gleichen Slave zu. Und der 
Timer scheint einen Heartbeat zuschicken. Ist dideser Hearbeat auch 
erforderlich, wenn man arbeitend auf den Slave zu greift?
Folgende Idee:
Der Zugriff auf den Slave (und damit die SPI) geschieht ausschließlich 
über den Timer. Wenn Arbeit ansteht (die Main will auf die SPI 
zugreifen) dann wird diese Arbeit in eine Buffer geschrieben. Die ISR 
erkennt das im Buffer etwas steht und übergibt nun anstatt des Heartbeat 
signals eben das Arbeitskommando. Das Ergebnis kann dann immer noch von 
der Main abgeholt (gebuffert) werden. Wenn du einen Empfangs-FIFO 
eingerichtet hast, brauchst du noch nicht mal extra Speicher.

Auf der anderen Seite brauch doch beim Senden der SPI nicht jedes Mal 
umkonfiguriert werden. Die Main und auch die Timer ISR sollten doch 
"nur" ein Wort an die SPI zum Senden übergeben. Wenn das Senden über 
einen FIFO läuft könnten auch beide getrennt darauf zugreifen. Nur das 
Zuordnen der Antworten müsste gelöst werden (was auch keine Hexerei 
ist).

Darüber hinaus: Warum nutzt du die oberen Prio-Level brauchst du alle 16 
(mal die Gruppen-Level)? Es macht der mehr Sinn irgend wo in der Mitte 
anzufangen und immer mindestens einen Platz zu lassen. Da hat man auch 
mal die Möglichkeit das System zu ergänzen.

Verzeih mir bitte mein Nachgehage, aber die richtige Lösung kannst nur 
du selber finden, da nur du das komplette System kennst. Wir können nur 
versuchen dir ein paar Tmehr oder weniger nützliche Tipps zu geben.

Gruß,
TManiac

von Gerald (Gast)


Lesenswert?

naja in beiden fällen nehme ich die gleich spi schnittstelle jedoch 
andere bitlängen! bei einem 50us window zählt jede einzige us;) weiss 
nicht ob es so schlau ist das senden nicht im interrupt zu machen...

der PEC transfer für das spi sollte auf interrupt 16 laufen.

wie finde ich raus wie lange das speichern der variablen auf den stack 
braucht bevor ich in den interrupt springe? die zeit wär schon recht 
nützlich!

ich sende in der main eine spi sequenz ab (z.b. 20 befehle)...und im 
timer interrupt soll alle 250us ein spi kommando angesendet 
werden...über das gleiche spi port! es sind unterschiedliche spi längen 
im spiel...dh ich muss vor dem senden immer umkonfig...die main loop 
kann über spi port 1 oder port 2 senden, der timer interrupt sendet nur 
über port 1...

mein SSC modul hat keinen FIFO.

von Gerald (Gast)


Lesenswert?

mein spi device ist master.

von TManiac (Gast)


Lesenswert?

Hello again,

Ich muss mal schrittweise antworten, also zitiere ich direkt den vorigen 
Post (gegen die Forumsregeln)

> naja in beiden fällen nehme ich die gleich spi schnittstelle jedoch
> andere bitlängen! bei einem 50us window zählt jede einzige us;) weiss
> nicht ob es so schlau ist das senden nicht im interrupt zu machen...

Das Umkonfigurieren kostet dich aber mehr Zeit als wenn du ein zu langes 
"Wort" schickst.
Beim Umkonfigurieren musst du erst die SSC deaktiveren, das CON Register 
beschreiben, dann eigentlich die Interrupt flags löschen (man weiß ja 
nicht ob inzwischen noch einer reingekommen ist, der auf der alten 
Konfiguration basierte) erst dann die SSC wieder aktivieren und nutzen. 
Da ist das eine Byte zusätzlich doch viel schneller reingeschrieben.
Darf man fragen mit welchem Device sich dein Controller unterhält?

> der PEC transfer für das spi sollte auf interrupt 16 laufen.

Ja die PEC sollten grundsätzlich in den obern drei Interrupt-Level 
liegen. Ich meinte auch mehr deine Timer Interrupt.

> wie finde ich raus wie lange das speichern der variablen auf den stack
> braucht bevor ich in den interrupt springe? die zeit wär schon recht
> nützlich!

Der Interrupt (vom Timer) sollte gar nicht den Stack sichern, er sollte 
gar nicht erst darauf zu greifen (es wird übrigens nicht der Stack 
gesichert, sondern die Register werden auf den Stack geparkt). Vorallem 
wenn er so schnell reagieren muss. Beim Tasking kann man das zum 
Beispiel schon in der EDE einstellen.

> ich sende in der main eine spi sequenz ab (z.b. 20 befehle)...und im
> timer interrupt soll alle 250us ein spi kommando angesendet
> werden...über das gleiche spi port! es sind unterschiedliche spi längen
> im spiel...dh ich muss vor dem senden immer umkonfig...die main loop
> kann über spi port 1 oder port 2 senden, der timer interrupt sendet nur
> über port 1...

Also noch mal: Die Heartbeat Nachricht die durch deinen Timer generiert 
wird ist auch bei anstehender Arbeit notwendig? Scheinbar ja, auch wenn 
ich das nicht glauben mag.
Du nutzt verschiedene SPI Kanäle (meinst du das mit den Ports?). Hängen 
da verschiedene Devices dran, oder warum machst du das?
Was konfigurierst du um? Es geht doch immer um die Kommunikation mit dem 
gleichen Device? Also ist doch das Protokoll das gleiche. Wenn dein 
Device (damit meine ich nicht den Controller) der Master ist, wie du in 
deiner Ergänzung schreibst, taktet doch dieser die Daten. Ich weiß jetzt 
nicht aus dem Stegreif wie der XC reagiert, wenn weniger Bits aus seinem 
Ausgang rausgetaktet werden als konfiguriert wurde. Aber auch wenn er 
eine Exception (wenn überhaupt implemnetiert) wirft, ist das dem 
Empfänger doch egal.

> mein SSC modul hat keinen FIFO.
Ok war verlesen hatte XE gelesen. Welchen XC hast du genau? XC166 gibt 
es ja nicht, damit bezeichnet man die Familie. Ist es ein 161, 164 oder 
167?

Meinst du mit deiner Ergänzung, dass das über SPI verbundene Device 
Master ist oder dein Controller?

von Gerald (Gast)


Lesenswert?

ok, habs nun gelöst;)

von TManiac (Gast)


Lesenswert?

Darf man noch grob erfahren, was du nun gemacht hast?

Danke,
TManiac

von Gerald (Gast)


Lesenswert?

einfach nur zum richtigen zeitpunkt den wdt interrupt disabled...damit 
ich in der main loop nur zwischen den wdt interrupts kommandos 
sende...wenn denn der wdt interrupt kommt soll dieser das zyklische spi 
kommando absenden...um verzögerung des wdt interrupts zu verhindern 
überprüfe ich den wdt counter in der main loop...

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
Noch kein Account? Hier anmelden.