Přeskočení instrukce

Ahoj mám prosbu…nelze nějakým způsobem říci CGG překladači pro STM32, aby nepoužíval při překladu nějaké instrukce? Např. instrukci relativního skoku? Dík

To by mě zajímalo jestli tohle vůbec nějakej překladač umí. Proč to potřebuješ?

Dík za reakci…
Nejdřív omáčka: V jedný aplikaci používám možnost přeprogramování flešky MCU přes seriovou linku. Funguje to tak, že mám paměť rozdělenou na tři části. Jedna se jmenuje BIOS, druhá APPL a třetí APPL_MIRR. Bios neměním, ale přeprogramovávám buď jednu nebo druhou část aplikace a program si sám vybírá odkud aplikace poběží. Tohle funguje bezvadně. Když chci, ale aplikaci přeprogramovat, tak musím vygenerovat dva obrazy aplikace. To se dělá tak, že jednou zkompiluju program s počáteční adresou APPL a podruhé s adresou APPL_MIRR.
A teď kam mířím: předpokládám a to jen teoreticky, protože programuji primárně v c-čku, že důvod proč musím generovat dva obrazy je to (a to skutečně musím jinak to nefunguje), že překladač používá instrukci např. nepřímého skoku. Kdyby se mi povedlo ho přesvědčit, aby tuto instrukci nevolal tak bych mohl používat jen přímé skoky a tím pádem bych mohl mít pouze jeden zkompilovanej obraz a ten nahrávat jak do části APPL tak i APPL_MIRR.

Načo je program 2x v pamäti?

Nie je lepšie progam preniesť cez sériovú linku, nahrať ho napríklad do SPI Flash alebo EEPROM, skontrolovať všetky CHS a CRC a keď je všetko v poriadku tak z tej EEPROM prepísať do reálnej programovej pamäte?

Ja to robím na ATmege tak, že

Po reštarte sa vždy najprv spustí bootloader.
Ten si overí či má bežať na základe nejakých dvoch bajtov v pevnej pamäti. Ak nemá, spustí samotnú aplikáciu.

Ak bežať má, potom beží a očakáva príjem častí hlavného programu. Ten sa cez protokol posiela v 128B balíkoch. Súčasťou balíka samozrejme je, kam sa má do pamäte uložiť.
Tento prístup umožňuje meniť len tie časti programu, ktoré sú od predchádzajúcej verzie zmenené. Respektíve ak nejaký balík neprejde, dá sa prenos zopakovať samostatne.

Ak je všetko čo malo byť zapísané aj zapísané, potom sa bootloaderu povie, že má spustiť hlavný program.
Ten sa spustí.
Hlavnému programu sa povie, aby zas prepol na bootloader. Ak to spraví a Master dostane hlášku že beží bootloader, zapíše sa do EEPROM, že hlavný program sa môže spustiť hneď od začiatku. Po každom ďalšom reštarte teda bootloader hneď spustí hlavný program.

Ak však nastala niekde chyba a hlavný program neposlušne odmieta spustiť bootloader, zariadenie stačí vypnúť a zapnúť. Keďže v EEPROM nie je uložená informácia o spúšťaní hl. programu od začiatku, bootloader čaká na preprogramovanie.

Je to ošetrené tak, že ak by aj náhodou niečo pri preprogramovávaní zblbo, hocikaý údržbár vie na vzdialenom mieste vypnúť a zapnúť istič a preprogramovanie môže začať znovu, lebo bootloader pohotov čaká na príkazy.

Samozrejme, ku klienovi posielam len na stole odladené programy, takže za dlhé roky nikdy nikto nemusel vypnúť a zapnúť istič na zariadení.

Pri zblbnutí na stole, stačí vypnúť/zapnúť zdroj, chybu opraviť a znovu preprogramovať.

Tým, že sa pri vývoji sw preprogramovávajú iba tie 128B bloky ktoré sa voči pôvodnému kódu zmenili, šetrí sa hodne času.

Tento spôsob roky používam k plnej spokojnosti.

Nenašiel som doteraz dôvod, prečo by mal byť v relatívne vzácnej programovej pamäti program 2x, ale rád sa nechám poučiť.
Hlavne ako rozhodnúť, ktorý z nich má vlastne bežať.
Ak je potrebné sa vrátiť k predchádzajúcej verzii, stále sa mi zdá praktickejšie použiť externú SPI Flash, napriklad AT25SF041-SSHDT čo je 512kB Flash za 0,26EUR. Alebo AT25SF161-SSHDB , čo je 2MB Flash za cenu 0,44EUR.

Já Ti asi rozumím. Jestli to chápu dobře, tak tam máš bootloader (ten se stará o update a spuštění jedné ze dvou různých aplikací) a ty dvě různé aplikace, každá samozřejmě na jiné startovní adrese. A ty bys chtěl aby se obě kompilovali se stejným nastavením adresy start, aby si nemusel řešit kterou apku na kterou pozici. Je tak? Tak to se neřeší zákazem konkrétní instrukce (to by sis nepomohl, skuz přijít na to proč), ale musíš požádat kompilátor aby to kompiloval jako relokovatelnej kód. Něco jako RO-position independent.

Martine, Ty mě vždycky dostaváš :slight_smile: Jak víš, že apky jsou stejný, hmm ?

No jasne, moc sa domýšľam :slight_smile:

Napríklad zo skratky APPL_MIRR som nejako záhadne vydedukoval, že sa jedná o MIRROR, čiže zrkadlo. Dúfam, že nie pokrivené a teda robí presne to isté ako APPL.

Ale možno len autor nahodil udičku a ja som sa nechal ľahko nachytať :slight_smile:

Ale ak sú rôzne, Tvoja rada je samozrejme oveľa viac k veci a správna.

A zároveň mám záhadný pocit, že otázka patrí do skupiny: “som viac menej začiatočník a snažím sa všetko ošetriť ako sa len dá, takže ak by náhodou jedna časť Flesky zblbla, bootloader rozhodne o spustení toho istého progamu z inej časti”.

Hlavne pasáž:"To se dělá tak, že jednou zkompiluju program s počáteční adresou APPL a podruhé s adresou APPL_MIRR. "

nenaznačuje, že by sa obe aplikácie mali nejako líšiť, teda okrem spúšťatelných adries.

A prečo tak dedukujem? Sám som si onehdá prevelice dávno prešiel obdobnými úvahami a snažil som sa ošetriť prakticky neošetriteľné.

Ale možno je všetko inak a zem ja naozaj guľatá kocka :slight_smile:

Jo MIRR - to by mohlo byt. To ze to kompiluje jednou tak a podruhe jinak (krome zmeny adresy) by mohlo znamenat z jednoho a tehoz src pomoci define vytvari ruzne apky, jedna toho umi vic, druha min. Kazdopadne moznosti je hodne, pockame at nam to prozradi sam :wink:

moc sa teším :slight_smile:

Nie je nad to, stretávať sa takto na fóre.

Krásny plodný večer :slight_smile:

Ahoj zkušení programátoři,
díky za komentáře. Z těch všech vašich námětů se mi jako jedinej použitelnej jeví nápad s

Musim se přiznat, že o tomhle jsem slyšel poprvé a příjde mi to jako řešení. Trochu jsem o tom poguglil a našel přepínač pro GCC kompilátor s názvem

viz.:
gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
Dneska jsem na to neměl moc času, ale vyzkoušel jsem zkopilovat kód s tímto přepínačem a povedlo se to. Očekával jsem, že kód bude o něco větší, protože kompilátor nyní nepoužívá absolutní skoky a tak nebude moci využít všech optimalizačích metod. Očekávání se skutečně vyplnilo, takže to bude asi správná cesta. Uplnej masakr by bylo převědčit kompilátor tak, aby jednu část programu kompiloval optimalizovanou a jinou jako PIC tedy jako

jak se metoda asi nazývá. To je asi dost scifi, ale podle hesla, které mi často říká můj boss

na to asi dřív nebo později příjdu.

No a teď vysvětlení proč se takovouhle pro zkušené programátory prkotinou zabejvám…

  1. ten jednoduchej důvod - nestudoval jsem tolik let abych pak jen kopíroval metody jinejch lidí, mám vlastní hlavu s milionama nápadů a chci jí používat.
  2. ten horší důvod - nějakej jouda vymyslel, že chce vyvynout nějakou řídící jednotku. Pak si vymyslel, že jí chce připojit k internetu. A nakonec si vymyslel, že si chce furt vymejšlet a že v tý jednotce chce mít každou chvíli nějaký nový funkce. A aby toho nebylo málo, chce mít ty jednotky rozsetý po celý republice. Mimoto nějakej jinej jouda jí dostal až do Austrálie což je super, protože tam další jiný joudové používají náš HW s mým SW. Na začátečnickýho programátora, kterej řeší všechno do detailu docela dobrý ne :slight_smile:)

Z tohoto důvodu musí bejt všechno naprosto spolehlivý. Neexistuje, že když se něco nepovede tak k tomu někdo příjde vypne/zapne napájení nebo,že program prostě nedělá to co má. A pokud náhodou začne něco co nemá dělat musí, se z toho sám dostat.

Takže nápad (tohle berte s rezervou…napíšu to jako soustavu myšlenek):
Rozdělit paměť na několik částí jak jsem psal…BIOS, APPL, APPL_MIRR.
Část BIOS nelze chápat jako bootloader, ale jako program kterej běží na pozadí a stará se o to, aby zařízení bylo kdykoliv je potřeba na síti a nadřazenej dohledovej systém s ním mohl kdykoliv manipulovat. No a APPL je prostě to, co to zařízení dělá. Jo a teď to nejlepší…všechno to musí fungovat najednou, protože toho joudu nezajímá, že na zařízení právě probíhá upgrade SW, kterej si ke všemu sám vymyslel. Jo aby toho nebylo málo ještě chce to zařízení zároveň na dálku ovládat. Takže v základu běží program z části buď APPL nebo APPL_MIRR. V případě nového upgradu se SW nahraje do části odkud program nebeží. Jakmile je programování dokončeno novej SW se spustí. Tím, že se novej SW spustí neznamená, že se resetuje MCU, ale že se původní aplikace vypne a zapne se jiná, všechno za běhu…
Zde se to malinko komplikuje, protože aby tohle mohlo správně fungovat musí se program dvakrát překompilovat a vytvořit jeden binární obraz doplněnej o dvě CRC aby mohla aplikace bežet z různejch oblastí. Protože systém, kterej ty jednotky přeprogramovává neví z jaké oblasti právě běží aplikace, musí mít k dispozici obě ‘‘zrcadla’’.

No a teď si představte, že nemáte dva obrazy stejné aplikace a že máte jen jeden, kterej můžete nahrát tam i tam. Stačí vám jednou zkompilovat, spustit skript třeba v pythonu a řídící jednotka, která vám řídí celý dům a která je umístěná někde ve sklepě domu se vám do pár sekund spustí s novým sw. Tohle je budoucnost mého vývoje sw.

Moc díky Radiusovy za nakopnutí.

Hele úplně jsem zapomněl na tu mojí základní myšlenku…mě totiž nebaví furt generovat nový obrazy, chci aby se to dělalo samo a já měl víc času na jiný věci. Takže tohle všechno vymejšlím jen díky své pohodlnosti, protože já už prostě nechci pracovat!!!

Pár pripomienok:

Čas preprogramovania napríklad ATmegy1284P s 128kB Flash môže trvať 2-3sekundy. 4,5ms treba na zápis jednej stránky po 256B a je ich maximálne 512.

Ak sa data uložia do externej Flash, BIOS nemusí celú pamäť preprogramovávať pomalšie ako do 1-3sekúnd v závislosti od veľkosti celého programu. Nepoznám aplikáciu, v ktorej by nemohlo - obzvlášť v nejakom domčeku - nastať 3 sekundové “nič nerobenie”. Samozrejme periférie ako napríklad relé, si musia zachovať svoj stav.

Ak má jedna aplikácia začať bežať hneď po druhej a tieto nie sú totožné, potom v nich temer na 100% nebudú sedieť adresy do SRAM, takže nová aplikácia nemôže využívať posledné hodnoty spracované predchádzajúcou aplikáciou. Pred takýmto preprogramovaním je potrebné celý užitočný kontext z RAM vhodne uložiť a po reštarte novej aplikácie sa táto najprv musí oboznámiť s aktuálnym stavom.

Ako často je potrebné aplikácie preprogramovávať? Reálne v súčasnosti. 1x za hodinu? 5x za deň? Alebo ak sa má upgrade spraviť automaticky stačí ho fyzicky vykonať v nejakú dohodnutú hodinu, napríklad o tretej nad ránom? Aj potom je dostatočné, ak je aplikácia niekde vo Flash a zariadenie sa preprogramuje samo. Samozrejme, aplikácia môže odpočívať aj vo Flash procesora. Ale načo?

Ak chce užívateľ hneď vyskúšať nové fičúry ktoré si navymýšľal, nepočká tie cca 2 sekundy na preprogramovanie?

No možno nie, ale čas na vyrovnanie sa s kontextom v RAM nejaký predsa len potrebný bude.

Ako riešiš túto časť?

V každom prípade ďakujem za informáciu o tej fičúre prekladača, nevedel som.

Inak ak Ťa nebaví generovať nové obrazy, prácu si zautomatizuj nejakým skryptom. BIOS môže spúšťať vždy tú časť, ktorej naprogramovanie je ukončené a ktorá bude napríklad mať vyššie číslo verzie.

Neni zač, tohle je klasika už z dob Z80 a HC11.

Zajímavá je ta pasáž s kontextem - používáš sdílenou paměť pro data na pevných, předem známých adresách?

Jsou BIOS, APPL, APPL_MIRR samostatné jedno/více vláknové aplikace, nebo jsou to vlákna jedné aplikace?