Close

aktualizování firmwaru přes uart

Úvodní stránka Fórum Vaše projekty Arduino aktualizování firmwaru přes uart

Aktuálně je na stránce zobrazeno 30 příspěvků - 31. až 60. (celkem z 69)
  • Autor
    Příspěvky
  • #11142
    michal123
    Účastník

    Děkuji, já zkoušel nastavit smyčku s pohyblivou mezerou a pak vypisovat neuspechy se zastaveni když by byl úspěch ale nšjak se to nepovedlo, nic nezabralo, treba to bude tím že už je pozdě. Konečně už mám osciloskop i když s ním pěkně zápasím aby ukazoval co má.

    už mám bjednaní samotné atmegy takže je plánuji pro další testování (až ohle bude fungovat) dát na desku a tím snad eliminovat tyhle různé chyby.

    Pěkný večer

    #11145
    Vojtěch Vosáhlo
    Účastník

    No 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?

    #11148
    michal123
    Účastník

    Vyzkoušel jsem nový kód a už je to lepší. procesor už odpovídá. nedá se říct že by se synchronizoval hned ale to si treba jeste vyladím.

    pozitivní odpoved v sériáku:
    Podpis procesoru: 1E950F
    Synchronizovan s cipem
    Parametry ziskany

    ale co dál, ještě mi nejde do hlavy jak je to s „pocatecniAdresaX“ a „velikostStrankyX“ a mohu nahravana data zapsat takto?
    programator.write(„100000000C945…0001FF“);
    samozrejmě bych to pak nahradil za nějakou nahrávací smyčku.

    Mohl by jste mi případně poslat celý funkční program pro nahrání blink?

    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)

    #11149
    Vojtěch Vosáhlo
    Účastník

    ale 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 pole

    byte 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.

    #11151
    michal123
    Účastník

    jak 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ů?

    Kde vezmu počáteční adresu? je to vždy 0x3E00?

    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)?

    Ruční prepisování bytů nemá smysl http://www.branah.com/ascii-converter by mohl případně dělat co chceme ale raději bych dal přednost ušetření datové komunikace snad for cyklem s polem charů.

    Děkuji, zítra odpoledne se sem snad zase dostanu.

    K zapisování jednotlivýchy bytů by

    #11152
    Vojtěch Vosáhlo
    Účastník

    jak 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_EOP

    I 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.

    Tady je opět odkaz na pastebin s porovnáním HEX souboru který vygeneruje arduino IDE a toho co posílá procesoru.

    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ší.

    #11154
    michal123
    Účastník

    Děkuji, už je mi to snad jasné, zkusím napsat kód (ale bude mi to chvíli trvat)

    #11155
    michal123
    Účastník

    Na co je getParams() ? co to říká? jen to testuje, že procesor reaguje? Je to zjískané číslo jedinečné (dá se na to spolehnout?)?

    #11156
    Vojtěch Vosáhlo
    Účastník

    Tak 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.

    #11163
    michal123
    Účastník

    Konečně jsem se k tomu odstal, je tedy možné to napsat nějak takhle?
    samozřejmě pro fungování by to tímto způsobem bylo příloš dlouhé a náročné, možní nespolehlivé.

    https://pastebin.com/HxW5D4p1

    Budu rád když mi řeknete co všechno je špatně případně co by šlo lépe.

    #11166
    Vojtěch Vosáhlo
    Účastník

    Jen 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

    #11167
    michal123
    Účastník

    zatím teoretická verze, k arduinu se dostanu až večer (později) a jsem si téměř jist že to fungovat nebude (dělám dost chyb a máloco ufnguje na první pokus).

    Děkuji moc za vysvětlení, doufám že se mi to brzy podaří odzkoušet.

    #11168
    Vojtěch Vosáhlo
    Účastník

    Kdyby 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é.

    #11169
    michal123
    Účastník

    Tak jsem opravil pár chyb a dostal jsem se k chybám v zapisdata(), to nefunguje vůbec.
    Když

     for(int i=0;i<100;i++){
          Serial.print(str[0][i]);
        }

    pak to vypíše nesmysly a když do toho napíšu HEX tak to taky není lepší, Takže vůbec netuším čím to je ale snad mi to dojde zítra.

    #11170
    Vojtěch Vosáhlo
    Účastník

    No 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.

    #11176
    michal123
    Účastník

    Děkuji, už to také vidím ale porád si nedovedu vysvětlit, že to vracelo blbosti i když tam HEX nebylo.
    Az přiijdu odpoledne domů tak to znovy vyzkouším s polem UINT_8 které by k tomu mělo být nejspíš nejlepší.

    #11177
    Vojtěch Vosáhlo
    Účastník

    No s typem pole problém nebude, jde o to co a jak do něj zapíšete.

    #11185
    michal123
    Účastník

    Nějak mi trvalo dlouho než jsem se k tomu vůbec dostal, tady posílám nějak opravený neodzkoušený kód
    Zítra se k němu dostanu zase až pozdě, zatím kód funguje do funkce kolem řádku 311 taže už to snad brzy vyjde.

    #11195
    michal123
    Účastník

    Tak jsem pořád zaseknutý na tomhle
    Proč to nefunguje? a jak na to?

    #11196
    Vojtěch Vosáhlo
    Účastník

    No 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.

    #11197
    michal123
    Účastník

    Děkuji, mám další problém.
    Nejspíš jsem ze zamotal kolem 336 řádku, zdá se, že proces již proběhne celý ale někde v tatech musí bých chyba protože arduino pořád nebliká.

    #11198
    Vojtěch Vosáhlo
    Účastník

    Zkuste trošku přiblížit co to má dělat, pak na to můžu kouknout. Jak nebliká, jako sériová komunikace?

    #11199
    michal123
    Účastník

    Mělo by to do druhého procesoru přes piny A2 A3 sw serial nahrát hex z proměné str.
    vypadá to, že procesor naváže synchronizaci, něco i do druhého naprgramuje ale druhý procesor po naprogramování a restartování nic nedělá.
    (doufám, že to takto stačí)

    #11205
    Vojtěch Vosáhlo
    Účastník

    Tak 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.

    #11217
    michal123
    Účastník

    Ještě jedna drobnost, proč mi to nejde když tak dám hex od blink z arduina?

    #11223
    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.

    #11224
    michal123
    Účastník

    Děkuji brzy ozkouším, jak jste na to přišel?

    #11225
    Vojtěch Vosáhlo
    Účastník

    Nic extra, prostě jen metoda pokus omyl. Vím že při malých datech to fungovalo ale když bylo dat víc, nevzalo arduino vše, tak jsem tipnul a vyšlo to ?

    #11230
    Vojtěch Vosáhlo
    Účastník

    Ještě jsem zapoměl zmínit že jsou tam 2 programy. Kratší je blink v GCC s pauzou 100ms a delší je arduinovské Blink s pauzou 1s. Prostě si odkomentujte co potřebujete a nebo zkuste vlastní kód.

    #11262
    michal123
    Účastník

    DObrý večer,
    nejspíš jsem nepochopil tu 1s pauzu.
    Kód funguje pro blink ale už ne pro blink na jiných pinech. Když jsem se na komunikaci kouknul osciloskopem tak jsem zjistil, že arduino když nahrává tak 20,5ms čeká, pošle řídící kód, pak 16ms čeká a pak nahraje stránku a tak to opakuje. (ještě to pak všechno zpětně ověří)
    Ale když se podívám na naše data tak, rídících kódů je tam zdáse víc (nevím co arduino neposílá nebo kde nečeká protože z toho nevyluštím konkrétní hodnoty.(případně pošlu nějaké obrázky), časem snad postavím další (arduino) pro paraelní čtení komunikace.

Aktuálně je na stránce zobrazeno 30 příspěvků - 31. až 60. (celkem z 69)
  • Pro reakci na toto téma se musíte přihlásit.