Vojtěch Vosáhlo
Vytvořené odpovědi
-
AutorPříspěvky
-
Vojtěch VosáhloÚčastník
Oprava je na tomto linku. Stačilo jen pozměnit delay při posílání charakterů na 10us, viz. řádek 349.
Vojtěch VosáhloÚčastníkTak bylo tam hned několik problémů. Zaprvé problém s konverzí toho ascii na hex a pak i se samotným zápisem v poli + pár smyček atd.
Nebudu vysvětlovat vše co jsem změnil ale jen to co potřebujete vědět. Nejdůležitější je asi konverze kterou jste prováděl, v poli jste měl sice zapsané byty tak jak by měly být ale pak jste posílal prakticky jen polovinu. Příklad:
Měl jste v poli byte 0x0C který by měl být v tomto tvaru odeslán do arduina ale vy jste ho posílal jako 2 byty, 0x00 a 0x0C, takhle tomu bylo u každého z nich.Upravil jsem tedy kód tak, aby jste do pole mohl zapsat jednu stránku, tzn 128B, ve vašem případě !!!256!!! charakterů, 256 kvůli tomu že jeden byte je reprezentován dvěma charaktery. Pokud budete tedy kopírovat data z intel hex souboru, odpovídá 256 charakterů přesně 8mi řádkům (pokud se odstraní :10 0000 00 ze začátků a poslední hex číslo což je checksum).
Opět dávám odkaz na pastebin, ten kód co tam je je PLNĚ funkční a uploadne na arduino program který bliká led na pinu 13 jednou za 100ms. Zkuste si sám jestli vám poběží.
Hezký zbytek dne.
Vojtěch VosáhloÚčastníkZkuste trošku přiblížit co to má dělat, pak na to můžu kouknout. Jak nebliká, jako sériová komunikace?
Vojtěch VosáhloÚčastníkNo na začátku jste arduinu řekl že chcete proměnnou uložit do flash, teď mu tedy musíte říct že chcete číst z flash. Aby kód fungoval, musí vypadat takto:
const uint8_t strr[4][50] PROGMEM = {//tohle je pro ukazku, dale se bude nacitat postupne coz uz ale nebude problem "0123456789ABCDEF", "230000000000000000000000000000", "600000000000000000000000000000", "800000000000000000000000000000" }; void setup() { Serial.begin(115200); Serial.println(strr[0][1]); Serial.println(strr[0][13]);//tady to jeste funguje for (int a = 0; a < 13; a++) { //3 Serial.print(a); Serial.print(","); Serial.print(pgm_read_byte(&(strr[0][a])), BIN);//proc to ve foru nefunguje? Serial.print("\t,"); Serial.println(pgm_read_byte(&(strr[1][a])), BIN); } } void loop() { }
Důležité je právě pgm_read_byte();, to označuje že chcete číst z programové paměti.
Vojtěch VosáhloÚčastníkNo s typem pole problém nebude, jde o to co a jak do něj zapíšete.
Vojtěch VosáhloÚčastníkNo ono to je pochopitelné ale mě to nedošlo. Vy máte vaše pole zapsané jako stringy. Viz třeba 1. řádek:
"0C9457000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C9469000C946900"
To si ale arduino neinterpretuje tak jak potřebujete. Dal jste to jako string takže arduino to má za sérii charakterů, např. nula by se tedy přeložila na 48 DEC podle ASCII. Musel byste buď použít nějaký převodník který by předělal HEX čísla na znaky které byste pak zapsal jako string a nebo čísla zapisovat v jakémkoliv tvaru (hex, dec nebo jako char) po kolonkách – 0x0C, 0x94, 15, ‚P‘,…
Možná jsem si nevšiml nějaké konverze, taky jsem tu zmiňovanou smyčku vůbec neviděl v kódu. Kdyžtak mě odkažte na řádky.
Vojtěch VosáhloÚčastníkKdyby něco nešlo tak pište, po ruce mám 4 arduina a RS232 převodník tak můžu kdyžtak odšpehovat co arduino pošle, pokud tohle nemáte dostupné.
Vojtěch VosáhloÚčastníkJen pár vysvětlení. V kódu jste se ptal proč jsem použil toto:
for(int i = 0; i <= programator.available(); i++){ prichozi[i] = programator.read(); } //vyhodnoti jestli jsme dostali OK odpoved if(prichozi[0] == 0x14 && prichozi[1] == 0x10){ return 1; }else return 0;
A důvod je jednoduchý, bylo to jediné co mi 100% fungovalo. Pokud vám funguje metoda s if, nechte jí, to je určitě lepší ale pro mě nefungovala a nebo jsem ji měl možná špatně zapsanou.
Tyto smyčky:
while (!programator.available()) { ; }
jsou problém a to už u mě protože program se v nich může zaseknout a jet do nekonečna. Zkuste implementovat kolik pokusů má na to aby získala data, pokud půjde přes limit, vyskočíme z ní. Mohlo by to vypadat třeba takto:
int maxPokusy = 5000; int pokus = 0; while (!programator.available() && pokus < maxPokusy) { pokus++; } pokus = 0;
Na toto:
//ZAPIS DAT programator.write(0x46);//-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-nevim jak ste na to prisel
jsem přišel ze zmíněné stránky, z vlastního odposlechu arduina a z datasheetu. 0x46 převedeno na charakter je F, to znamená že se uploaduje do Flash paměti. Je možnost použít E kdyby jste něco uploadoval do Eeprom.
Jinak žádnou do oka bijící chybu nevidím. Zkoušel jste už program nebo je to pořád „teoretická“ verze?
Vojta
Vojtěch VosáhloÚčastníkTak jak to stojí a leží jen získá podpis procesoru. To je číslo jedinečné pro rodinu procesorů a né každý zvlášť. 1E950F je podpis procesorů řady Atmega328P, každý z procesorů by tedy odpověděl stejným číslem. Každopádně musí být vždy stejné (u určité řady) takže se s ním dá i kontrolovat jestli je komunikace v pořádku.
Vojtěch VosáhloÚčastníkjak zjistím velikost stránky?
Předpokládám, že tahle velikost strany je velikost celého programu který se z nějakého důvodu nenahrává po stranách (kterých má být 256) ale celý najendou.
Kde přesně jí vezmu když mám hex soubor vytvořený arduinem? Mohlo by to být třeba tak, že vyzmu hex subor, odstraním z něj dvojtečky (na začátku každého řádku mám dvojtečku), odstraním zalomení řádků a spočítám počet znaků?Není. Velikost stránky kterou používá arduino je u všech základních modelů (tedy UNO, nano atd.) 128B
Vše můžete vzít z vygenerovaného .hex souboru.
Je ve formátu Intel HEX takže data jsou strukturována takto:
[:][Počet bytů][Adresa][Typ zápisu][Data][Nějaký checksum]Vezmu li tedy 1. linku mého hex souboru blink, vypadá takto:
:100000000C9434000C943E000C943E000C943E0082
Po úpravě tak aby se to dobře četlo může vypadat takto:
:#10 #00#00 #00 #0C,#94,#34,#00,#0C,#94,#3E,#00,#0C,#94,#3E,#00,#0C,#94,#3E,#00 #82
Z toho vyčteme že:
[#10] – Počet bytů v tomto řádku je 16. (0x10 -> DEC = 16)
[#00#00] – Hex soubor začíná na adrese #0000 takže i počáteční adresa bude #00
[#00] – Typ záznamu, #00 znamená datový záznam. Jediné co arduino používá je #00 – datový záznam a #01 – konec souboru. Je pro nás taky nevýznamný.
[#0C…#00] – Samotná data, tedy 16B
[#82] – checksum dat, pro nás nevýznamnýPočáteční adresa bývá vždy #0000.
Do arduina se ale nezapisuje jen 16B, programátor musí zapsat celou stránku, tzn. 128B.
Proto si vezme počáteční adresu z hex souboru (#0000) a načte si 128B dat. Pak na programovaný procesor vyflusne data ve formátu:
#55 #0000 #20 – tedy STK_LOAD_ADDRESS, 0x0000, SYNC_CRC_EOP – Tohle připraví programování.Poté už přijde samotný zápis dat.
#64 #00#80 #46 [128B dat] #20 – tedy STK_PROGRAM_PAGE, 0x0080 (velikost stránky), ‘F'(flash paměť), 128B dat,SYNC_CRC_EOPI když váš program nemá přesný počet bytů na stránku, musí se zapsat stránka celá, zbylé místo se tedy doplňuje #FF.
Ano poslat data v hex tvaru by vyřešilo tenhle problém ale byl by zbytečně velký tok dat při aplikaci, takže bych se zkusil vydat první cestou programator.write(“P”);
mohu tedy data uložit do proměné (nejspíš pole charů) a potom je posílat s tím že funkce write pošle bajt po bajtu (tedy for cyklem)?Úplně nevím co tím myslíte. Datový tok by měl být vždy stejný vzhledem k tomu že vždy posíláte X bytů reprezentovaných HEX číslem nebo charakterem.
Rozhodně neukládat do pole vše ale jen jednu stránku. Vždy byste si řekl modulu o data z internetu, nahrál je do pole a pak je posílal. Na posílání bych asi použil smyčku for jak říkáte, bude to nejlepší.
Vojtěch VosáhloÚčastníkale co dál, ještě mi nejde do hlavy jak je to s “pocatecniAdresaX” a “velikostStrankyX”
Tyhle proměnné slouží k nastavení velikosti stránky a počáteční adresy od které se bude zapisovat. Rozdělil jsem je do dvou bytů (2x8bit) protože bootloader očekává 16bit proměnné ale programator.write() umí odeslat jen jeden byte. Je tedy jednodušší nadefinovat proměnné jako 2 byty a pak je tak i odeslat. Pokud bych tedy měl velikost stránky 0x0080, nastavil bych velikostStrankyA na 0x00 a velikostStrankyB na 0x80.
mohu nahravana data zapsat takto?
programator.write(“100000000C945…0001FF”);Máte prakticky 3 možnosti jak zapisovat. Jako jednotlivé byty – programator.write(0x50);
Jako string ve kterém je vlastně každé písmenko byte – programator.write(„P“); Toto by vlastně poslalo 0x50.
Jako pole bytů – programator.write(buf, len);
buf je pole bytů které chcete vypsat
len je velikost tohoto polebyte buf[2] = {0x50, 0x60};
programator.write(buf, sizeof(buf));Tohle by vypsalo 0x50 a 0x60.
Takže tak jak jste psal se to vlastně vypsat úplně nedá, místo těch HEX čísel by tam museli být znaky reprezentující ta čísla.
Mohl by jste mi případně poslat celý funkční program pro nahrání blink?
Asi zase zítra ale rovnou říkám že budu trochu podvádět 🙂 Budu tam posílat program v GCC a né C++. Blink které je v arduinu má asi 1KB a to je hodně bytů které bych musel přepsat ručně do pole. Proto to bude v GCC kde má blink 176B, to je výrazně méně.
Abych odpověděl, dostal jsem se k osciloskopu keysight DSOX1102G, jen škoda že když jsem se s ním chtěl podávat na data v uartu tak napsal, že bych si ten doplněk musel koupit, což mě štve (má na to knoflík a stejně se to musí zvlášť platit)
Taky jsem na ně koukal, za tu cenu se to skoro nedá nekoupit, no, nekoupil jsem ho. Takovéhle dokupování je opravdu nanic.
Vojtěch VosáhloÚčastníkNo jak jste psal tak ráno je opravdu moudřejší večera 😀 Kód jsem projel, trochu pospravoval ty hovadiny co jsem napsal a vyšpehoval časy resetů a odesílání příkazů z IDE. Tady tedy přikládám druhou verzi. Musel jsem přidat více čekání, podle komunikace co jsem viděl potřebuje arduino asi 20ms čekat než se do něj odešlou příkazy, takže bylo nutné přidat před každý set příkazů delay(100);
Snad vám tohle bude fungovat, u mě to teď běží skoro 100%.
Mimochodem zvědavost mi nedá, co máte za osciloskop?
Vojtěch VosáhloÚčastníkTak to můžu popřát jen hodně štěstí. Já testuju na UNU a NANU a vše šlape jak hodinky. Ještě mě napadla jedna věc, když jsem vymýšlel jaká pauza má po resetu nastat, zapojil jsem reset toho programovaného arduina na D13 programátoru. Programátor měl pak nastaveno že hned po spuštění odešle příkazy. Programované arduino bylo tedy resetováno prakticky tou ledkou na pinu 13 a tím jak bliká při běhu bootloaderu. Vše taky fungovalo bez problému a na testování to postačilo, v takových chvílích by bylo hezké mít po ruce osciloskop… Možná by se s tím dalo něco vymyslet. Já se taky zítra pustím do testování 😉
Hezký večer.
Vojtěch VosáhloÚčastníkJak tak na to koukám tak možná dobře že jsem tu chybu neopravil. Nechte delay na 100, baud nechte jako long ale řádek 49 zakomentujte. Teď mi nedochází proč ale mě kód funguje jen bez něj…
EDIT: Taky mějte obě arduina napájená z výkonných zdrojů. Mě např. nefunguje napájet jedno arduino z druhého, musí mít obě zvlášť 5V zdroj. Nevím proč, regulátor by měl dodávat víc než dost proudu…
Vojtěch VosáhloÚčastníkAsi se pudu pifnout 🙂 je to moje hloupá chyba. Na začátku je baud definován jako int, nahraďte int typem long a mělo by to fungovat. Pro UNO by to tedy mělo vypadat takoto
long baud = 115200;
Krystal je v pořádku.
Vojtěch VosáhloÚčastníkTaké můžete přihodit fotky zapojení ale předpokládám že tam problém nebude.
Vojtěch VosáhloÚčastníkTak pojďme nejdřív zjistit rychlost UARTu. Jděte do arduino IDE, projděte toudo cestou File->Preferences a zaškrtněte obě možnosti u Show verbose output during…
Pokud máte česky tak Soubor->Vlastnosti Zobrazit více informací výstupu během: [Y] Kompilace | [Y] Programování
Teď nahrajte jakýkoliv kód do toho arduina co bude programované (to co bude updatované). Nahrajte normálně přes kabel třeba program Blink, je to jedno. V konzoli by vám mělo vyjíždět výrazně víc informací. Po nahrátí projeďte konzoli a zkuste najít takovýto blok textu:
avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.2.0_x64__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf" Using Port : COM4 Using Programmer : arduino Overriding Baud Rate : 57600 AVR Part : ATmega328P Chip Erase delay : 9000 us PAGEL : PD7 BS2 : PC2 RESET disposition : dedicated RETRY pulse : SCK serial program mode : yes parallel program mode : yes Timeout : 200 StabDelay : 100 CmdexeDelay : 25 SyncLoops : 32 ByteDelay : 0 PollIndex : 3 PollValue : 0x53 Memory Detail :
Tenhle řádek, Overriding Baud Rate : 57600 nás zajímá nejvíc. Jaká je tam rychlost? Klidně sem hoďte celý výstup konzole ale až od toho
avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch
, může se to hodit.
Vojtěch VosáhloÚčastníkJaké arduina používáte a které dělá co? Mají jako sériové převodníky použity ch340 nebo mega16u2?
Vojtěch VosáhloÚčastníkMůžu tu ještě něco říct z vlastní zkušenosti. Přes etherneťák mám připojené senzory k meteostanici které taky komunikují přes i2c a onewire (BMP180, DTH22…). Kabel má přes 5m a senzory jsou napájené přímo přes dvojici drátů. Při proudech které senzory odebírají se prakticky nemusím bát o úbytek napětí na kabelech, při napětí 3.3V a proudu 10mA bych se o něj musel začít bát až na nějakých 100 metrech kabelu. Přenos dat je zatím také bezproblémový. To je moje vlastní zkušenost. Senzory bych klidně napájel po 2 libovolných kablících toho ethernetového kabelu. Možná by bylo lepší mít senzory napájené z vyššího napětí a mít u každého regulátor kdyby jste se bál o ten úpadek napětí. Nevím jak je to přesně s přenosem dat ale možná by pomohlo přenášet je také na vyšších napětích, tzn senzory by měli u sebe převodník z jejich 3.3V pracovního napětí třeba na 5V a naopak. U tohohle ale opravdu nevím jestli by to pomohlo.
Vojtěch VosáhloÚčastníkNo otázka je jakých senzorů a jakými protokoly komunikují. První otázka je asi ohledně hardwarového řešení. To je asi na každém zvlášť, já si třeba oblíbil konektory RJ12 a k nim kabely. Je to vše poměrně levné a dobře funkční. Softwarové řešení se bude odvíjet od toho jak pracují ty senzory. Na přenos dat by se dala použít třeba RS485, tou se dá přenášet na stovky metrů, ale ty senzory budou nejspíše komunikovat přes I2C, SPI nebo RS232. U I2C je limit podle kapacity, myslím že drát by neměl mít víc jak 200pF. RS232 se dá vytáhnout snad až na desítky metrů ale nevím jak funkční pak bude.
Jak říkám je to spíš na vás a na senzorech…
V.
Vojtěch VosáhloÚčastníkZkuste to přes odkaz: https://drive.google.com/open?id=0Bxq_OMaWO7CwaGY5M2VzWWxtSzQ
Vojtě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.
Vojtěch VosáhloÚčastníkA co píše arduino IDE při nahrávání? Zkoušel jste něco co tu bylo napsáno? Ovladače atd.
V.
Vojtěch VosáhloÚčastníkAsi by se hodilo napsat podle jakého návodu a třeba přiložit i kód, bez toho tu asi nikdo nic neudělá.
V.
Vojtěch VosáhloÚčastníkAsi bych koukal po analogových multiplexerech, tam ale vybíráte co chcete kam posílat pomocí 2 a více signálů. Velmi jednoduchá součástka u které kombinací 1 a 0 na nastavovacích pinech přepínáte na jaký výstup má jít vstupní signál.
Vojtě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/rQaMxMc7Vojtě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
Vojtě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
Vojtě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 :/
Vojtě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.
-
AutorPříspěvky