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

Atmega8 interpretator komend

wilk125 17 Sty 2010 13:27 1134 5
REKLAMA
  • #1 7548741
    wilk125
    Poziom 23  
    Witam
    Zrobiłem sobie taki interpretator poleceń, że jak po USART przyjdzie komenda (string zakończony odpowiednimi znakami) to zmienna read_line jest ustawiana na 1 , a następnie funkcja strncmp(...) porównuje odebrany string (bufor) z wpisaną na stałe komendą, jeśli wynik, któregoś z porównań będzie prawidłowy, to wykona sie żadany kod i program skoczy do etykiety poczatek, żeby nie tracić niepotrzebnie czasu na dalsze sprawdzanie. Moje pytanie jest takie czy znacie jakieś inne bardziej optymalne sposoby na taki interpreter? U mnie problemem jest to ,że jak będzie do sprawdzenia kilkadziesiąt lub więcej komend i zostanie odebrana akurat ta komenda która znajduje sie na końcu to program i tak będzie musiał sprawdzić wszystkie porównaia powyżej.
    
    
    while(1)
    {
    poczatek:
    
    if(read_line)
    	{         
             read_line=0;
    			
               		wynik=strncmp(bufor,"komenda1",8);
    			if(wynik==0)
    			
    			{
    				
    				//wykonuje jakies operacje
    			 	goto pocztek;
    			}
                           wynik=strncmp(bufor,"komenda2",8);
    			if(wynik==0)
    			
    			{
    				
    				//wykonuje jakies operacje
    			 	goto pocztek;
    			}
                             wynik=strncmp(bufor,"komenda3",8);
    			if(wynik==0)
    			
    			{
    				
    				//wykonuje jakies operacje
    			 	goto pocztek;
    			}
    
            }
    }
    
  • REKLAMA
  • Pomocny post
    #2 7548776
    mirekk36
    Poziom 42  
    sposobów jest milion różnych

    ale tak na szybciora żeby coś uprościć to można np takie komendy trzymać w tablicy i po sprawdzeniu przekazywać tylko do polecenia switch index komendy. Ale i tak będzie trzeba zrobić jakąś pętelkę, która zawsze sprawdzi czy to któreś polecenie z tablicy. Z tym że późniejsza obsługa tego się już upraszcza w tym dodawanie komend do tablicy itp. A indeksy można później też dla ułatwienia zdefiniować sobie jako typ "enum"
  • REKLAMA
  • Pomocny post
    #3 7549351
    tmf
    VIP Zasłużony dla elektroda
    komendy mozna zastapic tokenami, ktore sa indeksami do tablicy zawierajacej adres funkcji realizujacej dana komende. Czyli pobierasz token (np. 8-bitowy, jesli komend jest mniej niz 256), odczytujesz adres funkcji z tablicy pod tym indeksem i ja wywolujesz. Dzieki temu nic nie musisz sprawdzac, a kazda komenda jest wykonywana z takim samym opoznieniem. Jesli to musza byc komendy slowne, to stworz posrednia tablice zawierajaca posortowane komendy. Wtedy szukasz komendy literka po literce (tu masz porownan max tyle ile liter ma najdluzsza komenda). Numer znalezionego polecenia jest indeksem do tablicy adresow jak w poprzednim rozwiazaniu.
  • REKLAMA
  • #4 7549414
    Dr.Vee
    VIP Zasłużony dla elektroda
    Najpierw zastanów się, czy wyszukiwanie komendy jest rzeczywiście krytyczną operacją w Twoim kodzie - może nie ma to znaczenia przy prędkości UARTA?

    Prostszym sposobem byłoby utworzenie z listy napisów drzewa binarnego - wtedy wyszukanie byłoby O(m*log n) albo O(log n) zamiast O(m * n) w Twoim przypadku. Użycie tablicy komend nie poprawi tutaj wydajności.

    Edit: fakt, binarne wyszukiwanie w posortowanej tablicy też by zdało egzamin i byłoby kompromisem pomiędzy drzewem a wyszukiwaniem liniowym.

    Możesz też użyć generatora lekserów, takiego jak http://re2c.org/, żeby wygenerował zoptymalizowany kod rozpoznający zbiór zadanych sekwencji za Ciebie.

    Pozdrawiam,
    Dr.Vee
  • REKLAMA
  • #5 7552988
    wilk125
    Poziom 23  
    Dr.Vee napisał:
    Najpierw zastanów się, czy wyszukiwanie komendy jest rzeczywiście krytyczną operacją w Twoim kodzie - może nie ma to znaczenia przy prędkości UARTA?
    Dr.Vee

    To fakt, problemem nie jest szybkość,a raczej wielkość kodu, dla zaoszczędzenia pamięci RAM wszystkie komendy umieściłem w pamięci flash i do porównania użyłem funkcji strncmp_P(..). Zastanawiam się jak by można było jeszcze zaoszczędzić pamieć flash. Dodam jeszcze, że tokeny nie wchodzą w grę bo komendy wysyła urządzenie i nie mam na nie wpływu, dokładnie są to komendy AT z modułu GSM SIM300D.
  • Pomocny post
    #6 7556158
    Dr.Vee
    VIP Zasłużony dla elektroda
    Możesz jeszcze zastosować haszowanie do 8 lub 16 bitów, wtedy jedna komenda zajmie odpowiednio 3 lub 4 bajty (hasz + wskaźnik na funkcję).
    Dobierasz takie haszowanie, żeby dla zestawu Twoich komend nie było kolizji.

    Pozdrawiam,
    Dr.Vee
REKLAMA