2012-12-29 6 views
5

Mam problem z hardfault, który pojawia się w pozornie przypadkowych razy, gdy wskaźnik wskazuje adres A5 lub FF (moja dozwolona pamięć jest daleko poniżej 80000000 i więcej). Wydaje się, że zawsze jest ten sam wskaźnik z tymi dwiema wartościami.Wskaźnik losowo przypisany tajemnicze wartości (A5A5A5A5 i FFFFFFFF) na stm32 przy użyciu freeRTOS powodujące hardfault

Używam wbudowanego systemu z procesorem STM32F205RE, który komunikuje się z układem fm/bluetooth/gps o nazwie cg2900, w którym występuje ten błąd.

Korzystając z debugera, widzę, że wskaźnik wskazuje odpowiednio adresy A5 i FF podczas kilku testów. Wydaje się, że zdarza się to w przypadkowych czasach, czasami mogę uruchomić test przez godzinę bez awarii, a innym razem ulega awarii 20 sekund.

Używam freeRTOS jako harmonogram, aby przełączać się między różnymi zadaniami (jeden dla radio, jedno dla bluetooth, drugie dla innej konserwacji okresowej), które może w jakiś sposób zakłócać.

Co może być tego przyczyną? Ponieważ działa niestandardowy sprzęt, nie można wykluczyć, że jest to problem sprzętowy (potencjalnie). Jakieś wskazówki (nie gra słów), jak podejść do debugowania problemu?

EDIT:

Po dalszych badań wydaje się, że to jest bardzo losowe gdzie ulega awarii, nie tylko, że specyficzny wskaźnik. Użyłem hardfault obsługi, aby uzyskać następujące wartości tych rejestrów (wszystkie wartości w hex):

Semi-long run przed katastrofą (w minutach):

R0 = 1 
R1 = fffffffd 
R2 = 20000400 
R3 = 20007f7c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = e000ed38 
CFSR = 10000 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

bardzo krótkim okresie przed zderzeniowych (w sekundach):

R0 = 40026088 
R1 = fffffff1 
R2 = cb3 
R3 = 1 
R12 = 34d 
LR [R14] = 40026088 subroutine call return address 
PC [R15] = a5a5a5a5 program counter 
PSR = fffffffd 
BFAR = e000ed38 
CFSR = 100 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

Innym krótki (sekundy)

R0 = 0 
R1 = fffffffd 
R2 = 20000400 
R3 = 20007f7c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = e000ed38 
CFSR = 1 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

po bardzo długim okresie (1 godzina +):

R0 = e80000d0 
R1 = fffffffd 
R2 = 20000400 
R3 = 2000877c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = 200400d4 
CFSR = 8200 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

Wydaje awarii w tym samym miejscu przez większość czasu. Poprawiłem pamięć zgodnie z wcześniejszymi sugestiami, ale nadal wydaje mi się, że mam ten sam problem.

Dziękujemy za poświęcony czas!

poważaniem

+1

Wygląda na to, że są bajtami magicznymi niezawodnymi. Czy na pewno nie masz wiszącego wskaźnika, dereferencji NULL lub zwróconej lokalnej tablicy gdzieś? –

+0

@ H2CO3 Tak, rzeczywiście wyglądają jak magiczne bajty. Wskaźnik jest podstawą tablicy (zasięg globalny) i mam już warunek, który sprawdza, czy nie piszę poza nim. Sam wskaźnik nigdy nie jest przypisywany po zainicjowaniu go na podstawie tablicy. – ChewToy

+0

, jeśli mógłbyś dodać jakiś rzeczywisty kod, który by pomógł. –

Odpowiedz

1

Okazuje się, że problem został spowodowanych pamięcią. Ponieważ pracowałem z procesorem przy najwyższej prędkości (120 Mhz) i zasilałem napięciem 1,8 wolta (jest ono przeznaczone głównie na 3 V), miałem pewne warunki wyścigowe z pamięcią. Rozwiązano go, stosując wyższy stan oczekiwania.

4

W swoim komentarzu wspomnieć, że ten wskaźnik jest wyraźnie przypisana raz potem nigdy zapisywane. W takim przypadku powinieneś przynajmniej zadeklarować to jako opcję inicjowania zamiast przypisywania, np.

arraytype* const ptr = array ; 

który pozwoli kompilator wykryć żadnych wyraźnych pisze. Jednak jest bardziej prawdopodobne, że wskaźnik jest uszkodzony przez jakiś niepowiązany błąd kodowania.

Moduł Coretx-M3 do debugowania chipów obsługuje punkty przerwania dostępu do danych; powinieneś ustawić taki punkt przerwania na danym wskaźniku, aby wszystkie wejścia do niego były uwięzione. Otrzymasz przerwę na inicjalizację, a następnie modyfikację - celową lub inną.

Prawdopodobne przyczyny są przekroczone w sąsiedniej tablicy lub stosie wątków.

+0

Dzięki za opinie! Powodem, dla którego nie jest stała, jest to, że kod może wykorzystywać kilka oddzielnych buforów w zależności od bieżącego zestawu funkcji na określonym urządzeniu, na którym działa. Tylko do celów debugowania i tak próbowałem zrobić to nadal na stałe, a kompilator wydaje się nadal akceptować kod, więc nie wydaje się, żeby to był przynajmniej problem. – ChewToy

+0

Jeśli chodzi o punkty przerwania dostępu do danych, w jaki sposób powinienem je aktywować? Nie mogłem znaleźć żadnych szczegółów na stronie Google/stronie internetowej ST/dokumentach. Używam edytora Ride7 i debugowania przez Rlink Pro, ale nie mogę znaleźć tej funkcji wewnątrz IDE. Ktoś ma jakieś zalecenia lub przykład, jak ustawić go ręcznie (przez kod asm lub coś podobnego)? – ChewToy

+0

@ChewToy: Nie używałem RIDE, ale Google może sugerować: * Debugowanie-> zaawansowane polecenia-> zaawansowane punkty przerwania *. Proponuję zapoznać się z instrukcją produktu; zdolność może być specyficzna dla sprzętu docelowego i/lub debuggera. – Clifford

3

Jeśli próbowali przenieść tablicę i nadal z tym samym problemem,

następnie niektóre zadaniem jest przepełnione.

Jak wspomniano, używasz FreeRTOS, a ponieważ zachowanie jest losowy jest prawdopodobne, że coś jest nie tak z ustawieniami STACK_SIZE w zaproszeniach do xTaskCreate

Dzieje się tak zwykle, gdy przydzielona rozmiar jest mniejszy niż ty naprawdę potrzebuję.

Jeśli przeczytałeś dokumentację o usStackDepth, zauważyłeś, że reprezentuje mnożnik, a nie liczbę bajtów.

Osobiście wykluczyć problemów ze sprzętem w osadzonym pokładzie i chciałbym skupić się na problemach konfiguracyjnych FreeRTOS

+0

Dzięki za odpowiedź! Tak może być. Rzeczywiście użyłem xTaskCreate, jakby był wielkości liczby bajtów! Będę szukać dalej do niego z pewnym testów, kiedy wrócę do pracy po newyears przeddzień – ChewToy

+0

I rzeczywiście mają problem zostałeś sugerujące, ale nie wydaje się, aby pomóc. Nadal mam te same problemy, co wcześniej. Mimo, że nie zgadzają się, że wciąż wygląda jak przepełnienie – ChewToy

+0

Patrząc na dane, które dodano, zauważyłem, że „link register” zawsze odnosi się do pamięci RAM, a gdy odnosi się do portu DMA1 ... to czyni mnie myślę, że inicjalizacja transferu DMA jest przerwana przez wyższą zadanie priorytetowe, dlatego należy chronić swój kod do sekwencji xSemaphoreTake (...) ~ xSemaphoreGive (...) Możesz przeczytać więcej o [mutex] (http: // www.freertos.org/Real-time-embedded-RTOS-mutexes.html). – RTOSkit

Powiązane problemy