Saját bootloader
Saját bootloader
Sziasztok Urak!
Szeretnék kérni némi iránymutatást a bascom saját bootloaderének kezeléséhez.
Az egyszerűség kedvéért maradjunk Delphi-nél.
A chipre feltöltött bootloaderen keresztül szeretném feltölteni a hex vagy bin állományomat a szintén saját, a procival eleve kommunikáló, Delphiben megírt felhasználói szoftverből; de nem igen jövök rá, hogy hogyan kellene kezelnem magát a bootloaderrel való kommunikáció folyamatát.
Alapbeállításként baud=38400-on kapcsolódok a procihoz, természetesen a feltöltés a bascom-on keresztül minden probléma nélkül működik. Tehát az alapok stabilak.
A Delphi-s oldal is megy, tudom kezelni a file megnyitást, a darabolást olyan szeletekre, amelyek a bootloadernek kellenek, stb.
A kédésem az, hogy ha megvan a bootloader a procin, de már van rajta működő program, akkor mi a teendőm, ha menet közben szeretném frissíteni a procimon a programot? Azt is tudom (a bootloader alapján), hogy egy általam kiadott soros paranccsal el tudom ugratni (pl.: M328P proci esetén) a procit a bootloader szekcióhoz GOTO $h3800 paranccsal. (Esetleg valakinek egy ennél egyszerűbb reset megoldás?)
Ezután mi a folyamat? Vagy, az egyszerűség kedvéért egy "üres" proci esetén, amin csak a bootloader van fent?
1) Milyen byte-okkal vezérlek?
A bootloaderben látom:
- 1: start of heading, PC is ready to send;
- 4: end of transmission , file is transmitted
- 123-al és 124-el is kilép a DO ciklusból; (mi a különbség?)
- minden másra: Exit Do ' no valid data
2) Mit válaszol? Én erre mit válaszolok??
2) Mekkora darabokban küldöm a feltöltendő programot?
3) A hex-et, vagy a bin-t küldöm? (Bár nyilván a BIN-t, hiszen a bascom külső bootloader programja is a BIN-t kéri)
Bízom benne, hogyg tudtok segíteni.
Nyilván nem konkrét Delphi-s programsorok érdekelnek, hanem a folyamat...
Előre is köszönöm a hozzászólásokat.
Szeretnék kérni némi iránymutatást a bascom saját bootloaderének kezeléséhez.
Az egyszerűség kedvéért maradjunk Delphi-nél.
A chipre feltöltött bootloaderen keresztül szeretném feltölteni a hex vagy bin állományomat a szintén saját, a procival eleve kommunikáló, Delphiben megírt felhasználói szoftverből; de nem igen jövök rá, hogy hogyan kellene kezelnem magát a bootloaderrel való kommunikáció folyamatát.
Alapbeállításként baud=38400-on kapcsolódok a procihoz, természetesen a feltöltés a bascom-on keresztül minden probléma nélkül működik. Tehát az alapok stabilak.
A Delphi-s oldal is megy, tudom kezelni a file megnyitást, a darabolást olyan szeletekre, amelyek a bootloadernek kellenek, stb.
A kédésem az, hogy ha megvan a bootloader a procin, de már van rajta működő program, akkor mi a teendőm, ha menet közben szeretném frissíteni a procimon a programot? Azt is tudom (a bootloader alapján), hogy egy általam kiadott soros paranccsal el tudom ugratni (pl.: M328P proci esetén) a procit a bootloader szekcióhoz GOTO $h3800 paranccsal. (Esetleg valakinek egy ennél egyszerűbb reset megoldás?)
Ezután mi a folyamat? Vagy, az egyszerűség kedvéért egy "üres" proci esetén, amin csak a bootloader van fent?
1) Milyen byte-okkal vezérlek?
A bootloaderben látom:
- 1: start of heading, PC is ready to send;
- 4: end of transmission , file is transmitted
- 123-al és 124-el is kilép a DO ciklusból; (mi a különbség?)
- minden másra: Exit Do ' no valid data
2) Mit válaszol? Én erre mit válaszolok??
2) Mekkora darabokban küldöm a feltöltendő programot?
3) A hex-et, vagy a bin-t küldöm? (Bár nyilván a BIN-t, hiszen a bascom külső bootloader programja is a BIN-t kéri)
Bízom benne, hogyg tudtok segíteni.
Nyilván nem konkrét Delphi-s programsorok érdekelnek, hanem a folyamat...
Előre is köszönöm a hozzászólásokat.
Re: Saját bootloader
A Bootloader tanulmányozása alapján arra jutottam, hogy a sok szakirodalomban említett 132byte-os csomagok igazából 131byte-osak...
Bár nem értem miért.
Alább a kommentjeim, amelyekre a progi működése alapján következtetek:
(A Bootloader.bas vonatkozó része a "Cdebug"-októl és felesleges villogtatásoktól megtisztítva)
Ahol az én kérédéseim vannak az nem egészen világos. (A többi az többé-kevésbé...)
A CSUM változóba tényleg csak simán pakolássuk bele a byte-okat? (+1)
Valakinek ötlet?
Bár nem értem miért.
Alább a kommentjeim, amelyekre a progi működése alapján következtetek:
(A Bootloader.bas vonatkozó része a "Cdebug"-októl és felesleges villogtatásoktól megtisztítva)
Kód: Egész kijelölése
Bstatus = Waitkey() ' Várjuk a loader által küldött '123' vagy '124' byte-ot (123-FLASH; 124-EEPROM)
Print Chr(bstatus); ' Visszajelezzük a loadernek, hogy a byte -ot megkaptuk (ez a 123 látszik a BASCOM-ban MCS Bootloader esetén)
' Itt ugrunk a loader szekcióhoz.
If Bstatus = 123 Then 'did we received value 123 ?
Bkind = 0 'normal flash loader
Goto Loader
Elseif Bstatus = 124 Then ' EEPROM
Bkind = 1 ' EEPROM loader
Goto Loader
Elseif Bstatus <> 0 Then
Decr Bretries
If Bretries <> 0 Then Goto Testfor123 'we test again
End If
Goto _reset ' A RESET csak akkor következik be, ha nem érkezett '0'-tól nagyobb érték
'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
Do
Bstatus = Waitkey() ' itt mit várunk??
Loop Until Bstatus = 0
If Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
Bretries = 10 'number of retries
Do
Bstarted = 0 ' we were not started yet
Csum = 0 'checksum is 0 when we start
Print Chr(nak); ' firt time send a nack (Visszajelzés a procitól)
Do
Bstatus = Waitkey() 'wait for statuse byte
Select Case Bstatus
Case 1: ' start of heading, PC is ready to send
Incr Bblocklocal 'increase local block count (a legelső = 1)
Csum = 1 'checksum is 1
Bblock = Waitkey() : Csum = Csum + Bblock 'get block (ezt már a BIN-ből veszi? ha igen, akkor ez a legelső byte-ja a BIN-nek?)
Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte
For J = 1 To 128 'get 128 bytes
Buf(j) = Waitkey() : Csum = Csum + Buf(j)
Next
Bcsum2 = Waitkey() 'get second checksum byte (ezt is a BIN-ből veszi?)
If Bblocklocal = Bblock Then 'are the blocks the same?
If Bcsum2 = Csum Then 'is the checksum the same?
Gosub Writepage 'yes go write the page
Print Chr(ack); 'acknowledge
Else 'no match so send nak
Print Chr(nak);
End If
Else
Print Chr(nak); 'blocks do not match
End If
Case 4: ' end of transmission , file is transmitted
If Wrd > 0 And Bkind = 0 Then 'if there was something left in the page
Wrd = 0 'Z pointer needs wrd to be 0
Spmcrval = 5 : Gosub Do_spm 'write page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
Print Chr(ack); ' send ack and ready
Portb.3 = 0 ' simple indication that we are finished and ok
Waitms 20
Goto _reset ' start new program
Case &H18: ' PC aborts transmission
Goto _reset ' ready
Case 123 : Exit Do 'was probably still in the buffer
Case 124 : Exit Do
Case Else
Exit Do ' no valid data
End Select
Loop
If Bretries > 0 Then 'attempte left?
Waitms 1000
Decr Bretries 'decrease attempts
Else
Goto _reset 'reset chip
End If
Loop
A CSUM változóba tényleg csak simán pakolássuk bele a byte-okat? (+1)
Valakinek ötlet?
Re: Saját bootloader
Szevasztok!
A fenti kérdésemre továbbra is izgatottan várom az esetleges ötleteket.
Menet közben azonban újabb kérdés merült fel:
Ha a bascom bootloaderét használom, akkor meg lehet-e tenni azt, hogy a bootloaderben létrehozok egy változót egy fix memóriacímen, majd azt az értéket felhasználom a normál program futása közben az adott címről kiolvasva?
A fenti kérdésemre továbbra is izgatottan várom az esetleges ötleteket.
Menet közben azonban újabb kérdés merült fel:
Ha a bascom bootloaderét használom, akkor meg lehet-e tenni azt, hogy a bootloaderben létrehozok egy változót egy fix memóriacímen, majd azt az értéket felhasználom a normál program futása közben az adott címről kiolvasva?
Re: Saját bootloader
Bascom oldalról megközelítve:
1, mentheted az adatot EEPROMba és azt bootloader/főprogram alól is eléred.
2, SRAM esetén a bootloader a memóriába beleír (használja) és a Tx/Rx lábakat is irányba állítja/soros initet végrehajt*. A SRAM hazsnálatának nyomait RAM törléssel tűnteti el . DE: $NORAMCLEAR direktívát az elején megadva a RAM törlés nem megy végbe!
Vigyázz! Ha DIM-mel foglalsz memóriát/változót/tömböt - akkor a nem törölt tartalom miatt véletlenszerű az indulási értéke (nem a Bascomban megszokott &H00 érték)!!! A fix címen létrehozott változó a
* Ez a főprogram futása alatt probléma lehet, mert a lábakat "szűz chipindulást feltételezve" nem iniciáalizálja a bascom (kivéve, ha TE a programban megteszed). Minden láb bemenet felhúzóellenállás nélkül és a járulékos belső HW nincs hozzárendelve (INT, ADC, stb). A BOOTLOADER _elpiszkálja_ a Tx/Rx-et alapesetben.
123 ill 124 kód:
Flash-t vagy EEPROM-ot bootloadoltál - annak a kilépése:).
Csomagméret: az utolsó a stringet lezáró 0 kódú karakter (ez a 132. karaktered)
Igen, BIN megy fel.
Mit küld /fogad? Sorosport minitor illetve soros port snifferrel lesd meg.... sermon a program neve (sysinternals készítette) a Win alatt. Jó régen használtam....
1, mentheted az adatot EEPROMba és azt bootloader/főprogram alól is eléred.
2, SRAM esetén a bootloader a memóriába beleír (használja) és a Tx/Rx lábakat is irányba állítja/soros initet végrehajt*. A SRAM hazsnálatának nyomait RAM törléssel tűnteti el . DE: $NORAMCLEAR direktívát az elején megadva a RAM törlés nem megy végbe!
Vigyázz! Ha DIM-mel foglalsz memóriát/változót/tömböt - akkor a nem törölt tartalom miatt véletlenszerű az indulási értéke (nem a Bascomban megszokott &H00 érték)!!! A fix címen létrehozott változó a
Kód: Egész kijelölése
DIM valami AT &Hmemóriacím
123 ill 124 kód:
Flash-t vagy EEPROM-ot bootloadoltál - annak a kilépése:).
Csomagméret: az utolsó a stringet lezáró 0 kódú karakter (ez a 132. karaktered)
Igen, BIN megy fel.
Mit küld /fogad? Sorosport minitor illetve soros port snifferrel lesd meg.... sermon a program neve (sysinternals készítette) a Win alatt. Jó régen használtam....
http://www.tavir.hu - a gazda
Re: Saját bootloader
Szeva Robi!
Köszi az infót. Akkor jól sejtem, hogy a $NORAMCLEAR direktívát a főprogramomba kell implementálnom, mondván, hogy annak az indulásakor ne törölje a SRAM területet.
Tételezzük fel, hogy a bootloaderben létrehozom a változót:
Ami azt jelenti, hogy az SRAM terület 300hex címére beíródik 2byte, 1545dec tartalommal.
Ez ott is marad a főprogram indulásakor, amennyiben használom a $NORAMCLEAR direktívát és például ugyan azzal a változódeklarációval tudom kiolvasni az ott lévő értéket:
Jól tévedek?
Köszi az infót. Akkor jól sejtem, hogy a $NORAMCLEAR direktívát a főprogramomba kell implementálnom, mondván, hogy annak az indulásakor ne törölje a SRAM területet.
Tételezzük fel, hogy a bootloaderben létrehozom a változót:
Kód: Egész kijelölése
DIM Secure_DTA as WORD AT $300
Secure_DTA = 1545
Ez ott is marad a főprogram indulásakor, amennyiben használom a $NORAMCLEAR direktívát és például ugyan azzal a változódeklarációval tudom kiolvasni az ott lévő értéket:
Kód: Egész kijelölése
DIM Secure_DTA as WORD AT $300 'A Secure_DTA változóban továbbra is a 1545-ös érték van
If Secure_DTA = 1545 Then Print "Everythings All Right!"
Re: Saját bootloader
Igen, így kell megoldani.
Tippek:
$NORAMCLEAR - nincs memóriatörlés induláskor
$NOINIT - nincs _semmiféle_ inicializálás induláskor
$INITMICRO - saját INIT utasítások beépítése - chip indulásakor
Tippek:
$NORAMCLEAR - nincs memóriatörlés induláskor
$NOINIT - nincs _semmiféle_ inicializálás induláskor
$INITMICRO - saját INIT utasítások beépítése - chip indulásakor
http://www.tavir.hu - a gazda
Re: Saját bootloader
A $NORAMCLEAR direktívával remekül működik amit szerettem volna. Ha a booltoaderben beállítok egy változóz egy előre lefoglalt SRAM területen, akkor azt a főprogramban vissza tudom olvasni.
Ha egy olyan Bootot teszek fel, amiben nincs beállítva ez a változó, akkor a főprogram hibával leáll (hiszen nem találja a hitelesítő adatot amit a bootloader ír be)
A teljes védelem úgy alakulna ki, ha visszaolvasás ellen védeni lehetne a boot területet. Ez elvileg lehetséges a BLB1 fuse bitekkel.
A bökkenő csak az, hogy ezt akár hogyan állítom is be (mind három lehetőséggel próbáltam), a visszaolvasott HEXet visszatöltve működik a programom.
Azt várnám, hogy a BLB1-el lezárva a boot szekciót, majd nem lehet visszaolvasni a bootloadert.
Ha levédem az APP területet is a BLB0-al, akkor meg nem működik a rendszer.
...de ha az LB fuse-al lezárom a verifikációt és a visszaolvashatóságot, akkor meg megintcsak nem fogok tudni programozni bootloaderrel. Vagy nem?
Miért nem működik a BOOT fuse beállításom?
Ha egy olyan Bootot teszek fel, amiben nincs beállítva ez a változó, akkor a főprogram hibával leáll (hiszen nem találja a hitelesítő adatot amit a bootloader ír be)
A teljes védelem úgy alakulna ki, ha visszaolvasás ellen védeni lehetne a boot területet. Ez elvileg lehetséges a BLB1 fuse bitekkel.
A bökkenő csak az, hogy ezt akár hogyan állítom is be (mind három lehetőséggel próbáltam), a visszaolvasott HEXet visszatöltve működik a programom.
Azt várnám, hogy a BLB1-el lezárva a boot szekciót, majd nem lehet visszaolvasni a bootloadert.
Ha levédem az APP területet is a BLB0-al, akkor meg nem működik a rendszer.
...de ha az LB fuse-al lezárom a verifikációt és a visszaolvashatóságot, akkor meg megintcsak nem fogok tudni programozni bootloaderrel. Vagy nem?
Miért nem működik a BOOT fuse beállításom?
Re: Saját bootloader
Bootloadert _felülírás_ ellen véded a fusebittel.
A chipet (teljesen) meg read/verify ellen. A LB lezárás csak a _külső_ programozós megoldásra korlátozódik. A LPM/SPM enable/disable az az hogy a flasht írhatod-e SW-ből.
Ha biztosra akarsz menni:
- disable debugwire/jtag
- disable ISP
- lockbitek es R/W védelem
- EEPROM preserve: nem
Ekkor csak nagyfesz soros/paralell programozóval eshetsz neki és az első lépés ERASE.
A chipet (teljesen) meg read/verify ellen. A LB lezárás csak a _külső_ programozós megoldásra korlátozódik. A LPM/SPM enable/disable az az hogy a flasht írhatod-e SW-ből.
Ha biztosra akarsz menni:
- disable debugwire/jtag
- disable ISP
- lockbitek es R/W védelem
- EEPROM preserve: nem
Ekkor csak nagyfesz soros/paralell programozóval eshetsz neki és az első lépés ERASE.
http://www.tavir.hu - a gazda
Re: Saját bootloader
Akkor nekem tulajdonképpen pont azt az esetet kellene használnom, hogy az LB bitet állítom be prog+ver disabled-re és minden mást hagyok Not programmed-en. (BLB0, BLB1)
Ekkor a chipet törölve újra lehet programozni ISP-n, de kiolvasni nem. Viszont a bootloaderből tudom frissíteni a főprogit.
Ekkor a chipet törölve újra lehet programozni ISP-n, de kiolvasni nem. Viszont a bootloaderből tudom frissíteni a főprogit.
Re: Saját bootloader
Üdv Urak!
Megvilágosodtam! (asszem'):
https://pythonhosted.org/xmodem/xmodem. ... yte-blocks
A linken megtekinthető infó alapján XModem-protokoll, amit a BASCOM bootloader is használ (ahogy azt a HELP-ben jelölik is ).
Magából a BIN állományból csak 128byte-os csomagokat szedegetünk ki.
Minden csomag elé oda bisszesztjük az első két byte-ot (ezt a mi programunk kezeli és küldi ki a blokkok elején):
1.BLOCK: 01; FE; [128byte a BIN állományból]; CSUM1
2.BLOCK: 02; FD; [128byte a BIN állományból]; CSUM2
3.BLOCK: 03; FC; [128byte a BIN állományból]; CSUM3
4.BLOCK: 04; FB; [128byte a BIN állományból]; CSUM4
...
X. BLOCK: $hX; FF-$hX; [128byte a BIN állományból]; CSUMx
Minden BLOCK-hoz én küldöm az első két byte-ot, és én számolom ki az így felépült csomagból a CSUMx-et a végére.
A bootloader a kapott byte-okat ugyan úgy összeadja (az általam küldött első két byte + a 128 adat byte a BIN állományból) és a végén elküldöm neki az általam kiszámított értéket (131.byte), amit összehasonlít az őáltala számítottal. Ha a kommunikáció megfelelő volt, akkor a két -ugyanazon elven összeadogatott- értéknek ugyanazt az eredményt kell adnia.
Ebből az közetkezik, hogy ugyan a kommunikáció során 131byte megy ki a bootloader felé, de ebből csak 128byte a hasznos adat, ami a BIN állományból kerül kiolvasásra. Az eslő kettő és az utolsó byte a programozó szoftver által van kezelve.
...és lőn fény.
Elnézést azoktól, akik számára ez egyértelmű volt
Megvilágosodtam! (asszem'):
https://pythonhosted.org/xmodem/xmodem. ... yte-blocks
A linken megtekinthető infó alapján XModem-protokoll, amit a BASCOM bootloader is használ (ahogy azt a HELP-ben jelölik is ).
Magából a BIN állományból csak 128byte-os csomagokat szedegetünk ki.
Minden csomag elé oda bisszesztjük az első két byte-ot (ezt a mi programunk kezeli és küldi ki a blokkok elején):
1.BLOCK: 01; FE; [128byte a BIN állományból]; CSUM1
2.BLOCK: 02; FD; [128byte a BIN állományból]; CSUM2
3.BLOCK: 03; FC; [128byte a BIN állományból]; CSUM3
4.BLOCK: 04; FB; [128byte a BIN állományból]; CSUM4
...
X. BLOCK: $hX; FF-$hX; [128byte a BIN állományból]; CSUMx
Minden BLOCK-hoz én küldöm az első két byte-ot, és én számolom ki az így felépült csomagból a CSUMx-et a végére.
A bootloader a kapott byte-okat ugyan úgy összeadja (az általam küldött első két byte + a 128 adat byte a BIN állományból) és a végén elküldöm neki az általam kiszámított értéket (131.byte), amit összehasonlít az őáltala számítottal. Ha a kommunikáció megfelelő volt, akkor a két -ugyanazon elven összeadogatott- értéknek ugyanazt az eredményt kell adnia.
Ebből az közetkezik, hogy ugyan a kommunikáció során 131byte megy ki a bootloader felé, de ebből csak 128byte a hasznos adat, ami a BIN állományból kerül kiolvasásra. Az eslő kettő és az utolsó byte a programozó szoftver által van kezelve.
...és lőn fény.
Elnézést azoktól, akik számára ez egyértelmű volt