Napisałem prosty metalowy przykład wielordzeniowy.
Kod, schemat obwodu jest tutaj - https://github.com/jeffreyantony/multipi/tree/master/Example_01
W moim przykładzie do pinów GPIO raspberry Pi podłączone są 3 diody LED. W Raspberry Pi 2. znajdują się 4 rdzenie. Każdy z nich ma przypisane miganie odpowiedniej diody LED.
Napisałem adres kodu do wykonania przez każdy rdzeń w poniższych adresach 0x4000009C dla rdzenia 1 0x400000AC dla rdzenia 2 0x400000BC dla rdzenia 3
Po skompilowaniu kodu miga tylko dioda LED przypisana do rdzenia 1 (jak w tym przykładzie żółta dioda LED). Inni nie są.
Oznacza to, że kod dla Core 2 i 3 nie są uruchomione (ponieważ inne diody LED nie migają). Odkryłem również, że kod po uruchomieniu wszystkich rdzeni również nie działa, tj. Core0_submain () - ta funkcja powinna mrugać diodą ACT na Raspberry Pi
Czy ktoś mógłby mi powiedzieć, na czym polega problem? Czy to dlatego, że wszystkie 4 rdzenie próbują pisać do tego samego rejestru GPIO, a wygrywa tylko Core 1?
Próbowałem dodać „ atrybut ((goły));” dla core0_submain (), ale nie było sensu.
Korzystam z zestawu narzędzi z https://launchpad.net/gcc-arm-embedded
jeszcze raz kod - https://github.com/jeffreyantony/multipi/blob/master/Example_01/main.c
makefile - https://github.com/jeffreyantony/multipi/blob/master/Example_01/Makefile
Aktualizacja 20 października 2015 : Dodałem obsługę JTAG. Ale nie udało się uzyskać interfejsu debugowania
Aktualizacja 25 października 2015 : Problem został rozwiązany. Zobacz odpowiedź.
źródło
Odpowiedzi:
Aktualizacja 25 października 2015 r .:
Forum Raspberry Pi udzieliło mi odpowiedzi .
Nie ma koncepcji _start przy użyciu -nostdlib
kod, który należy wykonać jako pierwszy, powinien być pierwszym plikiem przekazywanym do linkera.
Jeśli potrzebna jest lepsza kontrola, kod należy umieścić w sekcji init i poprosić linkera o skopiowanie tej sekcji
0x8000
Dziękuję wszystkim za wsparcie. Dowiedziałem się dużo o kompilatorze GNU C.
Aktualizacja 24 października 2015:
Kiedy zmieniłem kolejność plików podanych do kompilacji w Makefile, dostałem prawidłowe uporządkowanie (tj. Gdy
0x8000
mamy_start
funkcję) z-O2
optymalizacją. Ale moje pytanie dotyczące przepełnienia stosu dotyczące_start
symbolu nie zostało jeszcze rozwiązane. Nowy kod jest rejestrowany.Odniosłem pewien sukces. Nowy kod jest rejestrowany w github .
Przykład nie działa całkowicie. Istnieją pewne problemy z kompilacją. Wyjaśnię każde:
_start
symbol pojawi się na moim niestandardowym początku. Ale tak nie było. Z tego powodu wskaźnik stosu nie został skonfigurowany i nie nastąpił skok do głównego.Zadałem już pytanie na ten temat. Ale niewiele zrobiłem. Więc dodałem zestaw wbudowany, aby załadować wskaźnik stosu w głównej funkcji.
0x8000
(gdzie zaczyna się wykonywanie) Raspberry Pi znajduje się kod dla Core 1 -void core1_main(void)
. Moje założenie było takie,0x8000
że będzie_start
(co nie jest od początku pliku S nie jest brane do kompilacji) lub przynajmniej void main (void). Dzieje się tak z powodu-O2
optymalizacji GCC. W GCC, z wyższymi poziomami optymalizacji, funkcje są zmieniane. Kiedy wyłączyłem optymalizację (-O0
), wtedy pod adresem0x8000
była obecna główna.O zmianie kolejności funkcji możesz przeczytać tutaj
Podsumowanie: Obecny kod to tylko poprawka. Główny problem do rozwiązania - Dlaczego _start nie jest wywoływany od początku.S? Jeśli zostanie to naprawione, adres
0x8000 _start
przyjedzie. Dzięki temu nie musimy przejmować się kolejnością funkcji wykonanych przez GCC podczas wyższej optymalizacji.Jest też film demonstracyjny z mojej strony jako dowód. Chociaż częstości migania diod LED są różne i okresowe w kodzie, ponieważ wszystkie rdzenie próbują zapisywać w tych samych rejestrach GPIO, istnieją pewne konflikty, które powodują miganie diod LED w przypadkowych odstępach czasu.
źródło
htop
jest narzędziem użytkownika * opartym na * nix. W systemie Linux pobiera informacje z jądra za pośrednictwem/proc
. To jest nagi metal. Nie ma jądra do zapytania.