Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[bascom] optymalizacja kodu, select case

manekinen 03 Jun 2010 11:49 5851 19
  • #1
    manekinen
    Level 29  
    Hej,

    Potrzebuję troszkę zoptymalizować kod. Ten fragment "wyszukuje" właściwy procek po sygnaturze, najpierw podział na pojemność flasha na podstawie drugiego bajtu sygnatury, a następnie już konkretny model na podstawie trzeciego bajtu sygnatury. Po trafieniu we właściwe miejsce ustala wartości fusebitów i wysyła po uarcie nazwę procka...

    Fragment kodu
    Code:

    Select Case Signature(2)

       '512B memory chips:
       Case &H8F

       '1kB memory chips:
       Case &H90
          Select Case Signature(3)
             Case &H01
                Print "AT90s1200"
                W_fusebit(1) = &HDF



             End Select

       '2kB memory chips:
       Case &H91
          Select Case Signature(3)

              Case &H05
                Print "AT90s2333"
                W_fusebit(1) = &HDA

             Case &H0A
                Print "Attiny2313"
                W_fusebit(1) = &H64
                W_fusebit(2) = &HDF
                W_fusebit(3) = &HFF
                Set Extended

             Case &H09
                Print "Attiny26"
                W_fusebit(1) = &HE1
                W_fusebit(2) = &HF7
    [...]
          End Select
    End Select

    Chodzi o to że w ten sposób mam zapisanych prawie 100 procków, i to całe select case zajmuje zbyt dużo miejsca jak na megę8. Potrzebuję pomysłu jak to zoptymalizować, muszę zyskać choć 1kB :) Możnaby to upchać w jakąś tablicę, ale nie wiem jak wtedy zrealizować wysyłanie nazwy po uarcie...

    Pozdr.
    [28-30.06.2022, targi] PowerUP EXPO 2022 - zasilanie w elektronice. Zarejestruj się za darmo
  • Helpful post
    #2
    tadzik85
    Level 38  
    Ja na twoim miejscu zoptymalizowałbym napisy.
  • #3
    manekinen
    Level 29  
    Jakiś przykład? Myślałem nad Lookup dla danych oraz Lookupstr dla napisów, problem jest taki że mam dwie zmienne na podstawie których muszę odnaleźć procek :/
  • #4
    tadzik85
    Level 38  
    napis ATTINY powiela się, ja zrobiłbym jakiś konstant z tego. I w każdym casie dopisywał jedynie numer
  • #5
    manekinen
    Level 29  
    No tak, ale obawiam się że niewiele to da. Nawet jak dam na końcu jeden print i w nim będe sklejał i wysyłał tą nazwę, to tak czy siak za każdym razem gdy odnajdę procek będe musiał wpisywać pozostałą część nazwy w zmienną.

    Szukam sposobu aby całkowicie się pozbyć tego select case :)

    Dodano po 9 [minuty]:

    Ok, zmienne Signature(2) oraz Signature(3) sklejam razem i tworzę zmienną 16bit która będzie niepowtarzalna dla jakiejkolwiek kombinacji tych dwóch pierwszych. Dane z fusebitami odczytam z tablicy za pomocą Lookup, ale polecenie Lookupstr przyjmie maksymalnie 8bitowy adres dla tablicy no i d... blada.
  • #6
    tadzik85
    Level 38  
    Quote:
    Nawet jak dam na końcu jeden print i w nim będe sklejał i wysyłał tą nazwę, to tak czy siak za każdym razem gdy odnajdę procek będe musiał wpisywać pozostałą część nazwy w zmienną.
    Wypowiedź moim zdaniem bez sensu. Napisy są strasznie pamięciożerne. Jeśli nie case to ify a może jakaś arytmetyka. A może coś zapisać w eeprom na stałe. Np. te napisy.
  • #7
    manekinen
    Level 29  
    Troszkę się nie zrozumieliśmy, miałem na myśli wyświetlanie napisu dopiero na końcu tak aby nie powielać tego polecenia print. Wtedy zamiast print przepisywałbym do zmiennej jedynie numerek a na końcu (po całym select case) sklejał w jednym poleceniu print całość, czyli przedrostek ze stałej i numerek ze zmiennej. Sytuacja wygląda tak że mam 6 przedrostków i dodatkowo musiałbym za każdym razem ustawiać dodatkową zmienną aby na końcu wiedzieć którego użyć

    Attiny
    Atmega
    AT90s
    AT90pwm
    AT90usb
    AT90can

    Więc zrobię tak jak piszesz, będe wyświetlał od razu tyle że przedrostki ze stałych. A napisów faktycznie mam sporo, spróbuję to wszystko w eeprom wrzucić. Choć pozbycie się tego select case byłoby dobrą sprawą :)
  • #9
    manekinen
    Level 29  
    Code:

    Const Atmega = "Atmega"
    Const Attiny = "Attiny"
    Const At90s = "AT90s"
    Const At90pwm = "AT90pwm"
    Const At90usb = "AT90usb"
    Const At90can = "AT90can"

    A następnie dla każdego procka przedrostek biorę ze stałej i doklepuję numerek
    Code:

    Print Atmega ; "8U2"


    Wcale nie generuje mniejszego kodu, ba, o 16 bajtów większy! Nie wiem jakim cudem, zaglądałem w wynikowy BIN i jest tak jak ma być czyli same "końcówki". Nie wiem co ten bascom zrobił z zaoszczędzonym miejscem :/
  • #10
    tadzik85
    Level 38  
    Jeśli konkretne bajty znajdują się w jakiś przedziałach, a nie są rozrzucone po całym zakresie zmiennej bajt, można pokusić się o ztablicowanie Fusów.
  • #11
    atom1477
    Level 43  
    Bo Const to stała a Ty potrzebujesz czegoś jak DB albo PROGMEM. Czyli danych umieszczonych w pamięci.
    A stała niekoniecznie będzie tam umieszczona. Stała może być np. wbudowana w rozkaz assemblera (akurat nie tutaj ale inaczej to może być).
    Zrób raczej tak:
    Code:

    Dim Atmega As String
    Dim Attiny As String
    Atmega  = "Atmega"
    Attiny = "Attiny"


    Print Atmega ; "8U2"


    W BASCOMie raczej inaczej nie uda Ci się tego bardziej zoptymalizować.
    Chyba że jeszcze tak:
    Code:

    Gosub Print_Atmega
    Print "8U2"

    ...
    ...

    Print_Atmega:
    Print "Atmega"         'Tutaj coś trzeba dodać żeby nie wysyłało entera, ale nie pamiętam co.
    Return
    Print_Attiny:
    Print "Attiny"         'Tutaj coś trzeba dodać żeby nie wysyłało entera, ale nie pamiętam co.
    Return
  • #12
    manekinen
    Level 29  
    W taki sposób kod jest jeszcze większy. Ale tamten ze stałymi tez jest ok bo po kompilacji wygląda to tak:
    [bascom] optymalizacja kodu, select case

    Wcześniej gdy wysyłałem całe napisy a program był o 16 bajtów mniejszy:
    [bascom] optymalizacja kodu, select case

    Bascom chyba całe uzyskane miejsce wykorzystał na sklejanie tych napisów, ehh. I nic dziwnego, skoro powtarzam to samo prawie 100 razy w kodzie.

    Z adresowaniem tablicy będe miał taki problem że po sklejeniu np 92h jako drugiego bajtu sygnatury z np 01h jako trzeciego bajtu sygnatury, dostanę adres 37377 od którego w ogóle zaczną się dane. No to sobie odejmę, nie szkodzi. Problem taki że musiałbym przeznaczyć po 4 bajty dla każdego procka, trzy bajty na fuski oraz czwarty z flagą że występuje bajt extended lub nie (chociaż to by dało się obejść, sprawdzałbym trzeci bajt fusków czy nie jest zerem). Ale jeśli będzie kolejny procek z 4kB flash czyli oznaczenie 92h, i z trzecim bajtem sygnatury 02h, to jego adres w tablicy zacznie się na 37338 i wejdzie na dane poprzedniego procka - więc chyba nie mam co walczyć z tymi tablicami :(

    BTW, to właśnie znak ; dopisany na końcu powoduje że nie są wysyłane znaki CR i LF przenoszące kursor na nową linię.
  • #13
    tadzik85
    Level 38  
    To zamiast robić jedna wielką tablice zrób kilka mniejszych :d
  • #14
    manekinen
    Level 29  
    Inne napisy umieściłem w eeprom, zyskałem jakieś 400 bajtów miejsca. Z nazwami procków kombinowałem już na wszystkie sposoby, no i niestety nie zrobiłem tego... każdy jeden wpis "Print "napis"" kosztuje mnie 18 bajtów (w tym 9 bajtów sam napis), gdy np chcę przepisywać napisy do zmiennej string i na końcu wyświetlać - wychodzi po 20 bajtów na każdy jeden. Tablica z napisami kosztuje po 16 bajtów dla każdego, zamiast każdego printa wpisuje do zmiennej byte adres napisu w tablicy, ale niestety adres szybko doszedł do 255 - jeśli chciałem użyć dwubajtowego, to każde wpisywanie adresu zabierało nie 6 ale 12 bajtów programu i jak by nie zrobil to wychodziła kaszana - tak więc zostało print w każdym case. Około połowa procesorów nie ma nazwy. Problem nie rozwiązany, gdyby ktoś miał pomysł jaką sztuczkę zastosować z tymi nazwami lub jak się pozbyć select case to chętnie wysłucham ;) (za porady "przepisz do C" podziękuję ;) )
  • #16
    gaskoin
    Level 38  
    to moze napisz program w kodzie maszynowym ?
  • #17
    asembler
    Level 32  
    Nie wiem jak to w BASCOMie daloby sie napisac pewnie samą ideę mozna by przekopiowac, ale u mnie na wyszukiwanie dowolnego procesora zużyłem 22 bajty oczywiscie nie licząc tablicy w której sązakodowane procesory w której to tablicy na jeden procesor przypada od 4 do 6 bajtów a poniewaz tablice umieszczam w RAM-ie po zczytaniu z karty MMC to w sumie podprogram wyszukujący ma 22 bajty

    A tak swoją drogą mógłbys podesłac swoją tablice procesorów gdyż moja jest niekompletna komletnie. Z góry dziękuje.
  • #18
    piotr5000
    Level 21  
    Kolego Manekinen a dokąd wysyłasz te dane printem , bo jeśli do PeCeta to tam dokononaj konwersji . Wysyłałbyś tylko sygnatury!
  • #19
    manekinen
    Level 29  
    asembler ahh, karta sd :) Ja wszystko wcisnąłem we flash, może kiedyś zasiądę porządnie to znajdę coś do zoptymalizowania, albo użyję megi168.
    Tzn prosisz o całe zestawienie sygnatur plus fusków dla wszystkich procków? Sorki ale niestety nie mogę tego zrobić :( Wyłuskiwałem je ręcznie z not katalogowych, bo po zauważeniu ile błędów ma np taki kalkulator na engbedded.com zrozumiałem że więcej czasu zajmą mi poprawki gotowców niż stworzenie wszystkiego od nowa :(


    piotr5000 w sumie na cokolwiek co odbierze tą transmisję. Nie chciałbym zmuszać kogoś do używania dodatkowego programu na PC jeszcze. A po za tym program wysyła także sygnatury i wszystko co możliwe, nazwy to tylko mało znaczący bajer, ale kod tak czy siak chciałbym ścisnąć bardziej bo dojdą kolejne procki i trzeba będzie je dodać gdzieś :/
  • #20
    rpal
    Level 27  
    Na czym kolega chce generalnie zaoszczędzić ? Jak masz za mało flash-a aby wetknąc tam więcej napisów to po prostu zastosuje większy procesor będzie i tak prościej niż dokładanie jakiś zewnętrznych pamięci. Choć przyznam że trochę mnie dziwi problem jej braku. Piszesz może od nowa Windows na AVR-a ? :)