Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATmega32L][winAVR][C] - zmienne a przerwania

Komar_Rafal 12 Paź 2008 17:16 1489 14
  • #1 12 Paź 2008 17:16
    Komar_Rafal
    Poziom 10  

    Witam,

    mam dwa pliki projektu w C: interrupt. i main.c (dla uproszczenia).
    interrupt.c:

    Code:
    static volatile TFrame Frame ={0};
    
     
    SIGNAL (SIG_INTERRUPT0)
    {
       (...)  //m.in. zmienia sie struktura Frame
    }



    main.c:

    Code:
    extern TFrame Frame;
    

    void main (void)
    {
           (...)
           sei();
       while (1)
       {
          if (Frame.state & READY)
          {
              (...)  //tutaj nie zmieniam zmiennej Frame, jedynie sprawdzam jej stan
          {
       }
    }


    po kompilacji otrzymuje cos takiego:

    Code:
       sei();
    
          da:   78 94          sei
          dc:   ff cf          rjmp   .-2         ; 0xdc <main+0x4a>



    kompilatorowi wydaje sie, ze jest madrzejszy od wszystkich i stwierdza, ze zmienna Frame nie zmieni sie i wywala mi caly ten fragment :/ Czy jest jakis sposob zeby kompilator to normalnie skompilowal zeby nie pisac tego w asemblerze ? (nie to zebym nie lubil ale ja mam tego duzo i pisanie raz w C raz w asemblerze moze byc nie za fajne).

    0 14
  • #2 12 Paź 2008 17:28
    ZbeeGin
    Poziom 38  

    Wyłącz optymalizację lub zmień jej poziom na mniejszy.
    Ostatnio dość często widzę, że AVR GCC nie bardzo radzi sobie z takimi pętlami przy optymalizacji. Sam walczyłem z programem, który to co było po while(1) kompilator totalnie obcinał. Jakiś błąd w GCC musi być. Dopiero wyłączenie optymalizacji pomogło.

    0
  • #3 12 Paź 2008 17:30
    Komar_Rafal
    Poziom 10  

    zmienialem na wszystkie mozliwe (O0 - O3, Os), nawet wyrzucalem w ogole optymalizacje i zawsze dzieje sie to samo ;/

    0
  • #4 12 Paź 2008 17:33
    ZbeeGin
    Poziom 38  

    A którą wersję AVR-GCC używasz? Może warto na chwilę wrócić do poprzedniej wersji... I prześledzić sytuację.

    0
  • #5 12 Paź 2008 17:44
    fantom
    Poziom 31  

    A moze by tak w main tez dac kompilatorowi wskazowke zeby tego nie optymalizowal ?

    Code:

    extern volatile TFrame Frame;

    0
  • #7 12 Paź 2008 19:19
    ciastek4
    Poziom 13  

    Freddie Chopin napisał:
    po co to 'static'?

    4\/3!!



    static przy zmiennej globalnej powoduje, że zmienna jest widoczna tylko w tym pliku w którym została zdefiniowana. Jest to tzw ukrywanie zmiennych globalnych

    0
  • #8 12 Paź 2008 19:32
    BoskiDialer
    Poziom 34  

    ciastek4: Ale po co ukrywanie zmiennej globalnej, skoro ona właśnie ma być widoczna w innym module.

    0
  • #9 12 Paź 2008 19:46
    ciastek4
    Poziom 13  

    BoskiDialer napisał:
    ciastek4: Ale po co ukrywanie zmiennej globalnej, skoro ona właśnie ma być widoczna w innym module.


    Wiem. Może nie jasno się wyraziłem. Moje stwierdzenie wczesniejsze jest odpowiedzia na pytanie w 1 poście:

    Komar_Rafal napisał:
    Czy jest jakis sposob zeby kompilator to normalnie skompilowal zeby nie pisac tego w asemblerze ?


    Odpowiedź :
    usuń static w deklaracji zmiennej.
    Code:
    static volatile TFrame Frame

    0
  • #10 12 Paź 2008 20:04
    Komar_Rafal
    Poziom 10  

    nie wiem czy static dziala dla zmiennych globalnych tak samo jak dla funkcji, ja to tam dalem bo myslalem, ze pomoze, bez tego tez nie dziala.

    Dodano po 9 [minuty]:

    dodanie volatile w main robi cos dziwnego:

    Code:

    extern volatile TFrame Frame;

    void main (void)
    {
       (...)
       sei();
       while (1)
       {
          if (Frame.state & READY)
          {
             Frame.state &= ~READY;
             if (Frame.state & SUMERR)
             {
                Frame.state &= ~SUMERR;
                (...)
             }
             else
             {
                (...)
             }
          }      
       }
    }


    asm:
    Code:

       sei();
          f0:   78 94          sei
       while (1)
       {
          if (Frame.state & READY)
          f2:   80 91 f1 01    lds   r24, 0x01F1
          f6:   fd cf          rjmp   .-6         ; 0xf2 <main+0x60>

    0
  • #11 12 Paź 2008 20:13
    ciastek4
    Poziom 13  

    Nie no jeżeli zadeklarujesz zmienna w pliku interrupt tak:

    Code:
    volatile TFrame Frame; 


    a w main-e dasz informacje kompilatorowi w ten sposób:
    Code:
    extern volatile TFrame Frame; 


    to niemożliwe żeby kompilator pominął tą zmienną. Sprawdź jeszcze czy dobrze ustawiana jest flaga Frame.state & READY.
    Z natury nie ufam AVRStudio ( Softwarowy Debugger juz pare razy mnie oklamal :P po prostu )

    0
  • #12 12 Paź 2008 20:15
    bobbyAIR
    Poziom 20  

    w interrupt.h

    Code:

    volatile TFrame Frame ={0};

    w main.c
    Code:

    extern volatile TFrame Frame;

    0
  • #13 12 Paź 2008 20:20
    Komar_Rafal
    Poziom 10  

    No tak mam wpisane (tylko deklaracje mam w interrupt.c bo w h sie nie da). Ja tego nie sprawdzam w softwarowym debuggerze tylko w pliku *.lss, wyraznie tam widac, ze jest cos fest pomieszane ;/

    0
  • Pomocny post
    #14 12 Paź 2008 20:27
    BoskiDialer
    Poziom 34  

    Code:
    if (Frame.state & READY) 
    
          f2:   80 91 f1 01    lds   r24, 0x01F1
          f6:   fd cf          rjmp   .-6         ; 0xf2 <main+0x60>
    po tym kodzie szacuję, że READY ma wartość równą 0. Odczyt Frame występuje (bo jest oznaczone jako volatile), ale porównania nie ma, gdyż jest zawsze fałszywe (tylko moje spekulacje). Jeśli READY to numer bitu, musisz maskować przez _BV(READY) a nie samo READY.
    -- edit: lit.

    0
  • #15 12 Paź 2008 20:33
    Komar_Rafal
    Poziom 10  

    ooo kuuuuurdeeeee, faktycznie READY mialem na 0 zamiast na 1, to jest maska, po prostu w pierwszej wersji mialo to byc faktycznie 0 ale potem zmienilem w kodzie, szkoda, ze nie zmienilem w define :/ Dzieki bardzo za pomoc ! :)

    0
  Szukaj w 5mln produktów