aktualizování firmwaru přes uart
Úvodní stránka › Fórum › Vaše projekty › Arduino › aktualizování firmwaru přes uart
- Toto téma obsahuje celkem 68 odpovědí. Do diskuze (3 diskutující) se naposledy zapojil uživatel michal123 a poslední změna proběhla před 7 roky a 5 měsíci.
-
AutorPříspěvky
-
1.4.2017 v 11:14 #10938michal123Účastník
Ahoj,
jak aktualizuji FW když nový dostanu třeba v hex přes uart?
Řeším takovou věc, že na web jsem umístil hex, ten dokáži přečíst například přes GPRS ale nevím, neznám jaké příkazy použít aby si ho procesor nahrál přes původní program.
Jde to vůbec, nebo je nutné programovat přímo kód třeba v atmel studiu?
Doufám, že to lze, všechno lze takže jak na to?1.4.2017 v 12:06 #10939Vojtěch VosáhloÚčastníkDobrý den,
napadá mě hned několik řešení tak se na ně pojďme podívat. Budu mluvit o procesoru který používáte jako AVR, použitá metoda programování by pak musela být nejspíš přes SPI.1) Je závislé na modulu který budete používat k připojení k internetu. Pokud by měl modul samotný možnost uploadovat do něj program (můžete měnit co běží v modulu), třeba nějaké ESP, mohl byste si napsat prográmek kde modul samotný nahraje program do AVR. Několik takových programů pro ESP již existuje.
2) AVR by flashnulo samo sebe. Na tohle se používá bootloader, to je prográmek v paměti který je před samotným kódem a je spuštěn vždy při zapnutí čipu. Muselo by se tedy nejspíše naprogramovat to že AVR si řekne GPRS modulu o soubor, „stáhne“ si ho a pak do sebe nahraje. Tady je ale pár možných komplikací, nejsem nějaký bootloader expert a nevím jestli by se do samotného bootloaderu dala zapsat celá procedura, tzn. stahování jednotlivých bytů ze souboru a jejich vypalování do paměti. Možná by tedy bylo potřeba aby AVR nejdříve stáhlo soubor (asi někam extérně kvůli velikosti, SD nebo externí flash) a resetovalo se. Bootloader by pak jen přečetl externí paměť a nahrál vše do AVR.
3) Mít nějaký čip, třeba další AVR, které bude dělat programátor pro váš hlavní čip. Prakticky byste mohl mít čip který funguje jako USBasp akorát přes internet. Tahle metoda by byla použitelná asi jen pokud by nefungovala 2, tedy provedení všeho v bootloaderu.
Pokud existojou lepší metody tak jsem si jistý že mě někdo opraví a vylepší co jsem napsal.
1.4.2017 v 12:41 #10941michal123Účastníkaktuálně používám atmega328p
1)takovýto modul nemám, ale jestli to dobře chápu tak se to blíží možnosti 3)
2)jakou výhodu má bootloader oproti programu za běhu nebo například přerušení?
jak se píše vlastní bootloader?
proč to nejde tak, že za běku se vyvolá například přerušení, vyprázdní se ram, do ní nenahraje požadovaný kód a pak nenaprogramuje do příslušné paměti?
3)ano i o této možnosti jsem přemýšlel ale uní zase nevím jak umožnit přeprogramovávání dvou procesorů za běhu (pak samozřejmě restart) nebo úpravy bootloaderu
mohl by jste mě prosím odkázat na nějaký pochopitelný kód?
Děkuji, tyto odpovědi se mi moc líbí, jen nevím jak je realizovat (ani jednu)1.4.2017 v 15:28 #10944Vojtěch VosáhloÚčastníkaktuálně používám atmega328p
Používáte ji jako Arduino nebo jako čip samotný, programovaný třeba přes Atmel Studio?
U psaní bootloaderu totiž moc arduina neuvidíte, ten se píše v GCC nebo Assembleru. Výhody oproti programu? On je vlastně sám program, ale je na přesně definovaném místě v paměti (úplně na konci) a procesor ho spouští jako první. Je to takový BIOS, on se stará o to aby se váš program rozjel tak jak má, je to takový startér.
Zde je hezký článek o tom jak bootloader funguje a i ukázka velice jednoduchého kódu: Bootloader AVRPoté si můžete projít i bootloader který je v arduinu zde: Arduino bootloader
proč to nejde tak, že za běku se vyvolá například přerušení, vyprázdní se ram, do ní nenahraje požadovaný kód a pak nenaprogramuje do příslušné paměti?
Budu trošku tipovat ale řekl bych že hlavně kvůli tomu že váš program běží v nějaké smyčce, jakmile byste vyprázdnil ram a začal zapisovat cokoliv do paměti, smyčka by se roztrhla a program by stopnul takže byste nezapsal nic. Když máte v paměti bootloader i program, běží si oba v jiné smyčce, paměť je rozdělena. Bootloader přesně ví kde je aby nezasáhl do své smyčky a když se rozjede, může bez problému zapisovat data do zbylé části paměti. Bootloader může také vykonávat funkce pro zápis bytů na specifické místo v paměti.
3)ano i o této možnosti jsem přemýšlel ale uní zase nevím jak umožnit přeprogramovávání dvou procesorů za běhu (pak samozřejmě restart) nebo úpravy bootloaderu
Proč přeprogramování dvou procáků? Mám jeden, třeba „aktualizační“ a druhý, „hlavní.“
Hlavní procesor může běžet a dělat si co chce, jakýkoliv kód který mu dáte. Aktualizační procesor může zatím sedět a čekat, třeba počítat a každou hodinu kontrolovat internet zda tam není nový soubor. Pokud by se GPSR modulu měl dostávat i hlavní procesor, musel by být hlavní procesor ten co provádí váš program ale i počítá, pak by si sám zavolal ten aktualizační, ten by převzal modul a zjistil jestli je možný update. Pokud by update byl, aktualizační procesor by se zachoval jako programátor. Stahoval by byte po bytu z vašeho hex a zapisoval by ho do paměti toho druhého zatímco by ho držel v resetu.. Reset je samozřejmě proveden přivedením pinu RST na zem. Aktualizační procesor se nemusí sám nikdy aktualizovat.Tahle metoda má jednu velkou výhodu, nemusíte na ní znát C. Vše co jsem popsal by neměl být problém naprogramovat v Arduino IDE, je to prakticky jen komunikace po SPI, UART a přepínání pinů. Mohl byste začít třeba s příkladem v arduino IDE a to ArduinoISP, prakticky plní to co vy potřebujete, čte UART a vš přehraje do paměti čipu připojeného přes SPI, stačilo by to upravit tak aby četl z internetu.
Pak by se možná dalo vymyslet i něco s existujícím arduino bootloaderem, možná mu posílat příkazy přes serial. Vzhledem k tomu že je to optiboot, měli by se dát i ty příkazy někde najít. Ale o tom vám bohužel moc neřeknu :/
2.4.2017 v 17:08 #10955Zbyšek VodaSprávcePěknou přednášku o Arduino bootloaderu a jeho modifikacích měl Petr Stehlík na posledním Install Festu – https://www.youtube.com/watch?v=6_1VQvVuFf8&feature=youtu.be&list=PLub6xBWO8gV_t_p-5-J_qU20fkkDtsLjB. Třeba byste se mohl nechat inspirovat 🙂
3.4.2017 v 10:41 #10971michal123ÚčastníkDěkuji, je to pro mě velkým přínosem, i když je tam spousta věcí co ještě neznám.
3.4.2017 v 10:57 #10972michal123ÚčastníkDosud jsem používal pouze arduino, přemýšlím o atmel studiu (mám snad už nějaké základy assembleru a c++ tak by to snad mohlo jít), rád bych to vyřešil pro Arduino.
Zde je hezký článek o tom jak bootloader funguje a i ukázka velice jednoduchého kódu: Bootloader AVR
Ano, tenhle článek jsem četl už asi před týdnem, a rozhodně mi osvětlil některé časti. Výhdami jsem mylsel to jestli (případně proč) bootloader umi i něco více než arduino program. Chapu to tak ze kdyz bych psal v atmelstudiu tak bootloader bude umet stejne veci jako kod, ale nejsem si jist jeslti to tak opravdu je a jeslti když bych psal v arduinu budou na všechno příkazy.
Poté si můžete projít i bootloader který je v arduinu zde: Arduino bootloader
Děkuji, tohle jsem hledal, ale bohůžel se stalo to co je nejspíš pravděpodobné, že mi ten kód moc neříká (a studovat hotřeba týden když se mu chci vyhnout se mi moc nechce)
Budu trošku tipovat …
Zezačítku jsem tohle co jsete psal moc nechaápal, už to ale čtu poněkolikáté a žačalo to dávat smysl, takže tomu rozumím tak, že kód který je zapsaán v nejaké paměti nemůže tu stejnou paměť přepsat, ptotože by došlo k chybě. Lze zavolat funkci která by byla nějakým způsobem uložena do paměti pro bootloader? a tím moha přepsat stávající hlavní program? (tuším, že to pravděpodonmě nebude jednduché takže odpověď bude NE)
Jak může vypadat aktualizační procesor? Ještě jsem nezkoušel dostat aeduino na procesor menší než atmega328, a když už bych ho tam dal, tak by bylo zbytečné ho nevyužívat i jinak než jen jako aktualizační.
Lze použít pro arduino jako aktualizační procesor třeba nějaký levný jak attiny10 ? možná s extermním paměťovým čipem?
Myslím, že když zvládnu naprogramovat jeden druhým, tak i druhý prvním. To snad nebude problémAno, metoda přes UART nebo SPI se mi zdá snažší (snad i zabere méně paměti) a myslím, že ni moje znalosti stačit mohou (i když jsem se ještě nepodíval na ArduinoISP)
Ještě se tedy pokouším zhodnotit kterou metodou se vydám, jeslti ISP nebo UART (který se mi zatím zdá méně náročný na počet pinů)Raději bych se tedy bootloaderu vyhnul, ale měl bych k němu ještě otázku. Je je nějaký funkční rozdíl mezi původním 2kb bootloaderem a menším optiboot bootloaderem?
3.4.2017 v 13:22 #10973michal123Účastníkkdyž zvolím možnost z aktualizačního procesuru posílat data přes uart, následují nejspíš tyto kroky?:
restart procesoru
čekání 20ms
poslání „řídícího slova“ kde najít jak má vypadat?
nahrání bit nebo hex kódu, nebo jende stranky?
poslani dalsiho slova s dalsi strankou nebo restart?nepodařilo se mi najít přesný postup
4.4.2017 v 17:28 #10991Vojtěch VosáhloÚčastníkZezačítku jsem tohle co jsete psal moc nechaápal, už to ale čtu poněkolikáté a žačalo to dávat smysl
Příště budu konkrétnější.
Lze zavolat funkci která by byla nějakým způsobem uložena do paměti pro bootloader? a tím moha přepsat stávající hlavní program? (tuším, že to pravděpodonmě nebude jednduché takže odpověď bude NE)
No, možná ano. Assembler má příkaz ve které můžete skočit na určitou adresu v paměti, myslím že jmp. Z bootloaderu skáčete na program právě touto funkcí takže nevidím důvod proč by to nešlo ALE když skočíte do bpotloaderu, není to stejné jako kdyby se procesor bootoval od začátku. Jde o to že vše co jste si nastavil v programu (konfigurace pinů, přerušení…) zůstane nastavené takže bootloader nemusí fungovat tak jak má. Já ale vlastně nevidím důvod proč do bootloaderu skákat z programu. Jaký je důvod? Mohl byste prostě připojit reset přes tranzistor k zemi a pak ten tranzistor spínat nějakým pinem procesoru, jednodušší a 100% funkční.
Jak může vypadat aktualizační procesor? Ještě jsem nezkoušel dostat aeduino na procesor menší než atmega328, a když už bych ho tam dal, tak by bylo zbytečné ho nevyužívat i jinak než jen jako aktualizační. Lze použít pro arduino jako aktualizační procesor třeba nějaký levný jak attiny10 ? možná s extermním paměťovým čipem?
No na attiny10 byste to určitě nedostal. Možná pokud by to bylo psané v GCC ale ani u toho si nejsem jistý. Kdyby jste si chtěl vše napsat v arduino IDE tak musíte hledat procesor který bude mít +-8KB flash (soudím podle velikosti programu arduinoISP která je asi 4KB). Já teď hodně využívám ATmegy8a, jsou za poměrně slušnou cenu tady v ČR no a z číny, dal jsem asi 5$ za 10ks. Pokud vím tak i 328P by měla být teď levnější, přesněji její redesign 328PB.
Pochybuju že by se nějak vyplatilo kupovat avr s podporou extérní flash, to jsou vyhozené peníze, vyšlo by to dráže než třeba ta mega8a.
když zvolím možnost z aktualizačního procesuru posílat data přes uart, následují nejspíš tyto kroky?:
1. restart procesoru
2. čekání 20ms
3. poslání „řídícího slova“ kde najít jak má vypadat?
4. nahrání bit nebo hex kódu, nebo jende stranky?
5. poslani dalsiho slova s dalsi strankou nebo restart?Zde je odkaz na optiboot wiki kde je popsáno jak zhruba optiboot funguje. To by mělo zodpovědět otázky restartů a posílání dat. Na té stránce je pak odkaz na dokumentaci STK500 kterou optiboot používá, zde přikládám odkaz na PDF. Jsou tam všechny příkazy společně s jejich hexadecimálním číslem.
A takové finále tady je stránka na které je vypsaný celý proces programování arduina opět s hex reprezentací příkazů. Tohle by vás snad mělo dovést do zdárného konce.
Držím palce, Vojta
6.4.2017 v 19:11 #11038michal123ÚčastníkJe mi tedy jasné, že resetuji procesor a pak ho začnu programovat, ale stále se v těch příkazech nějak nevyznám.
Prošel jsem výše zmíněné odkazy ale nekokážu si podle toho ani předsatvit jak by měl vypadat funkční výsledek.
Nevím jaké příkazy použít bylo by prosím možné odkázat na nějaký příklad? takový kde by bylo nejlépe Serial.write(„prikaz1“) a seznam rpikazu tak jak se pouzivaji.
Chtěl jsem odposlechnout stávající komunikaci při programování za prevodnikem z usb ale k tomu mi nyní jedno arduino chybí, takže budu muset počkat.
Doufám, že mi to brzy dojde a naprogramování se podaří.6.4.2017 v 20:21 #11039Vojtěch VosáhloÚčastníkNo ono to odposlouchávání není nutné, ta stránka kterou jsem posílal to řeší za vás, tam je odposlech komunikace mezi arduinem UNO a Arduino IDE (respektive avrdude který je řízený Arduino IDE).
Vše co je tam vypsáno je rozhovor který spolu avrdude a arduino vedou, u každého příkazu je napsáno zkratkou co znamená a je u něj hexadecimální reprezentace.Ukážu tady jak bych tím procházel já. Pojďme vzít první dva řádky zaznamenané komunikace z té stránky.
Avrdude/Arduino IDE:#30#20 STK_GET_SYNCH (mělo by být jen STK_GET_SYNC), Sync_CRC_EOP
Target/Arduino UNO: #14#10 STK_INSYNC, STK_OKPrvní je Avrdude/Arduino IDE:#30#20 STK_GET_SYNCH, Sync_CRC_EOP, to je tedy sada příkazů kterou pošle avrdude na sériový port, ve vašem případě by tyto příkazy odesílal aktualizační procesor. #30#20 je vlastně ta HEX reprezentace příkazů, první má tedy hodnotu 0x30 a druhý 0x20, to co následuje je jen vysvětlení toho příkazu jeho zkráceným názvem. 0x30 má tedy název STK_GET_SYNC a už podle názvu se dá usoudit že avrdude zjišťuje jestli je spojené s procesorem a snaží se s ním spojit. Kdyby to bylo málo, otevřu si datasheet STK500 a vyhledám si příkaz buď podle HEX čísla nebo zkratky. U tohoto příkazu bych dostal takovéto detaily
Use this command to try to regain synchronization when sync is lost. Send this command
until Resp_STK_INSYNC is received.plus nějaké další věci. Druhý příkaz bych si opět dohledal atd…
Druhý řádek už je odpověď arduina na dotazy, přesněji Target/Arduino UNO: #14#10 STK_INSYNC, STK_OK. Opět dostaneme nazpět HEX čísla, tentokrát 0x14 a 0x10 a jejich vysvětlení. Mohl byste tedy odpověď přečíst a po jejím vyhodnocení pokračovat dál.
Příkazy u kterých je v závorce text Command that is consumed but ignored by the bootloader prakticky nemusíte posílat vzhledem k tomu že je bootloader ignoruje.
Kdyby jste tedy chtěl napsat program který by tuto komunikaci simuloval, musíte odesílat do arduina příkazy přavě jako jejich HEX hodnoty. Na odesílání by stačilo použít třeba Serial.print(DEC reprezentace prikazu, HEX);
Například pro poslání příkazu s kódem 0x30 by byl Serial.print(48, HEX);
48 je 0x30 převedeno na desítkovou soustavu.
nemělo by být potřeba posílat <CR> nebo <LF>, alespoň to není zmíněno.Já se vám tu asi o víkendu až budu mít čas ještě ozvu s nějakým kódem, sám si to rád zkusím. Vy se zatím můžete ještě podívat na to co jsem napsal.
Hezký večer
6.4.2017 v 22:00 #11044michal123ÚčastníkDěkuji, tohle mi hodně pomohlo, už mi to začíná být jasné. Za nějaký kód budu také moc rád. Přeji pěkný víkend.
8.4.2017 v 20:09 #11070Vojtěch VosáhloÚčastníkTak jo, po troše trápení mám kód který funguje. Je pořád co doplňovat ale to už byste mohl zvládnout vy. Co to teď dělá? Prakticky je schopný zjistit jestli má spojení s procesorem a přečíst jeho podpis (device signature), také už je hotová skoro celá rutina na zápis do paměti, tu si ale musíte dodělat vy. Nevím jak budete stahovat data z netu takže si sám budete muset doplnit smyčku která nafluše data na sériový port, na to už by ale mělo stačit jen jednoduché for(). No, níže přikládám ten kód, je to prakticky ready to go, jediné co budete muset změnit je rychlost software serial, pro UNO je to 115200, Nano je 57600 a pro Diecemila a Duemilanove je to 19200. Piny software serialu jsou nastavené na 10 jako RX a 11 jako TX, reset pin je na 2. Vše se dá změnit hned nahoře nad setupem. Všechny funkce vracejí 1 pokud jsou úspěšně provedeny a 0 pokud je někde chyba. Tak snad bude fungovat 😉
Hezký zbytek víkendu.
KÓD:
Je na pastebinu https://pastebin.com/rQaMxMc710.4.2017 v 21:56 #11090michal123ÚčastníkDěkuji, bodůžel si musím počkat do středy na další arduino, takže pak napíšu jak mi to jde.
12.4.2017 v 13:28 #11098Vojtěch VosáhloÚčastníkJeště jako bonus tady dávám obrázek jak jsem to měl zapojené. Programátor je samozřejmě arduino na kterém běží kód co jsem výše posílal.
-
AutorPříspěvky
- Pro reakci na toto téma se musíte přihlásit.