logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

jak najszybciej odczytywać dane

arturromarr 25 Sie 2011 17:32 1928 10
  • #1 9862104
    arturromarr
    Poziom 17  
    Witam
    Mam pewnien "akademicki" temat do wykonania na AVRze.
    Potrzebuje zrobić prosty interpreter własnego bardzo prymitywnego języka.
    Program będzie zapisany na twałe w pamięci eprom.
    Chciałbym uzyskać możliwe szybkie wykonanie pętli programu dlatego rozważam zastodowanie zewnętrznego ramu z równoległym dostępem do którego był by przepisany program po starcie, przepisywanie do wewnętrznego ramu lub odczytywanie bezpośrednio z epromu jeśli nie jest dużo wolniejsze.
    Zastanawiam się jak wygląda porównie szybkości odczytu pamięci z epromu Atmela Megi, z jej wewnętrznym ramem i ewentualnie zewnętrzym ramem czyli defakto szybkości portów.
    Bardzo prosze o podzilenie się jakimiś doświadczeniami w takiej tematyce.
  • #2 9862241
    BoskiDialer
    Poziom 34  
    Dostęp do pamięci ram (wewnętrzna/zewnętrzna): 2 cykle (o ile pamięć zewnętrzna jest podłączona do dedykowanego interfejsu).
    Odczyt z pamięci eeprom: chyba coś koło 8 cykli (wpisanie adresu 2ck, wpisanie polecenia odczytu 1ck, wymuszone zatrzymanie procesora na 4ck, odczyt bajtu 1ck)
    Odczyt z pamięci flash: 3 cykle.

    Największa zaleta zewnętrznego ramu jest taka, że można raz przenieść cały interpretowany program do pamięci (której, jeśli jest zewnętrzna, jest zwykle znacząco więcej niż wewnętrznej), po czym nie trzeba dodatkowo kombinować z dostępem - można używać wskaźników do operowania na ciągach znaków.

    Inna możliwość, to mając już jakiś prosty język, można go kompilować w locie podczas przenoszenia z pamięci eeprom do ramu (pojedynczy przebieg: generowanie kodu + tablica nierozwiązanych etykiet + tablica znanych etykiet). Zaletą jest jednokrotne parsowanie (unika się ciągłego przetwarzania ciągów znaków), bardzo duża szybkość (w pamięci opcode zapisane w postaci binarnej, można używać switch'a), szybkie skoki (adresy absolutne wpisane do wygenerowanego kodu po parsowaniu, więc nie trzeba szukać ponownie etykiet).

    Oczywiście najłatwiejszy do zaimplementowania język będzie czymś pokroju asemblera - poszczególne instrukcje podawane jawnie, brak struktur typu warunki i pętle - trzeba generować jawnie za pomocą testów i skoków do etykiet. Można dodać składnię warunków i pętli, co odrobinę skomplikuje parser (konieczność śledzenia otwartych struktur oraz generowanie otoczki przez instrukcje). Języki pokroju asemblera są o tyle łatwe w parsowaniu, że można je parsować mając prostą funkcję wyciągającą n-ty wyraz z danej linii, wyciągając pierwszy wyraz można ustalić co to za instrukcja, na jej podstawie wyciągnąć odpowiednie następne wyrazy i przetwarzać je.
  • #3 9862259
    tmf
    VIP Zasłużony dla elektroda
    Sprecyzuj pytanie o jaki AVR chodzi. Bo np. dostęp do EEPROM w XMega jest znacząco inny niż w innych typach AVRów.Podobnie dostęp do zewnętrznej pamięci SRAM (tu też wszystko zależy co to za pamięć).
  • #4 9867339
    arturromarr
    Poziom 17  
    Dziękuję za odpowiedzi.
    Procesorem będzie jakaś mega128.
    Rozumiem że mówicie o odczycie w asemblerze, jak by to wyglącało gdy będę korzystał z "C", czy kompilator spowoduje jakieś spowolnienie?
    Od dawna myślałem o napisaniu czegoś na wzór własnego języka i chciałem się z tym zmierzyć dla wartości poznawczej.
    Zastanawiam się czy są jakieś "szkoły" w podejściu do tematu, ale jezyki interpretowalne to nisza i ciężko coś znaleźć.
    Z tego co piszecie to nie ma co sobie zawracać głowy i czytać program bezpośrednio z wewnętrznego, epromu? Całość itak nie będzie błyskawicą więc takie czasy odczytu nie powinny mocno rzutować na prędkość pętli programu?
  • #5 9870252
    Slkkk
    Poziom 14  
    Czy są szkoły... Są przede wszystkim gotowe programy do tworzenia interpreterów/kompilatorów, takie jak np. flex + bison :). Swoją drogą to ciekawe, czy kod wygenerowany przez nie dałoby się upchnąć w ATmedze :)
  • #6 9871182
    arturromarr
    Poziom 17  
    Tak ale ja nie chcę gotowego rozwiązania :)
    Chciałem się sam zmierzyć z tematem dla celów poznawczych.
    Zastanawiam sie jak rozlokować zmienne prgramu.
    program mógłby byż zapisywany od początku pomięci a zmienne od końca, do momentu wypełnienia całej.
    Zastanawiam się czy na początku określić komórki pamięci dla wszystkich zmiennych czy (chyba byłby większy porządek) czy w trakcie dynamicznie je dodawać. Może się okazać że potrzebna będzie duża ilość zmiennych pomocniczych (może trzeba taki typ stworzyć) przy wywoływaniu funkcji przez funkcję itd... Cziekawi mnie czy są jakieś sprawdzone już metody. Pewnie inne podejścia są skuteczne dla języków inerpretowanych a inne dla kompilowanych.
    Nie jestem informatykiem z wykształcenia i pewnie brakuje mi podstaw (stąd moje tak postawowe pytania) ale temat mnie ciekawi i chciałbym coś prostego napisać i nauczyć się przy tym nowych rzeczy.
  • #7 9874572
    Slkkk
    Poziom 14  
    Oj, ale te rozwiązania to nie żadne gotowce, tylko profesjonalne narzędzia, które wspomagają tworzenie programów przetwarzających języki. Ot choćby PHP, Ruby czy Perl korzystają z parserów generowanych przez yacc/bison. Jeśli ktoś lubi oglądać takie wnętrzności, to plik Bisona generujący parser PHP mamy tutaj: https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y
    Jednak jeśli interpreter ma działać na procesorku takim jak ATmega, to raczej się nie przydadzą, gdyż generują kod bardzo ochoczo korzystający z pamięci operacyjnej. 1 kB to raczej za mało, jak wiadomo dopiero 640 kB wystarczy każdemu...

    A jeśli chodzi o organizację pamięci podczas wykonywania programu, to najbardziej typowe rozwiązanie to takie, że na początku umieszczony jest kod programu i zmienne globalne, dalej jest sterta na zmienne alokowane dynamicznie w czasie pracy, a na końcu pamięci stos wywołań funkcji, który rośnie sobie w kierunku sterty (mając nadzieję, że się nigdy nie spotkają :)) i przechowuje zmienne lokalne oraz adresy powrotu z funkcji, co pozwala funkcjom dowolnie nawzajem się wywoływać.
  • #8 9875196
    INTOUCH
    Poziom 30  
    Witam.
    Pozwolicie że dołączę się do tematu.
    Ostatnio zastanawiam się nad realizacją przekaźnika programowalnego opartego na ATMEGAxxx. Moje założenia to:
    Program główny (interpreter języka logicznego) będzie wgrany do pamięci FLASH.
    Kod wykonywany przez interpreter będzie znajdował się na karcie SD.
    Kod kod z karty SD będzie wykonywany linijka po linijce z wyjątkiem "skoków bezwarunkowych".
    Zastanawiam się czy można by cały interpretowany kod umieścić w pamięci RAM żeby się szybciej wykonywał, czy cały czas odczytywać poszczególne komendy kodu z karty SD.
    Kod będzie zawarty w pliku tekstowym.
    Jeżeli kod interpretowany będzie wykonywany z prędkością równą 1/4 prędkości taktowania mikrokontrolera uznam to za duży sukces.



    Przykład.


    A0=1to B0=0 i B1=1

    A- wejścia
    B- wyjścia
  • #9 9875229
    Slkkk
    Poziom 14  
    Takie rozwiązanie, które na starcie kopiuje do RAM cały kod programu, będzie łatwiejsze do napisania, ale wielkość kodu będzie wtedy ograniczona przez ilość dostępnej pamięci (np. 1 kB w tanich ATmegach). To więc zależy od tego, jakie programy chcesz interpretować.
REKLAMA