USB ist tot wenn ISR Code enthält

OP #4226875
Lesenswert?
• ▲
▼
Hi,

ich habe hier ein schräges Problem mit meinem V-USB-Code. Der 
funktioniert prinzipiell super, es sei denn ISR(TIMER0_COMPA_vect) 
enthält Code.

So funktioniert alles ordnungsgemäß und das USB-Gerät wird erkannt:

    ISR(TIMER0_COMPA_vect)
    {
    }

    TCCR0A = (1<<WGM01); // CTC Modus
    TCCR0B |= (1<<CS01); // Prescaler 8
    OCR0A = 15; // 100 kHz

    TIMSK |= (1<<OCIE0A);

Sobald in der ISR aber Code drin ist, wird das Gerät nicht mehr erkannt:

    static volatile unsigned int pulseOnCtr=0,pulseOffCtr=0;

    ISR(TIMER0_COMPA_vect)
    {
       if (pulseOnCtr>0)
       {
          pulseOnCtr--;
          if (pulseOnCtr==0)
          {
          }
       }
       else if (pulseOffCtr>0)
       {
          pulseOffCtr--;
       }
    }

Ich weiß, dass die ISR so noch nichts sinnvolles macht, aber es reicht 
um die USB-Verbindung nicht zu stande kommen zu lassen.

Hat jemand eine Idee, was die Ursache sein könnte? Was an dem Code in 
der ISR ist falsch?

Danke!
Gast #4226891
Lesenswert?
• ▲
▼
ich habe mir deinen Code nicht weiter angeschaut, aber wenn deine 
Kommentare stimmen, dann würde die ISR mit 100 kHz aufgerufen werden.

Das kann selbst bei deinen kleinen Code schon zuviel sein, so das 
wichtige Sachen für USB zurückgesteckt werden müssen, und diese nicht 
mehr im richtigen Zeitfenster behandelt werden konnte.

Reduzier die Frequenz mal auf 100 Hz.

Btw. Mit welcher CPU Frequenz fährst du? Du kannst dir ja mal 
spasseshalber das Dissambly anschauen, die Takte von den 
Assemblerbefehlen zählen (inkl. den ganzen Push und Pop), und dann mal 
schauen, wieviel Zeit eigentlich für den restlichen Code bleibt.

Ist nur eine Vermutung, könnte dir aber weiterhelfen.
OP #4226900
Lesenswert?
• ▲
▼
tja schrieb:
> Btw. Mit welcher CPU Frequenz fährst du?

Die CPU läuft mit 16,5 MHz. Wenn ich die Frequenz auf 10 kHz senke, 
klappt es wieder.

Allerdings erscheint mir das schon sehr wenig, in der ISR werden initial 
(also pulseOnCtr und pulseOffCtr beide auf 0) nur ein paar Takte 
verbraten. Das bringt den V-USB tatsächlich schon aus dem Tritt?
#4226912
Lesenswert?
• ▲
▼
Karl K. schrieb:
> es sei denn ISR(TIMER0_COMPA_vect)
> enthält Code.

Der Code in einem ISR ist so kurz wie möglich zu halten, und dann ist 
zum unterbrochenen Programm zurückzukehren, oder der Hardware-Interrupt 
wieder zu enablen.
Sonst besteht die Gefahr, dass andere Interrupt Requests nicht 
rechtzeitig bedient werden.
Die Ausrechnung irgenwelcher Dinge kann meist später erfolgen, wenn 
jemand die Daten des Interrupts anfordert.
Oft teilt man deshalb die ISR in einen schnellen Raw-ISR, der z.B. nur 
ein Timer-Register liest, und einen Mediated ISR, der z.B. dann das 
Datum daraus errechnet, auf.
Gast #4226915
Lesenswert?
• ▲
▼
Karl K. schrieb:
> Autsch, dass da schon mal 50 Zyklen rein für die Verwaltung draufgehen
> wusste ich nicht...irgend eine Chance die Frequenz wenigstens auf 20 kHz
> hochzubekommen ohne das V-USB die Grätsche macht?

War nur geschätzt, aber 2 volatiles, da werden jeweils LD(S), modify, 
ST(S) draus, die verwendeten Register und das Statusregister muss 
gesichert werden. Multipliziert mit 100kHz werden da schnell jede Menge 
Cycles verbraucht und VUSB ist empfindlich. Schau Dir das Disassemblat 
an, oder simulier's. Wüsste nicht, wie 100kHz klappen soll, denn um 
maximalen Speed zu erreichen, müssten Prozessorregister für die uints 
reserviert sein und da spielt der Compiler nicht mit.
#4226917
Lesenswert?
• ▲
▼
Karl K. schrieb:
> Autsch, dass da schon mal 50 Zyklen rein für die Verwaltung draufgehen
> wusste ich nicht...irgend eine Chance die Frequenz wenigstens auf 20 kHz
> hochzubekommen ohne das V-USB die Grätsche macht?

VUSB mag keine Interupt Last, weil Atmel AVR MCUs keine Interrupt 
Prioritäten oder unterbrechbare Interrupts kennen. Andere Interrups 
verzögern die VUSB Interrupts, die relativ genau getimed sind.

Abhilfe:
Man nehme eine Atmel MCU mit integriertem USB, da hat man das Problem 
VUSB nicht mehr. Die Hardware USB Implementationen bei der Interrupt 
Latenz nicht empfindlich.
Gast #4226918
Lesenswert?
• ▲
▼
am code kann man aber noch ein stück optimieren.

pulseOnCtr

wird 3 mal verwendet, ist vermutlich volatile - das kosten viel zeit.

lass man das volatil weg und caste in der main auf volatile. Dann wird 
die ISR schneller.
(Firma: matzetronics) #4227035
Lesenswert?
• ▲
▼
Du kannst deine Timer ISR auch als ISR_NOBLOCK deklarieren, damit 
erlaubst du V-USB, welches immer die höchste Priorität haben sollte, die 
ISR zu unterbrechen:
1
 ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)

Vorsicht vor Race Conditions. Die Timer ISR sollte mgölichst an nichts 
rumfummeln, was der V-USB IRQ benutzt.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.