www.mikrocontroller.net

Forum: Compiler & IDEs In ISR wird pointer nicht gescheit gesetzt?


Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich bin mit meinem Latein nach 2 Stunden sinnlosem rumprobieren mal 
wieder am Ende. Das ganze soll ein Lauflicht mit verschiedenen 
Leuchtszenen werden. Die 4 LEDs hängen an PortB. Der Pointer 
currentSceneAdress will in der ISR einfach nicht gesetzt werden, man 
sieht aber anhand des Verhaltens der LEDs, dass currentStep erfolgreich 
auf 0 zurückgesetzt, also die ISR richtig ausgeführt wird.

wenn ich den Codeteil der ISR in die while-Schleife der main-function 
verfrachte, dann funktioniert es, also geh ich mal davon aus, dass der 
Pointer in der ISR nicht richtig neu gesetzt wird. Aber warum? Sieht 
jemand einen Fehler? Immer wieder deprimierend wie man sich an solchen 
komischen Dingen aufhält.

Der Code ist bis aufs mindeste reduziert.
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t counter_lightdelay;
volatile uint16_t counter_lightshow;

volatile uint8_t currentScene;
volatile uint8_t *currentSceneAdress;
volatile uint8_t currentStep;


const uint8_t scene1[] PROGMEM = {
(0b1000 << 4) | 10,
(0b0100 << 4) | 10,
(0b0010 << 4) | 10,
(0b0001 << 4) | 10,
0};

const uint8_t scene2[] PROGMEM = {
(0b1100 << 4) | 15,
(0b0110 << 4) | 15,
(0b0011 << 4) | 15,
(0b1001 << 4) | 15,
0};

const uint8_t scene3[] PROGMEM = {
(0b1111 << 4) | 1,
(0b0000 << 4) | 15,
(0b1111 << 4) | 1,
(0b0000 << 4) | 4,
0};

const uint8_t *lightshow[] PROGMEM = {
  scene1,
  scene2,
  scene3
};


int main(void)
{
  uint8_t temp;

  DDRB = 0b00001111;

  TCCR1B = (1 << CS12) | (1 << CS11) | (1 << CS10);
  TIMSK = (1 << TOIE1);

  currentSceneAdress = pgm_read_word(&lightshow[0]);
  currentScene++;

  sei();

  while(1)
  {
    if(counter_lightdelay)
    {
      counter_lightdelay--;
    }
    else
    {
      temp = pgm_read_byte(currentSceneAdress + currentStep);

      if(!temp)
      {
        currentStep = 0;
        temp = pgm_read_byte(currentSceneAdress);
      }
      currentStep++;

      counter_lightdelay = temp & 0b00001111;
      PORTB = temp >> 4;
    }

    _delay_ms(20);
  }
}


ISR(TIMER1_OVF1_vect)
{
  counter_lightshow++;
  if(counter_lightshow == 900)
  {
    counter_lightshow = 0;

    currentSceneAdress = pgm_read_word(&lightshow[currentScene]);
    currentStep = 0;

    currentScene++;
  }
}

lg PoWl

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Such mal nach "atomarer Zugriff" oder "atomic access"

Autor: Paul H. (powl)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
danke, ich such mal danach. Habe übrigens meinen Code mal etwas 
auskommentiert, damit sich besser darin zurecht gefunden wird.

Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Atomarem Zugriff meinst du nicht zufällig, dass es da einen konflikt 
zwischen Auslesen in der Main-Function und neu Setzen des Pointers in 
der ISR gibt? Das würde aber dann mehr oder weniger zufällig passieren, 
das setzen des Pointers klappt nie. Er springt einfach nicht zur 
nächsten Szene, wie als könnte er auf den Pointer da nicht zugreifen 
aber das ist ja irgendwie auch quatsch. Das ist ein µC, da gibts keine 
Speicherbereiche wo irgendein Befehl nicht drauf zugreifen kann, muss 
irgendwie am C-Code liegen.

Allerdings habe ich den Pointer ja als volatile deklariert, somit müsste 
er auch von der ISR raus zugänglich sein :-(

lg PoWl

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum untersuchst du das nicht mal im Simulator? Die Methode "scharfes 
Hinsehen" ist zwar nett, aber wie du selber merkst, kommt man damit 
nicht immer weiter. Für dein Problem reicht der AVR-Studio-Simulator. Am 
besten alle delays vorher auskommentieren oder verkleinern, dann einen 
breakpoint in die ISR, und laufen lassen.

Sehr zu empfehlen ist auch VMLAB. Am Anfang etwas gewöhnungsbedürftig, 
und miserabel dokumentiert (da nicht fertig), aber wenn es dann mal 
läuft, bekommst du einen ganz anderen Einblick in deine Programme.

Oliver

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul Hamacher wrote:

> Allerdings habe ich den Pointer ja als volatile deklariert, somit müsste
> er auch von der ISR raus zugänglich sein :-(

Nein, hast du nicht. Der Pointer selber ist nicht volatile, sondern nur 
das, worauf er zeigt.

volatile uint8_t *currentSceneAdress;
->
uint8_t* volatile currentSceneAdress;

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist eben noch ein Fehler mehr.

Nicht-atomarer Zugriff führt zu fiesen, sporadischen Fehlern, die in 
einem Simulator kaum nachvollziehbar sind (es sei denn, das 
Echtzeitverhalten bleibt unberührt).

http://www.roboternetz.de/wissen/index.php/Fallstr...

Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke @ Stefan Ernst,

das hat das Problem gelöst :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.