logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

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

Komar_Rafal 12 Paź 2008 17:16 1615 14
  • #1 5624582
    Komar_Rafal
    Poziom 10  
    Witam,

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

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



    main.c:

    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:

    	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).
  • #2 5624620
    ZbeeGin
    Poziom 39  
    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.
  • #3 5624625
    Komar_Rafal
    Poziom 10  
    zmienialem na wszystkie mozliwe (O0 - O3, Os), nawet wyrzucalem w ogole optymalizacje i zawsze dzieje sie to samo ;/
  • #4 5624639
    ZbeeGin
    Poziom 39  
    A którą wersję AVR-GCC używasz? Może warto na chwilę wrócić do poprzedniej wersji... I prześledzić sytuację.
  • #7 5625038
    ciastek4
    Poziom 14  
    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
  • #8 5625092
    BoskiDialer
    Poziom 34  
    ciastek4: Ale po co ukrywanie zmiennej globalnej, skoro ona właśnie ma być widoczna w innym module.
  • #9 5625148
    ciastek4
    Poziom 14  
    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.
    static volatile TFrame Frame
  • #10 5625183
    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:

    
    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:
    
    	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>
  • #11 5625258
    ciastek4
    Poziom 14  
    Nie no jeżeli zadeklarujesz zmienna w pliku interrupt tak:
    volatile TFrame Frame; 


    a w main-e dasz informacje kompilatorowi w ten sposób:
    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 )
  • #13 5625293
    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 ;/
  • Pomocny post
    #14 5625328
    BoskiDialer
    Poziom 34  
    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.
  • #15 5625353
    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 ! :)
REKLAMA