Skocz do zawartości

Elvis

Nowy
  • Zawartość

    2694
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    198

Posty napisane przez Elvis

  1. W każdym razie:

    10 minut temu, ethanak napisał:

    Zauważ: zakładając, że PB5 to stała a PINB to odwołanie się do zawartości rejestru - 1 << PB5 obliczany jest w czasie kompilacji. PINB >> PB5 w czasie wykonania.

    Ergo: jeśli moje założenia są słuszne, nie jest optymalny niezależnie od mikrokontrolera 😉

    to nieprawda. Są takie architektury gdzie oba kody mogą być tak samo wydajne.

  2. Przy okazji warto jeszcze wyjaśnić jak ten pin jest skonfigurowany i jak niby miało działać - bo najpierw używany jest rejestr PORTB, czyli wygląda jakby to miał być pin w trybie wyjścia, ale chwilę później następuje odczyt z rejestru PINB, więc jednak wejście. Jestem bardzo ciekaw jak autor rozumie działanie takiego programu.

    @ethanak zostawmy te optymalizacje w spokoju, może warto zacząć od poprawności programu. Może nie być różnicy, czy przesunięcie jest wykonywane podczas kompilacji, czy wykonywania.

  3. Niestety nie znam metody na użycie GPS w małym robocie, dlatego zapytałem. Dokładność 2m to bardzo optymistyczne założenie. Filtr Kalmana to dobry pomysł, sprawdza się w nawigacji samochodowej - ale znowu, przy rozmiarze i szybkości reakcji robota raczej nie zadziała poprawnie.

    Można uzyskać wysoką dokładność w przypadku GPS, taki sprzęt używany jest np. w geodezji - ale ceny są zupełnie inne niż w przypadku opisywanych modułów, czas pomiaru jest dość długi no i konieczny jest abonament na dane dla DGPS.

  4. Robiłeś może jakąś analizę dokładności danych z GPS? Pytam bo to dość mały robot i kilka metrów to dla niego spory dystans, a z moich doświadczeń z odbiornikami GPS otrzymywanie "szumu", który wygląda jak skoki po kilka metrów to normalne działanie. I bardzo mnie ciekawi jak sobie poradziłeś z tym problemem.

  5. Dobra, z tymi timerami to był zły pomysł - jednak na esp32 jest zupełnie inaczej niż na stm32, a mi się wszystko pomieszało 😞

    W każdym razie jak chodzi o gotowca to proponuję popatrzeć na kod biblioteki FabGL: https://github.com/fdivitto/FabGL

    Jest tam kod sterownika VGA, który wykorzystuje DMA, ale zamiast jak myślałem GPIO używane jest I2S - pozostaje przeanalizować kod, a może i przetestować.

    Tak jako ciekawostka, że ESP32 może faktycznie generować obraz VGA:

     

     

  6. Ja bym proponował zostawić DMA na moment i zacząć od czegoś prostszego, czyli timera. Niezależnie, czy używając DMA, czy CPU i tak konieczne jest ustalenie prędkości transmisji do wyświetlacza - podejście z liczeniem cykli maszynowych się nie sprawdzi, więc proponuję uruchomić timer i na początek programowo go używać. Czyli to co może zrobić DMA najpierw niech robi drugi rdzeń - jest nawet szansa, że to zadziała i DMA nie będzie niezbędne (chociaż zawsze warto czegoś nowego się nauczyć).

  7. Oczywiście, że taki sposób istnieje. Możesz po prostu wyrzucić FreeRTOS, przejąć pełną kontrolę i wszystko sam zrobić. Będzie to dość trudne, ale jak najbardziej możliwe.

    Wydaje mi się jednak, że po prostu źle do tego podchodzisz. W przypadku AVR takie sterowanie pinami mając policzone takty zegara działało - w nowszych układach będzie bardzo skomplikowane. O wiele łatwiej i dokładniej byłoby użyć do tego odpowiednich modułów peryferyjnych. Do odmierzania czasu - timer, a do transmisji DMA.

  8. Zakładałem że scheduler na ESP32 używa dwóch rdzeni i sam uruchomi zadanie na drugim. Ale możliwe, że to było zbyt optymistyczne założenie. Wydawało mi się, że użycie priorytetów jest mniej "inwazyjne" niż wskazywanie rdzenia, ale oczywiście użycie xTaskCreatePinnedToCore zadziała na pewno, a z priorytetami trzeba byłoby przetestować.

  9. Nie mieszajmy innym w głowie, czasem lepiej nic nie pisać niż pisać nieprawdziwe rzeczy. Wskaźnik i tablica to co innego w języku C, więc zapis

    const char *napis = "jakis napis";

    oraz:

    const char napis[] = "jakis napis";

    nie są równoważne, chociaż podobne. Zachęcam do poczytania podstaw języka C oraz sprawdzenia czym się różnią.

  10. Prawdopodobnie całe nieporozumienie wzięło się z warunku w pętli:

    for(t=0;t<=6;t++){
      

    Jak słusznie zauważył kolega @Hudyvolt, taka pętla wykona się 7 razy, za pierwszym razem t=0, a za ostatnim t=6, czyli t=0,1,2,3,4,5,6 daje razem 7. Powodem tego zamieszania jest użycie warunku <= (mniejszy-równy), popularniejsze jest używanie ostrej nierówności, czyli kodu:

    for(t=0;t<6;t++){
      

    Domyślam się, że o to chodziło autorowi tematu i taka postać jest używana znacznie częściej. Pętla chyba miała się wykonać 6 razy, czyli t=0,1,2,3,4,5 i wówczas po wyjściu z pętli wartość t wynosiłaby 6, a więc oryginalny warunek byłby spełniony.

  11. 18 minut temu, Hudyvolt napisał:

    Twoja pętla wykonuje się 7 razy. Warunek if(t==6) zawsze będzie prawdziwy, ponieważ z taką wartością pętla kończy pracę.

    Właśnie ten warunek raczej nigdy nie będzie prawdziwy... i dlatego program wchodzi do pętli for od nowa. Powinno być if (t==7), albo i zupełnie bez tego if-a.

    • Lubię! 2
  12. Nie wnikałem tak bardzo w wyrównywanie stosu na stm32, bo jak chodzi o tak niskopoziomowe programowanie zajmuję się cortex-a, a nie cortex-m. W każdym razie bardzo wątpię, żeby to co próbujesz zrobić było problemem. Przeczytaj sobie chociażby programming manual od stm32f10x: https://www.st.com/resource/en/programming_manual/cd00228163-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf

    "Unless stack alignment is disabled, the stack frame is aligned to a double-word address. If the STKALIGN bit of the Configuration Control Register (CCR) is set to 1, stack align adjustment is performed during stacking."

    Czyli jeśli nie wyłączyłeś wyrównywania to działa - a jak nie to zgłoś do ST że mają błąd.

    Wyrównywanie stosu oczywiście ma sens. Sprzętowo odkładane są rejestry, stos jest wyrównywany do 4, rejestry mają po 4 bajty, więc wszystko jest ok. Problemem jest dopiero kompilator. W przypadku cortex-a procedura obsługi przerwania jest pisana w asemblerze i wtedy wyrównanie do 4 jest wystarczające. Natomiast w przypadku cortex-m, procedury obsługiwania najczęściej pisze się w C, a kompilator zakłada że stos podczas wywołania jest wyrównany do 8. Jeśli nie jest to wygenerowany kod może działać niepoprawnie. 

    Nie znajdziesz raczej opisów kiedy taki kod powstaje bo to zależy od wszystkiego - wersji kompilatora, bibliotek, ustawień itd. Najmniejsza zmiana i możesz dostać odrobinę inny kod wynikowy, który już będzie działał.

    Ale żeby wyjaśnić na czym polega problem, wyobraźmy sobie następujący zupełnie sztuczny przykład. Mamy dwie zmienne lokalne, czyli jak wiemy zapisane na stosie, powiedzmy:

    uint32_t x,y;

    Teraz kompilator generuje kod odczytu powiedzmy x

    ldr r0, =<adr_x>

    Teraz można sobie do tego x pisać, czytać itd. wykorzystując adres zmiennej zapisany w rejestrze r0. Ale jak kod będzie chciał odwołać się do y, to musi obliczyć adres. Pewnie zrobiłby to inaczej, ale załóżmy że na danym systemie najszybciej działają proste operacje bitowe. Skoro kompilator zakłada, że stos jest wyrównywany do 8, więc adres zmiennej x ma najniższe bity równe 0. Mógłby więc wygenerować taki kod:

    orr r1, r0, #4

    Czyli do r1 wpisać (r0 or 4) - to zadziałą poprawnie jeśli x będzie miał adres wyrównany do 8, a po nim będzie y. Ale jeśli stos będzie wyrównany do 4, ten sam kod już zadziała źle.

    To oczywiście absolutnie sztuczny przykład, ale chodziło mi o pokazanie na czym polega problem - kompilator, albo raczej optymalizator zakłada że stos jest wyrównany do 8. Może więc wygenerować dziwny, ale optymalny kod, który działa tylko wtedy. A jeśli nie będzie wyrównywania to wszystko się posypie.

    • Lubię! 1
    • Pomogłeś! 1
  13. Znalazłem hat grove z którym mi się pomyliło: https://www.seeedstudio.com/GrovePi.html

    Nazwa podobna, a na nim wszystkie moduły są podpinane do atmegi, więc właściwie wychodzi z tego arduino podłączone do raspberry. Ale ten moduł z zestawy jest tańszy i prostszy, więc pozwala trochę lepiej poznać samą malinkę. Tylko trzeba pamiętać że pracuje tylko z 3.3V, a niektóre moduły grove wymagają 5V.

    Edit: Zestaw do nauki elektroniki to chyba faktycznie najlepszy pomysł - proponowałbym nawet więcej, na razie zamówić tylko ten zestaw, przerobić kurs, porobić trochę własnych eksperymentów. Będziesz wtedy wiedział lepiej co Cię interesuje i na co wydać resztę pieniędzy.

    • Lubię! 1
  14. Edit: Wcześniej nie miałem czasu dokładnie przejrzeć informacji akurat o tym shieldzie, a widziałem podobne z atmegą na pokładzie, gdzie wszystko było sterowane przez mikrokontroler. Tutaj wydaje się że jest lepiej, na pokładzie jest stm32f030, który służy głównie jako konwerter analogowo-cyfrowy, natomiast sporo pinów jest podpiętych bezpośrednio do malinki. Taki układ wygląda dużo ciekawiej, przepraszam jeśli wcześniej zbytnio namieszałem.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.