<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    Nepochybně ten nárůst kvůli knihovně nebude velký, ale sám jste
    psal, že to větší bylo:-)<br>
    V podstatě je tam několik věcí, které zvětšení způsobují (a třeba i
    nějaké další):<br>
    1. Separátně kompilovaná knihovna: Optimalizace překladu celku by
    třeba našla společné sekvence a tím ušetřila. Tohle ale nenastane.<br>
    2. Obecné vložení cizího kódu: Styl kódu je jiný, tak se snižuje
    pravděpodobnost, že kompilátor najde společné sekvence.<br>
    <br>
    ><font face="Arial">několikrát za sebou použije buf[i]<br>
      <br>
      Nejsem si 100% jist, ale očekával bych, že tohle závisí na
      nastavení optimalizace a jak pak překladač uzná za vhodné. A že
      šance na registr se dá zvýšit slovem register v deklaraci.<br>
    </font><br>
    PH<br>
    <br>
    <div class="moz-cite-prefix">Dne 21.04.2024 v 10:12 Martin Záruba
      napsal(a):<br>
    </div>
    <blockquote type="cite"
      cite="mid:ad05c63c-19ec-43ed-be6f-96709c5490ab@volny.cz">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p><font face="Arial">Myslím, že to s dobře napsanou knihovnou
          nebude tak hrozné. Všimněte si, že když napíšete funkci, ale
          pak ji nepoužijete, zkontroluje se sice na syntaktickou
          správnost, ale pak nezabírá žádný prostor v paměti.</font></p>
      <p><font face="Arial">Stále váhám, zda pro 100byte buffer, který
          je v tiskové rutině, takže asi nehrozí, že by bylo nutné, aby
          rutina byla reentrantní je vhodné použít malloc. Ten problém,
          co píšete, se tam asi nemůže stát a rutina se tím stane
          univerzální a bude vždy zabírat jen tak nejméně statické
          paměti, jak je nutné. Ale zase bude mít delší kód.</font></p>
      <p><font face="Arial">Nevíte zda jestliže se několikrát za sebou
          použije buf[i] bude se index pokaždé počítat nebo si
          kompilátor uloží index do registru? A co třeba proměnné cyklu?
          Jsou v paměti nebo v registrech?</font></p>
      <p><font face="Arial">Vím, že to tu někdo psal, ale nemohu to
          najít, jak získat výpis assembleru. Holt mých asi 10 různých
          assemblerů, které jsem se v životě učil mi možná v těch
          vyšších jazycích chybí.<br>
        </font></p>
      <pre class="moz-signature" cols="72">Martin Záruba</pre>
      <div class="moz-cite-prefix">Dne 20.4.2024 v 23:27 Pavel Hudeček
        napsal(a):<br>
      </div>
      <blockquote type="cite"
        cite="mid:b01b7f84-7e73-407b-b567-dbd0f77e05e7@seznam.cz">
        <meta http-equiv="Content-Type"
          content="text/html; charset=UTF-8">
        Posledně jsem nějak zapomněl na poslední dva:-)<br>
        Teď jsem hledal jak se jmenuje to se stringem ve flash..<br>
        <br>
        <font face="Arial">> ultoa()</font><br>
        Jakmile chci do výsledku něčeho jinak celkem jednoduchého
        zasáhnout, je obvykle lepší to mít celé svoje. A když z
        univerzální knihovny použiju jen jednu funkci, často sežere o
        dost víc než když mám svoji. <br>
        <br>
        <font face="Arial">> pole buf pomocí malloc</font><br>
        To samozřejmě jde a může ušetřit prostředky, jen je nutná jistá
        míra opatrnosti. Malloc/free v rámci blokující funkce je obvykle
        bezproblémové.<br>
        <br>
        Je dobré se vyhnout situaci, kdy probíhají asynchronní malloc a
        free na více místech. Když alokuju jeden kus, pak druhý, pak
        vrátím první a pak třeba alokuju jinej kus, kterej může bejt
        větší a současně alokovaných kusů může bejt hodně. To vede k
        fragmentaci volného místa, až nakonec malloc vrátí NULL, protože
        požadovaná paměť není k dispozici v celku. Typický problém třeba
        u příjmu komunikačních paketů s pozdějším zpracováním v jiném
        pořadí. I s tím se žít dá, jen se prostě musí počítat se
        situací, že malloc paměť nedá (na PC mám vždy if, jestli se to
        povedlo) a potom adekvátně reagovat.<br>
        <br>
        PH<br>
        <br>
        <div class="moz-cite-prefix">Dne 20.04.2024 v 14:01 Martin
          Záruba napsal(a):<br>
        </div>
        <blockquote type="cite"
          cite="mid:07035d67-bd13-4ca5-8b45-c6fcaf944dee@volny.cz">
          <meta http-equiv="Content-Type"
            content="text/html; charset=UTF-8">
          <p><font face="Arial">Nojo, jenže pak s tím neuděláte tabulku.
              Je potřeba, aby například pokud je hodnota 3753, napsalo
              to |3753mV| ale pokud je 53, napsalo to |  53mV| a ne
              |53mV|. Tedy aby celý řetězec (včetně toho mV) byl stále
              (například) 6 znaků.<br>
            </font></p>
          <p><font face="Arial">Zkusil jste, kolik to zabere paměti?
              Podle toho, co píšete to dělá převod na float. To ale na
              osmibitu je hrůza. Já si hraju jen s "grafikou". Číslo
              stále dělím deseti, to je i na osmibitu snadné. A vypisuji
              zbytek po dělení. No a někam vrazím jakoukoli "výplň",
              třeba tu tečku. Pak to vypadá jako desetinné číslo, které
              ale je v celočíselném formátu uloženo třeba 10x 100x nebo
              jak se chce větší, což je myslím ten nejefektivnější
              způsob, jak na malinkém procesoru zobrazit desetinné
              číslo.</font></p>
          <p><font face="Arial">Zkoušel jsem také použít ultoa(). Ale je
              to větší a stejně musíte výsledek formátovat.</font></p>
          <p><font face="Arial">Napadlo mě ještě nejprve první smyčkou
              zjistit délku masky a pak nadefinovat pole buf pomocí
              malloc. A na konci ho uvolnit. Pak by většinou bylo
              malinké. Co si myslíte o tomto nápadu? <br>
            </font></p>
          <pre class="moz-signature" cols="72">Martin Záruba</pre>
          <div class="moz-cite-prefix">Dne 20.4.2024 v 12:29 Pavel
            Hudeček napsal(a):<br>
          </div>
          <blockquote type="cite"
            cite="mid:674463bf-438e-4e67-88aa-34cf0e2f0c10@seznam.cz">
            <meta http-equiv="Content-Type"
              content="text/html; charset=UTF-8">
            Ne, v mém příkladu je přeci stav uBat1=3753,
            tak uartSend("\1mV", adUbat1, 0); vypíše 3753mV<br>
            Pokud by adUbat bylo 53, vypíše 53mV<br>
            a pokud by bylo zadáno uartSend("\1mV", adUbat1, 3);<br>
            vyleze 3753,000mV<br>
            nebo třeba 3753,001, pokud float hodnota nevyšla přesně
            3753,000<br>
            <br>
            Nějak tak to fungovalo, už je to dlouho.<br>
            Ale jak se tu o tom teď diskutuje a ještě jsme na kroužku
            došli k sériáku, tak si asi konečně udělám tu knihovnu, kde
            tohle bude jedno z přetížení.<br>
            <br>
            PH<br>
            <br>
            <div class="moz-cite-prefix">Dne 20.04.2024 v 11:27 Martin
              Záruba napsal(a):<br>
            </div>
            <blockquote type="cite"
              cite="mid:62da3616-1d24-431d-9cf0-0c397e03b07f@volny.cz">
              <meta http-equiv="Content-Type"
                content="text/html; charset=UTF-8">
              <p><font face="Arial">Jen dotaz: Co vypíše:</font></p>
              <p><font face="Arial">uBat1 je 53</font></p>
              <p><font face="Arial">uartSend("\1mV",adUbat1,0);<br>
                </font></p>
              <p><font face="Arial">nevypíše to</font></p>
              <p><font face="Arial">53mV      ?</font></p>
              <pre class="moz-signature" cols="72">Martin Záruba</pre>
              <div class="moz-cite-prefix">Dne 20.4.2024 v 10:36 Pavel
                Hudeček napsal(a):<br>
              </div>
              <blockquote type="cite"
cite="mid:cafe8589-63d8-448f-9f19-eb19f16669d4@seznam.cz">
                <meta http-equiv="Content-Type"
                  content="text/html; charset=UTF-8">
                Tady asi došlo k mírnému nedorozumění:<br>
                Oba umíme zobrazit jen jednu hodnotu.<br>
                Oba umíme požadovaný počet des. míst.<br>
                Oba umíme text před ním i po něm.<br>
                Já nemám formátování tisíců, ale zas můžu ve výstupním
                textu použít #.<br>
                Zas to formátování s # se asi dá ohackovat, že zobrazí
                třeba 2 čísla zakódovaný do jednoho longu?<br>
                <br>
                // adUin je 12,3456  uBat1 je 3753<br>
                // UART_sendDT je ','  UART_sendPosChr je '\1'<br>
                uartSend("Uin=\1 V\n", adUin, 2);<br>
                uartSend("\1mV", adUbat1, 0);<br>
                výsledek je:<br>
                Uin=12,34 V<br>
                3753mV<br>
                <br>
                Ten uartSend byl trochu prasáckej, mist nakopíruje do
                globální uartSendMist a pak zavolá cislo((long)(v * m)),
                kde m je třeba 1000 pro mist=3. A cislo pak do
                požadovaného místa vnutí oddělovač a uartSendMist
                vynuluje. Tohle jsem už někde měl i na ty tisíce, jen se
                to nevypínalo samo.<br>
                <br>
                Chystám se že bych si z těhle věcí konečně udělal
                nějakou knihovnu, zatím to jen kopíruju mezi projekty a
                nejčastějc si vystačím s putchar2, text na poslání textu
                a cislo na poslání longu.<br>
                takže posledně to bylo ve stylu<br>
                text("Uin=");
                cislo(static_cast<long>(1000.0*adUin)); text("
                mV\r\n");<br>
                <br>
                Buffer je na zásobníku, takže sám vznikne a sám zmizí.<br>
                Ale 100 B, to je 20 % RAMky na ATtiny816, což je hodně,
                případně 1,25 % na AVR64DD32, to už by bylo v pohodě.<br>
                Mě se to obecně nelíbí, protože rád používám děje na
                pozadí. Funkce cekej(uint32_t ms) je i víc než půlka
                programu a pokud možno všechno čekání volá aspoň
                cekej(0). No a když se těch čekání sejde více takových,
                kde mezitím vzniknul buffer..<br>
                Takže mám snahu takové buffery nedělat.<br>
                Další věc je, že mám snahu minimalizovat místa, kde je
                potřeba omezovat velikost stringu. Takže mě stačí buffer
                na 10B celej vstup může mít 254, výstup až 264 a ve
                verzi s txtPred + txtPo můžou klidně oba texty mít do
                254.<br>
                <br>
                Ovšem to s F a PSTR je pro mě novinka, za to díky.<br>
                <br>
                Byl jsem zvyklý na codevision, tam se daly deklarovat
                proměnné do RAM, EEPROM i Flash, "text" byl ve flash a
                všechno fungovalo do velké míry samo, včetně toho, že v
                EEPROM je pointer do flash. Super věc, pokud se po
                kompilaci k binárce sprostě přikopírujou UTF8 texty ve 4
                jazycích a za ně bitmapa fontů. Při prvním spuštění
                program ve flash najde "Tady>>>", pak dohledá
                začátky jazyků, hlášky v default jazyku a nakonec font.
                Pointery hodí do EEPROM a odteď se může na displeji 10
                ms po zapnutí objevit třeba normální čeština.<br>
                A v případě GCC jsem si myslel, že nic už takhle
                elegantně nepůjde.<br>
                Vlastně opravdu nejde, protože si sice můžu nadeklarovat
                proměnnou v EEPROM, ale nemůžu jí přímo používat, jen
                přes funkce na čtení a zápis EEPROM, který maj navíc
                hrozně dlouhý názvy. "Super" do vzorce se 3 kalibračníma
                konstantama.<br>
                Tak aspoň snad zas můžu mít texty ve flash:-)<br>
                <br>
                PH<br>
                <br>
                <div class="moz-cite-prefix">Dne 19.04.2024 v 21:23
                  Martin Záruba napsal(a):<br>
                </div>
                <blockquote type="cite"
cite="mid:ab12d61f-7c9b-4434-9138-43db4d9875b4@volny.cz">
                  <meta http-equiv="Content-Type"
                    content="text/html; charset=UTF-8">
                  <p><font face="Arial">Já to tak původně dělal, jenže
                      byl to mnohem složitější a vlastně můžete takto
                      udělat jen část než narazíte na první formátovací
                      znak. Pak už je to stejně jen odeslání čísla.
                      protože nevíte, zda nebude následovat další
                      formátovací znak po libovolné počtu "výplní". Tvar
                      text,val, míst se mi nelíbil, protože s ním
                      neuděláte třeba 10mV. Takto je text kdekoli,
                      dokonce je kdekoli i třeba \n, takže nemá smysl
                      println. A varinta txtPred, val, míst, txtPo to
                      sice umí, ale jsou 4 parametry a stejně nejde
                      udělat třeba odskočené tisíce. Taky se mi líbí, že
                      to sežere i float. Předpokládím, že buffer se
                      vytvoří na zásobníku a po opuštění funkce zmizí.
                      Je to tak?</font></p>
                  <p><font face="Arial">Ještě to chci doplnit o možnost
                      mít formátovací řetězec ve flash. Není mi ale
                      jasné, jaký je rozdíl mezi PSTR("V paměti flash")
                      a F("V paměti flash"). Asi se mi víc líbí F(" "),
                      je to kratší zápis a dovoluje přetížení funkce.
                      Ale možná má nějakou nevýhodu, na kterou jsem
                      nepřišel.<br>
                    </font></p>
                  <pre class="moz-signature" cols="72">Martin Záruba</pre>
                  <div class="moz-cite-prefix">Dne 19.4.2024 v 20:50
                    Pavel Hudeček napsal(a):<br>
                  </div>
                  <blockquote type="cite"
cite="mid:b4bb63a0-c0e8-4e00-bb0f-836ae08e652c@seznam.cz">Moc pěkný. <br>
                    Já bych teda akorát nekopíroval celý text do velkého
                    bufferu a místo toho text před číslem rovnou
                    odesílal v prvním do/while, pak převed a odeslal
                    číslo a nakonec odeslal zbytek vstupního textu. <br>
                    <br>
                    Už jsem taky kdysi použil variantu, kdy se zadávají
                    parametry (text, val, mist) a v textu je pak znak
                    pro umístění čísla a des. míst se odešle podle
                    hodnoty mist. Častějc mám ale (txtPred, val, mist,
                    txtPo). <br>
                    <br>
                    Odesílání mám teda téměř vždy rovnou průběžně po
                    znacích a odesílací funkce čeká jen na dokončení
                    předchozího znaku, takže konverze na výstupní text
                    probíhá paralelně s odesíláním. <br>
                    <br>
                    PH <br>
                    <br>
                    Dne 19.04.2024 v 19:23 Martin Záruba napsal(a): <br>
                    <blockquote type="cite">Už jsem se Vás dost natrápil
                      na toto téma a měl jsem pocit, že nic moc
                      úsporného a jednoduše použitelného není. Jenže
                      jsem paličatý a zkusil jsem přece něco vymyslet.
                      Požadavek byl: <br>
                      <br>
                      Výpis na požadovaný počet míst s možností textu
                      před i za číslem. <br>
                      <br>
                      Potlačení nevýznamných nul. <br>
                      <br>
                      Co nejúspornější kód jak funkce, tak volání,
                      vhodný pro malinky procesor. <br>
                      <br>
                      Přímý tisk bez nutnosti psaní Serial.print(); <br>
                      <br>
                      Vyrobil jsem toto, posuďte a navrhněte prosím co
                      by ještě šlo líp. <br>
                      <br>
                      <br>
                      void pr(int32_t h, const char* f) { <br>
                        char buf[100]; <br>
                        uint8_t i = 0xFF; <br>
                        int32_t x = abs(h); <br>
                        do { <br>
                          i++; <br>
                          buf[i] = f[i]; <br>
                        } while (f[i] != 0); <br>
                      <br>
                        do { <br>
                          i--; <br>
                          if (buf[i] == '#') { <br>
                            if (x != 0) { <br>
                              buf[i] = x % 10 + (uint8_t)'0'; <br>
                              if (h < 0 && x < 10) { <br>
                                i--; <br>
                                buf[i] = '-'; <br>
                              } <br>
                            } else { <br>
                              buf[i] = ' '; <br>
                            } <br>
                            x /= 10; <br>
                          } <br>
                        } while (i != 0); <br>
                        Serial.print(buf); <br>
                      } <br>
                      <br>
                      <br>
                      Funkce má jediný formátovací znak # <br>
                      <br>
                      Příklady: <br>
                      <br>
                      int32_t napetimV = 5432; <br>
                      pr(napetimV, "Pokus1=###.###V\n"); <br>
                      pr(-21,      "Pokus2=### zaporne cislo\n"); <br>
                      pr(9876543,  "Pokus3=# ### ### cislo s mezerami po
                      1000\n"); <br>
                      float a = 54.3; <br>
                      pr(a*10,     "Pokus4=####.# vypis float na 1
                      desetinne misto\n"); <br>
                      <br>
                      Výsledek vypadá takto: <br>
                      <br>
                      Pokus1=  5.432V <br>
                      Pokus2=-21 zaporne cislo <br>
                      Pokus3=9 876 543 cislo s mezerami po 1000 <br>
                      Pokus4=   54.3 vypis float na 1 desetinne misto <span
                      style="white-space: pre-wrap">
</span></blockquote>
                  </blockquote>
                </blockquote>
              </blockquote>
            </blockquote>
          </blockquote>
        </blockquote>
        <br>
        <fieldset class="moz-mime-attachment-header"></fieldset>
        <pre class="moz-quote-pre" wrap="">_______________________________________________
HW-list mailing list  -  sponsored by <a
        class="moz-txt-link-abbreviated" href="http://www.HW.cz"
        moz-do-not-send="true">www.HW.cz</a>
<a class="moz-txt-link-abbreviated moz-txt-link-freetext"
        href="mailto:Hw-list@list.hw.cz" moz-do-not-send="true">Hw-list@list.hw.cz</a>
<a class="moz-txt-link-freetext"
        href="http://list.hw.cz/mailman/listinfo/hw-list"
        moz-do-not-send="true">http://list.hw.cz/mailman/listinfo/hw-list</a>
</pre>
      </blockquote>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
HW-list mailing list  -  sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>