Jak uruchomić rdzeń 1,2,3 w Raspberry Pi 2

10

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ź.

Schemat obwodu wprowadź opis zdjęcia tutaj

robomon
źródło
To wydaje się naprawdę fajne. Przyjrzę się temu. Mam na myśli, że może być jakieś oprogramowanie w języku raspbian, które wykorzystuje tylko 1 rdzeń, chyba że inne są potrzebne do oszczędzania energii lub coś w tym stylu ...
Kachamenus

Odpowiedzi:

6

Aktualizacja 25 października 2015 r .:

Forum Raspberry Pi udzieliło mi odpowiedzi .

  1. Nie ma koncepcji _start przy użyciu -nostdlib

  2. kod, który należy wykonać jako pierwszy, powinien być pierwszym plikiem przekazywanym do linkera.

  3. 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 0x8000mamy _startfunkcję) z -O2optymalizacją. Ale moje pytanie dotyczące przepełnienia stosu dotyczące _startsymbolu 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:

  1. Właściwie spodziewałem się, że ten _startsymbol 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.

  1. Ale kod nadal nie działał. Kiedy sprawdziłem listę zestawień, okazało się, że pod adresem 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 -O2optymalizacji GCC. W GCC, z wyższymi poziomami optymalizacji, funkcje są zmieniane. Kiedy wyłączyłem optymalizację ( -O0), wtedy pod adresem 0x8000był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 _startprzyjedzie. 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.

robomon
źródło
Spróbuj przyjrzeć się kodowi źródłowemu htop i dowiedzieć się, jak to zrobić, aby wyświetlić wielordzeniowe dane na ekranie.
Piotr Kula,
3
@ppumkin To bez sensu. htopjest 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.
złotowłosa