Kysymys:
Pakkaa .hex-tiedosto mikro-ohjaimelle
Danial
2019-10-12 15:53:18 UTC
view on stackexchange narkive permalink

Kirjoitan ohjelmaa tällä hetkellä AVR Studiossa , tässä on koontiversio * Muistin käyttö: *

  Laite: atmega32
    Ohjelma: 9304 tavua (28,4% täynnä)
    (.teksti + .data + .bootloader)
    Tiedot: 334 tavua (16,3% täynnä)
    (.data + .bss + .noinit)
 

Koska käytän ATmega32 -mikro-ohjainta, se ei näytä olevan ongelma, mutta haluan käyttää samaa koodia ja käyttää ATmega8 -mikroa-ohjain.

Haluan siis pienentää ohjelman kokoa vähemmän kuin 8192 tavua .

Kuinka voin tehdä tämän?

Käytätkö liukuluku kirjastoa?
@Danial tämä ei ratkaise ongelmaa, mutta huomaan vain, että .hex-tiedosto on vain muoto, johon ohjelmakoodi tallennetaan. Ne ovat vain tekstiä, joten ne puristuvat hienosti.Mutta se ei päädy MCU: n flashiin, varsinainen ohjelmakoodi on.Joten _sitä_ haluat pienentää, ei .hex-tiedostoa sellaisenaan.
Seitsemän vastused:
Oldfart
2019-10-12 15:59:56 UTC
view on stackexchange narkive permalink

Voit ei pakata heksakoodin, voit vain yrittää vähentää sitä.

  • Kokeile eri tapaa?kääntäjän asetukset (suurin optimointi ja koon optimointi)
  • Valitse lähdekoodisi läpi ja katso, mitä voidaan optimoida tai jättää pois.
  • Katso, vedetäänkö tarpeetonta kirjastokoodia sisään (sen ei pitäisi olla, mutta kuka tietää)

Hyvä piste Jeroen3: lta: Tarkista, tarvitsetko / tarvitsetko liukulukua.Erityisesti toiminnot, kuten printf , vetävät toisinaan liukulukukoodin selvittääkseen printf ("% f" ... .)sitä ei tarvitse.

Michel Keijzers
2019-10-12 16:04:03 UTC
view on stackexchange narkive permalink

MCU ei voi suorittaa pakattua koodia.

Voit kuitenkin tehdä joitain asioita:

  • Luomalla kaikki tai kaikki toiminnot sen sijaan, että käyttäisit täysimittaisia kirjastotoimintoja;tällä tavalla voit optimoida kirjastotoiminnot, jotka ovat enimmäkseen (liian) joustavia juuri sinun tarpeisiisi.
  • Poista päällekkäinen koodi omasta koodistasi.Käytä parametreja melkein päällekkäiseen koodiin, jotta se olisi joustava.
  • Käytä pienintä tyyppiä vakioille ja erityisesti vakiomalleille.
  • Poista 'ilmeinen' kuollut koodi (koodi, jota ei voida koskaan suorittaa), katso alla oleva Jeroen3: n ja Dakkaronin huomautus.(tarkista, esiintyykö näin kaikki toiminnot tai osa toiminnoista).Katso myös tämä linkki.
  • Pienennä merkkijonoja (jos käytät paljon tulosteita, minimoi nämä vakiojonot mahdollisuuksien mukaan).
Kuolleen koodin poistaminen on [linkkeriominaisuus] (https://renenyffenegger.ch/notes/development/languages/CC-plus-plus/GCC/options/Wl/index): ** - Wl, --gc-section ** joka koskee myös käyttämättömiä kirjastotoimintoja.
@Jeroen3 Kiitos, en tiennyt, että se oli niin älykäs.Päivitin vastaukseni (kommentilla nimesi).
@Jeroen3 Tämä toimii vain "kovan" kuolleen koodin kohdalla, joten koodi, jossa kääntäjä voi päätellä, että se on kuollut.Se ei toimi kuolleen koodin kohdalla, jota kääntäjä ei voi määrittää, esim.jokin koodi, joka suoritetaan vain, jos funktiota kutsutaan tietyllä parametrilla, mutta funktiota ei koskaan kutsuta tällä parametrilla.Joten on ehdottomasti hyödyllistä käyttää linkkintarkistusta, mutta on myös hyödyllistä analysoida koodi käsin kuolleen koodin löytämiseksi.
@Dakkaron Kiitos ... Lisäsin nimesi kommenttiin (minulla oli itse asiassa jotain, mitä kirjoitit aiemmin).
Michael Karas
2019-10-12 19:41:12 UTC
view on stackexchange narkive permalink

Muiden täällä olevien vastausten erinomaisten ehdotusten lisäksi haluan kommentoida, että voi olla valtava ero siinä, kuinka paljon kääntäjät (ja linkkerit) voivat optimoida koodia.

Olen työskennellyt yrityksessä muutama vuosi sitten, jossa tuote käytti ATMega8: ta. Kun saavuin paikalle, tällä tuotteella oli kolme erilaista lähdekoodirakennetta, jotka antoivat erilliset ominaisuudet eri tuotekokoonpanoille. Lähdekoodi on koottu käyttäen edullista C-kääntäjää, ja jokainen koodijoukko mahtui tuskin laitteen FLASH-muistin 8K tavuun.

Pyysin yrityksen ostamaan huippuluokan kääntäjän AVR-yhteisössä tunnetulta yritykseltä. Sitten menin työskentelemään ohjelmistojen lähdekoodien parissa ja asetin kääntäjävaihtoehdot optimointia varten.

Kun olen valmis, kaikki tuotevaihtoehdot mahtuvat yhteen kuvaan, joka on alle 8 kt tavua. Itse asiassa minulle oli tarpeeksi tilaa lisätä vain lähetettävän ohjelmiston UART koodiin, jotta ohjelmisto voisi levittää sisäisiä tietoja, joita käytettiin tuotteen parametrien kalibrointiin. UART-lähtö laukaistiin, kun 28 V-signaali syötettiin yhteen A / D-kanavasta jännitteenjakajan kautta. Liipaisinta tarvittiin, koska ohjelmiston UART-lähtö käytti GPIO: ta, joka oli normaalisti signaali, joka oli tuotteen lähtö.

Hyvä tarina.Kääntäjät voivat tehdä hyvää työtä, mutta ihmisen ponnistelut voivat auttaa.Samalla tavalla otin projektin käyttöön 8-bittisessä PIC-prosessorissa asiakkaalta, jossa eri versiot erotettiin kolmeen samankaltaiseen lähdekoodiin - ohjelmamuisti oli melkein täynnä jokaiselle versiolle (8 k: n ohjelmamuisti, noin 85% täynnä).Yhdistin koodit, optimoin itse C-koodin tarkistamalla luodun kokoonpanokoodin ja lisäsin monia toimintoja ajan myötä (noin 98% täynnä).Paremman kääntäjän heittäminen siihen olisi voinut auttaa, mutta ei niin paljon kuin koodin optimoinnit.
Graham
2019-10-13 01:02:23 UTC
view on stackexchange narkive permalink

Ensimmäinen askel kaikenlaiseen optimointiin on selvittää, mitä se tekee .

Ensimmäisen askeleen tulisi olla saada linkki tyhjentämään koontiversiossa olevien kaikkien tunnisteiden osoitteet.Siinä kaikki toiminnot ja kaikki muuttujat.Linkittäjän tulisi myös pystyä ilmoittamaan toimintojen koot;se ei todennäköisesti tee muuttuvia kokoja, mutta voit päätellä ne luettelon seuraavan muuttujan osoitteesta.

Kun tiedät, mihin avaruutesi menee, voit tehdä asialle jotain.Mahdollisuudet ovat melko hyvät, ratkaisu on ilmeinen, kun aloitat katsomaan suurinta.

Kunnes tiedät, olet vain haulikko sokea, eikä se ole koskaan hyvä suunnitelma.

filo
2019-10-13 15:39:09 UTC
view on stackexchange narkive permalink

Ei ole "käytännöllistä" tapaa suorittaa pakattua koodia AVR: llä, joten ongelmastasi tulee "miten voin optimoida laiteohjelmistoni koon".

Työkaluketjut (eli sinun ei tarvitse muokata koodiasi):

  1. Mikä on kääntäjän optimointitaso? Kohdassa gcc vaihtoehtoa optimoida pienimmälle koolle kutsutaan -Os

  2. On olemassa linkki-ajan optimointiin kutsuttu toiminto, joka voi edelleen optimoida koon mukaan. Se on jo mainittu tässä vastauksessa.

  3. Linkittäjä voi optimoida käyttämättömät tiedot ja symbolit. Se otetaan käyttöön -Wl, - gc-section -ffunction-section -fdata-section

  4. Ota käyttöön -mcall-prologues . Selitetty täällä.

Yleisiä kooditemppuja:

  1. Suorita nm -S --size-sort -t d your_output_file.elf . Tämä komento näyttää, kuinka suuri kukin symboli on (linker-speaken symboli tarkoittaa tietoja tai koodia). Sitten voit selvittää, missä optimoinnin suurin mahdollisuus on.

  2. Yritä löytää koodinpätkiä, joista voi tulla omia toimintoja.

  3. Vältä printf : n käyttöä. Jos sinun tarvitsee vain muuntaa kokonaisluvut merkkijonoiksi, niin itoa on vaihtoehto. Voit myös tutustua xprintf -ohjelmaan, joka on kevyempi vaihtoehto tavalliselle printf.

  4. Jos käytät liukulukuja (float, double) - yritä muuntaa koodi kokonaislukuiksi. Esimerkiksi jos tarvitset 2 desimaalia, voit käyttää yksinkertaista skaalausta 100: lla (ts. 2,5 tulee 250). Kaikki liukulukuoperaatiot (niin yksinkertaisia ​​kuin float x = a + b ) AVR: llä vetävät kirjaston koodipinon, koska CPU ei tue tällaisia ​​operaatioita laitteistossa.

sktpin
2019-10-14 19:50:09 UTC
view on stackexchange narkive permalink

Jos etsit tapoja pienentää ohjelmakoodiasi - sen lisäksi, että optimoiva kääntäjä & linker pilkkoa joitain ja ei käytä tavallisia kirjastotoimintoja, kuten muut ovat huomanneet, se riippuu myös ohjelmakoodin kokoonpanosta kuinka suuri se tulee olemaan.

  • Yritä ensin löytää tapa näyttää, mitkä ohjelman osat ovat loukkaavimpia koon suhteen. Valitettavasti en ole perehtynyt AVR studioon, mutta täällä, käyttäjän skeeve, viesti # 7 luetellaan yhden objektin tiedostojen koot. Jos ohjelmassasi on useita moduuleja, tiedät ainakin, mitkä niistä ovat suurimmat, ja hyvät ehdokkaat manuaaliseen optimointiin .
    • miksi koodin manuaalinen korjaus, sanot? Jos saat koodin pienemmäksi tällä tavalla, toisin kuin kääntäjän optimointia varten, virheenkorjaus (kuten koodin selaaminen GDB: llä tai vastaavalla) toimii paljon mukavammin kuin silloin, kun optimoija luo jyrkän eron suoritetun todellisen koodin ja lähdekoodisi, mikä tekee asioista vähemmän helppoja seurata
  • tässä on joitain vinkkejä: katso luku "3 vinkkiä koodin koon pienentämiseksi"
  • vältä "copy & paste" -koodia
    • eli käytä rutiinia useammalle kuin yhdessä paikassa tekemäsi toimintosarjalle ja soita sitten kyseisistä paikoista
    • tämä saattaa kuulostaa itsestään selvältä ("Olen käyttänyt toimintoja, duh!"), mutta voi olla hyödyllistä etsiä koodista paikkoja, jotka tekevät melkein täsmälleen saman asian, ottavat useita vaiheita joka kerta, ja kaikki erilainen riippuu vain pari parametria, jotka voivat olla funktion argumentteja
    • Sivuhuomautus: Tähän on myös muita syitä: käytä rutiineja rutiininomaisesti
  • (epätoivoisempi, taistelu pari ylimääräistä tavua varten ...) harkitse suuremman kytkimen / tapauksen muuntamista tai jos..else..if..else ... lohkot (joista funktiot kutsutaan) const-taulukoksitoiminnon osoittimet.Toimii vain, jos kaikilla toiminnoilla on sama allekirjoitus, eli sama osoitintyyppi, ja taulukkohakemiston laskeminen arvosta päättää, mihin kutsutaan, ei lisää paljon koodia yksin.Taulukon indeksointi ja funktiosoittimen kutsuminen voi tuottaa pienemmän koodin kuin paljon kytkimiä / tapauksia tai jos / muuta samalle skenaarialle.(se teki minulle - kuitenkin 32-bittisellä Microblaze-laitteella. YMMV)
Dvidunis
2019-10-13 02:34:56 UTC
view on stackexchange narkive permalink

Jos projektisi koostuu useista lähdetiedostoista (kuten useimmat projektit tekevät), voit myös tarkastella Link Time Optimization: tä (yleisesti lyhenne LTO).

Se tekee ylimääräisiä optimointeja objektien välillä (linkin aikana, kuten nimestä voi päätellä).

Voit etsiä tiettyä "Link time optimization" / "LTO" -vaihtoehtoa IDE: stä tai etsiä paikkaa kääntäjän lippujen lisäämiseksi.

Jos kääntäjäsi on GCC- tai Clang-pohjainen, voit lisätä -flto -lipun Sekä kokoamisen että linkityksen aikana (tarvittaessa CFLAGS ja LDFLAGS).

Tämä voi optimoida kokonaiset koodilohkot (sisäiset toiminnot), joita ei ole kutsuttu, tai optimoida ne tietylle syötekuvioon.

Huomaa, että jos käytät vakiokirjastoa, sinun on varmistettava, että käännät sen LTO: n kanssa saadaksesi suuria säästöjä.

Voit lukea lisää LTO: sta täältä: https://fi.wikipedia.org/wiki/Interprocedural_optimization
Ja esimerkki Linux-ytimestä: https://lwn.net/Articles/744507/



Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 4.0-lisenssistä, jolla sitä jaetaan.
Loading...