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

Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo

lupin22 21 Sie 2017 02:07 1173 16
  • #1 16653771
    lupin22
    Poziom 10  
    Witam, mam szybkie pytanie odnośnie tego, co się dzieje w warunku if. Działam na procesorze xmega, z debuggerem atmel ice.

    Jak widać zawartość warunku wykonuje się (aktywowany breakpoint) mimo, że wartość wyrażenia powinna być fałszywa.

    Co może być tego powodem?

    Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo
    Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo

    Dodam jeszcze, że gdy zamieniłem ten kod na taki:
    Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo
    efek znowu jest niespodziewany:
    Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo

    Tzn po odjęciu obu wartości otrzymałem wartość 256.

    Siedzę już parę godzin nad tym i nie mogę zrozumieć, skąd się to bierze... także byłbym bardzo wdzięczny za pomoc :)
  • #2 16653793
    rajszym
    Poziom 21  
    1. Trudno będzie pomóc, jeśli nie pokażesz choćby kawałka kodu
    2. 256 > 100, wobec tego wartość wyrażenia w instrukcji warunkowej jest jak najbardziej prawdziwa (oczywiście widzę wartości elapsed_time i current_time na ostatnim obrazku)
  • Pomocny post
    #3 16653801
    Andrzej__S
    Poziom 28  
    Jeśli któraś ze zmiennych elapsed_time i/lub current_time jest współdzielona z procedurą obsługi przerwania (jak się można domyślać), to spróbowałbym przed blokiem warunkowym wyłączyć przerwania, a po bloku włączyć:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 16653808
    Konto nie istnieje
    Konto nie istnieje  
  • #7 16653918
    yokoon
    Poziom 29  
    Sei()
    to chyba włącza globalne przerwania??
  • #8 16653983
    Konto nie istnieje
    Konto nie istnieje  
  • #10 16653988
    Konto nie istnieje
    Konto nie istnieje  
  • #11 16653996
    dondu
    Moderator na urlopie...
    R-MIK napisał:
    Oglądałem rozwinięcie assemblerowe.

    No to sprawdzamy dla mikrokontrolera ATmega8:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    co daje:

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    Teraz proszę kol. R-MIK o odpowiedź na pytanie: Co wykonują rozkazy spod adresów:

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod

    oraz:
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod
  • #12 16654019
    Konto nie istnieje
    Konto nie istnieje  
  • #13 16654031
    dondu
    Moderator na urlopie...
    R-MIK napisał:
    No to sprawdzamy dla mikrokontrolera ATmega8:
    Jaka wersja bibliotek? Sprawdzałem dla 1.xxxxx

    Po pierwsze jest to zapewne niezależnie od wersji, choć nie sprawdzę teraz.
    Po drugie, skoro kolega ma jakieś archaiczne doświadczenia, następnym razem zanim kolega coś napisze proszę sprawdzić lub podać źródło swoich twierdzeń.
    Po trzecie nie odpowiedział kolega na zadane pytania.
  • #14 16654183
    Andrzej__S
    Poziom 28  
    dondu napisał:
    Raczej tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kolega ma jak najbardziej rację, tylko że oczekiwanie wewnątrz funkcji eeprom_write_byte() ma miejsce tylko wtedy, kiedy nie został zakończony poprzedni zapis, więc wszystko zależy od częstotliwości zapisu. Może błędnie założyłem (nie widząc reszty kodu), że zapis nie jest na tyle częsty, żeby funkcja eeprom_write_byte() musiała czekać. Generalnie chodziło mi tylko o zwrócenie uwagi na konieczność zapewnienia atomowego dostępu do zmiennych.

    Ale jak najbardziej, może być tak, że częstotliwość zapisów jest duża, i wtedy wyłączenie przerwań na cały czas zapisu (który jest dość długi) może spowodować problemy. Dziękuję za sprostowanie ;)

    No i chciałbym zwrócić uwagę, że w tym wątku mowa akurat o xmega, więc zapis jest raczej realizowany inaczej , i funkcja eeprom_write_byte() prawdopodobnie wcale nie wyłącza przerwań ;)
  • #15 16654202
    lupin22
    Poziom 10  
    Dziękuję serdecznie za odpowiedzi, dodanie volatile i wyłączenie obsługi przerwań na czas porównania wydaje się naprawiać problem. Funkcje eeprom nie wymagają u mnie żadnej dodatkowej opieki, a przerwań używam dość sporo w moim projekcie, więc na pewno zauważyłbym, gdyby tak było. Zapis jest rzadki, chodzi tutaj po prostu o zapisanie sobie, że wystąpił problem w trakcie transferu danych.

    Mam jednak wciąż pytanie co do drugiej części, jeżeli zmienna jest volatile to dlaczego konieczne jest wyłączanie obsługi przerwań? Czy wynika to z tego, że to 4-bajtowy typ long i przerwanie może nastąpić w trakcie porównywania i zmienić wartość niesprawdzonych jeszcze bajtów? I czy w takim wypadku w przypadku porównywania jednobajtowych wartości uint8_t taki problem nie występuje?

    Pozwolą też Koledzy, że jeszcze o jeden problem zapytam. Zacznijmy od kodu (to większy wycinek z pierwszego posta w zasadzie):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    A teraz problem:
    Warunek if na procesorze xmega z debuggerem atmel ice działa nieprawidłowo

    Proszę zobaczyć, że argument size podany jest jako 132, a iterator i ma już wartość 232, której przecież nie mógłby mieć, bo pętla zostałaby przerwana wcześniej warunkiem

    if (i > size - 1) break;

    Co więcej, wywołanie tej funkcji wygląda tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Ogólnie przy jej wywoływaniu i sprawdzaniu debuggerem wartość size jest według debuggera nieprawidłowa, a jednak program wykonuje się tak, jakby była poprawna. Czym może być to spowodowane? Oprócz elapsed_time żadna ze zmiennych nie jest używana w przerwaniach.
  • Pomocny post
    #16 16654285
    Konto nie istnieje
    Konto nie istnieje  
  • #17 16654312
    dondu
    Moderator na urlopie...
    Andrzej__S napisał:
    Kolega ma jak najbardziej rację, tylko że oczekiwanie wewnątrz funkcji eeprom_write_byte() ma miejsce tylko wtedy, kiedy nie został zakończony poprzedni zapis, więc wszystko zależy od częstotliwości zapisu. Może błędnie założyłem (nie widząc reszty kodu), że zapis nie jest na tyle częsty, żeby funkcja eeprom_write_byte() musiała czekać. Generalnie chodziło mi tylko o zwrócenie uwagi na konieczność zapewnienia atomowego dostępu do zmiennych.

    Ale jak najbardziej, może być tak, że częstotliwość zapisów jest duża, i wtedy wyłączenie przerwań na cały czas zapisu (który jest dość długi) może spowodować problemy. Dziękuję za sprostowanie ;)

    Ta moja z pozoru drobna uwaga w różnych okolicznościach może być bardzo istotna, właśnie ze względu na wykorzystane w eeprom_write_byte() pętle sprawdzające jakiś bit. W przypadku XMega jest ich kilka:

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod

    Dlatego pamiętając o tym, że zapis do EEPROM trwa sporo czasu, tym bardziej należy włączyć przerwania przed jej wywołaniem

    Nie jestem specjalistą rodziny XMega więc z ciekawością poczekam co napisze TMF, w tym zakresie.
REKLAMA