Błąd odczytu / zapisu I2C przy dużym obciążeniu przerwania


10

W moim systemie używam I2C i zdaję sobie sprawę, że pod dużym obciążeniem przerywającym (z innych źródeł) komunikacja I2C jest łatwo zakłócana. Czy to oczekiwane zachowanie I2C? Spodziewałbym się pomimo przerwania ładowania, nadal byłoby dobrze, ponieważ I2C nie jest interfejsem o krytycznym znaczeniu dla czasu, zegar jest wyposażony w dane.

Aktualizacja:

Procesor to STM32. Przerwania są spowodowane ADC, nie mogę wyłączyć przerwań podczas zdarzeń odczytu, dlatego muszę znaleźć rozwiązanie, w którym mogę uczynić komunikację i2c bardziej stabilną. STM32 jest urządzeniem nadrzędnym, a urządzenie podrzędne jest innym urządzeniem (akcelerometrem).

Aktualizacja 2:

Kiedy podłączam analizator logiczny do zegara za pomocą małego latającego kabla, problem znika. Co ciekawe, nie ma obciążenia przerwania, odczyt zapisu działa dobrze, gdy obciążenie przerwania nie działa. Jeśli jednak podłączę sondę do zegara, odczyt zapisu działa również pod obciążeniem przerywającym. Myślę, że gdzieś jest problem z pojemnością.


1
Twoje pytanie jest bardzo ogólne, ponieważ wszystko zależy od projektu twojego systemu. Sposób obsługi I2C naprawdę zależy od urządzeń w magistrali. Czy możesz je zignorować i przejść do później? W układach FPGA możesz zaprojektować logikę, która zajmie się Tobą i unikniesz tego. Ponownie potrzebujemy więcej informacji o mikrokontrolerze i innych posiadanych przez ciebie rzeczach. Zwykle dobrym rozwiązaniem jest użycie RTOS i odpowiednie zaprojektowanie zadań.
Gustavo Litovsky

Dwie rzeczy, na które należy zwrócić uwagę: spadek napięcia na podciągnięciach lub zasilanie twojego i2c master i slave, emi lub problemy z pojemnością. Jeśli chodzi o ładowanie przerwania, czy masz na myśli, że twój mistrz przestaje obsługiwać przerwanie? Niektóre żetony nie pozwalają na nieskończone rozciąganie zegara.
Passerby

@GustavoLitovsky masz rację, ale 80% cykli procesora obsługuje przerwanie ADC i nie ma wystarczająco dużo czasu na wykonanie cyklu odczytu w oknie bez ISR. Czytanie zostanie przerwane bez względu na to, jak dobrze zaprojektuję system operacyjny.
Ktc

@Passerby możesz mieć rację. Problem zniknął, gdy podłączyłem sondę analizatora logicznego do linii zegara.
Ktc

Jaka jest twoja aktualna wartość dla podciągnięć. Czy próbowałeś zmienić je na inną wartość? (Spróbuj 10k lub 4k7 lub 2k tylko dla pierwszego odgadnięcia)
Tom L.

Odpowiedzi:


9

Jest to problem z oprogramowaniem, spędzasz zbyt dużo czasu na obsłudze przerwań, a twoja procedura I2C nie jest w stanie sobie z tym poradzić (więc to dwie rzeczy, które nie są właściwe). Przeszedłem przez kilka podobnych sytuacji.

Po pierwsze: musisz robić tak mało, jak to możliwe w przerwaniach, tylko odczytywać i przechowywać dane, nie wykonuj żadnego przetwarzania, które możesz wykonać poza ISR, matematyka może zająć DUŻO cykli procesora, a procesor nie może zrobić nic innego podczas tego przerwania.

Po drugie: Zbadaj DMA, aby zautomatyzować różne rzeczy, aby Twoje przerwania stały się prawie automatycznym procesem w tle.

Po trzecie: jeśli I2C jest ważny, włóż TO w przerwę, ale upewnij się, że wypracowałeś priorytety!

Po czwarte: dowiedz się, dlaczego zawodzi twoja procedura I2C, sam I2C może wytrzymać bardzo przerywane czasy, pauzy i oczekiwania itp., Więc twoja procedura może wymagać modyfikacji, aby na to pozwolić.

Po piąte: sprawdź, czy możesz „łączyć” przerwania, może okazać się, że możesz obsłużyć odczyty ADC bardziej wydajnie, lub przełączyć ADC w inny tryb, w którym działa on lepiej przed przerwaniem (np. Poczekaj, aż wszystkie odczyty będą dostępne, następnie czytaj wszystko za jednym razem, zamiast 8 oddzielnych przerwań dla 8 oddzielnych odczytów kanału ADC).

Po szóste: użyj oscyloskopu lub analizatora logicznego i zapasowych styków we / wy na płycie, aby prześledzić, ile czasu spędzasz w każdym fragmencie kodu, i sprawdź, czy możesz go przyspieszyć. (Ustaw wysoki pin, gdy wejdziesz do funkcji / ISR, ustaw ponownie niski przy wyjściu).

Po siódme: Zdecyduj, czy naprawdę musisz tak dużo czytać ADC, czy wolniejsze pogorszenie sytuacji? Jest to sprzeczne z intuicją, ale czasem działa wolniej, w rzeczywistości daje lepsze wyniki, wykonując pracę polegającą na uśrednieniu sygnału i zmniejszeniu skoków / stanów przejściowych, które mogą powodować problemy lub wymagać dodatkowego przetwarzania w celu usunięcia. Ulepszyliśmy procedurę PID sterowania silnikiem, po prostu uruchamiając ją o 1/4 prędkości, uwalniając obciążenie procesora podczas procesu.


Dziękuję za sugestie. Problem w jakiś sposób wskazuje na sprzęt.
Ktc

4

Niewolnik autobusowy, który jest zajęty innymi rzeczami, może taktować czas, aby kupić czas, aż będzie w stanie kontynuować komunikację. Robi to, nie wysyłając natychmiast impulsu zegarowego ACK / NACK, utrzymując komunikację w stanie pośrednim, dopóki nie będzie gotowy do odpowiedzi.

Rozciąganie zegara jest właściwym sposobem radzenia sobie z tego rodzaju sytuacją. Urządzenie, które nie rozciąga się i robi inne złe rzeczy (zawieszanie / restartowanie magistrali, NACK prawidłowy adres lub polecenie itp.) Może być problematyczne i nakłada dodatkowe obciążenie na urządzenie nadrzędne, aby utrzymać porządek (musi powtarzać polecenia , śledź NACK itp.)


Masz rację, ale problemem jest gospodarz. Gospodarz jest zajęty innymi rzeczami, a nie niewolnikiem. Więc nie jestem pewien, czy mogę zrobić odcinek zegara.
Ktc

Czy używasz wbudowanego sprzętu I2C, czy też generujesz protokół bitowy poza liniami GPIO? W standardzie nie ma określonego interwału przekroczenia limitu czasu I2C, więc urządzenia podrzędne powinny czekać w nieskończoność, aż master zakończy pakiet.
Adam Lawrence

Korzystam z interfejsów API STM32 IC2. Proszę zobaczyć aktualizację, wygląda to na problem z pojemnością.
Ktc

1

W zależności od możliwości STM32 (nigdy go nie użyłem), możesz wypróbować jedno z poniższych podejść. Jeśli możesz podać więcej szczegółów na temat tego, co próbujesz zrobić, i przekonać cię, dlaczego każde przerwanie jest konieczne w takiej formie, w jakiej go masz, to możesz rozważyć bardziej szczegółową odpowiedź. Jednak w twoim przypadku I2C jest wystarczająco wolne, aby nie stanowiło to problemu z dobrze napisanymi procedurami przerwań.

  • Przerwania dla czegokolwiek można zwykle wyłączyć. W każdym zwykłym kontrolerze znajduje się najwyżej jedno lub dwa Przerwania Niemaskowalne, z których jedno jest resetowane. Jeśli nie potrzebujesz kontroli czegoś (w twoim przypadku ADC lub I2C), zamień ten kod peryferyjny na taki, który nie używa przerwań, a następnie wyłącz przerwań.

  • Procedury obsługi przerwań nie powinny być długie. Spróbuj zrobić jak najmniej z samego wektora przerwań. Skrajnie minimalistyczne podejście do przerwań polega po prostu na ustawieniu flagi w ramach procedury obsługi przerwań i powiedzmy, że główna pętla wykonuje wszystkie ciężkie kroki odtąd. To, czego wymaga konkretna architektura aplikacji i oprogramowania układowego, może nie być tak proste, jak to, ale naprawdę warto włożyć wysiłek, aby zobaczyć, ile naprawdę trzeba zrobić z przerwami.

  • Jeśli masz peryferyjne DMA, użyj tego zamiast przerywania w każdym bajcie. Zazwyczaj łatwiej byłoby umieścić ADC na DMA w przeciwieństwie do I2C, ale różne układy mają różne implementacje. Nie zdziwiłbym się, gdyby istniał czysty sposób na wydzielenie wymiany I2C do DMA. DMA pozwala zmniejszyć liczbę przerwań i pozostawia rdzeń procesora wolny od konieczności radzenia sobie z każdym blokiem danych.

  • Spróbuj zidentyfikować konkretne przypadki, w których występuje uszkodzenie danych, oraz mechanizm, w którym dochodzi do uszkodzenia danych. Jest to o wiele trudniejsze, ale dzięki kreatywnemu wykorzystaniu nowoczesnego analizatora oscyloskopu / logiki możesz zauważyć niektóre problemy. W szczególności upewnij się, że problem dotyczy czasu, a nie pamięci (co jest możliwe w połączeniu z okropnym kodem i liberalnym kompilatorem)

EDYCJA: Kilka szczegółowych uwag dotyczących tego wystąpienia problemu, z twoich komentarzy do pytania:

  • Posiadanie 80% procesora używanego do odczytu ADC zwykle nie jest warte zachodu. Zbieranie danych jest bezużyteczne, jeśli nie możesz na nich działać, a nawet zapisać dane.
  • Nawet jeśli w jakiś sposób gromadzisz (pożytecznie) ogromną ilość danych, przerwania ADC nie powinny być na tyle długie, aby całkowicie stłumić urządzenie peryferyjne I2C na wystarczająco długi czas, aby spowodować utratę danych. I2C działa co najwyżej 100/400 KHz. Potrzebujesz naprawdę, bardzo długiego przerwania, aby przerwać wystarczająco długo, aby wyglądało to na coś poważniejszego niż jitter zegara na I2C.

Dzięki. Nasz system wymaga tego rodzaju złożonego i długiego ISR, to długa historia. Masz rację, I2C musi wytrzymać nawet przy tym obciążeniu przerywającym i nie może. Podejrzewam, że problem dotyczy sprzętu, zobacz aktualizację.
Ktc

Z tego, co jest warte, z mojego doświadczenia, większość przypadków użycia, które wydają się nakazać szalenie długi ISR, w rzeczywistości zasługują na RTOS. I tak, według twojej ostatniej edycji wydaje się to problemem sprzętowym. Spróbuj umieścić mały kondensator na linii, w której znajdował się analizator logiczny, i prawdopodobnie nic ci nie będzie. Jednak dlaczego jest to konieczne, trudniej jest odpowiedzieć. Sprawdziłbym rezystory podciągające I2C (może być za niski dla pojemności twojej magistrali) i sprawdziłby arkusze danych wszelkich używanych buforów / repeaterów I2C.
Chintalagiri Shashank

0

W danym systemie może dochodzić hałas dochodzący do zegara i magistrali danych. Pokazuje to fakt, że Twój program logiczny usuwa problem. Aby uzyskać praktyczne i najszybsze wdrożenie, wystarczy postępować zgodnie ze wskazówkami podanymi przez Twoją obserwację. Na magistrali i2c z implementacją 400 kb / s, w oparciu o podobną obserwację, podłączyłem 2M równolegle z 12pf do ziemi od zegara i punktów danych i stwierdziłem, że problem został rozwiązany. To usuwa / filtruje szum poza pasmem zainteresowania wymaganym dla konkretnej komunikacji i2c. Proszę spróbować i doradzić.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.