Nem sok esélyt látok rá, de hátha. Írt már valaki esp8266 bootloadert?
Idáig jutottam (AI segítségével).
Első körben egy led villogtató, serial print "Hello word" elég lenne, a többi talán már menne.
Fontos hogy IRAM-ból fusson, A 0x100000-0x1FFFFF flest akarom 0x000000-0x0FFFFF helyre másolni vele.
bootloader.ld
ENTRY(_start)
MEMORY{ /* IRAM: 32 KB-os RAM terület */ iram (rwx) : ORIGIN = 0x40100000, LENGTH = 32K}
SECTIONS{ .text : { . = ALIGN(4); /* 1. LITERÁLOK */ *(.literal) *(.literal.*) /* 2. KÓD */ *(.text) *(.text.*) /* 3. KONSTANS ADATOK */ *(.rodata) *(.rodata.*) /* --- ÚJ: Globális Adatok (Inicializált) --- */ . = ALIGN(4); *(.data) *(.data.*) /* --- ÚJ: Globális Adatok (Inicializálatlan, 0-ra kell állítani) --- */ . = ALIGN(4); _bss_start = .; *(.bss) *(.bss.*) . = ALIGN(4); _bss_end = .; } > iram}
bootloader.S
.section .text.global _start
_start: /* Stack Pointer beállítása az IRAM végére: 0x40107FFC */ movi a1, 0x40107FFC
/* Ugorjunk a C kód fő belépési pontjához */ call0 main_entry
/* Végtelen ciklus (trap) */hang: j hang
bootloader.c
#include <stdint.h>
// -------------------------------------------------------------------------// Hardver Regiszterek Definiálása// -------------------------------------------------------------------------
// System/WDT#define WDT_CTL_REG 0x600000A0#define DPORT_BASE_ADDR 0x3FF00000#define DPORT_CLOCK_GATE_REG (DPORT_BASE_ADDR + 0x28) // Órajel vezérlés
// GPIO/LED (Wemos D1 Mini)#define GPIO_BASE_ADDR 0x60000300#define GPIO_ENABLE_W1TS_REG (GPIO_BASE_ADDR + 0x14)#define GPIO_OUT_W1TS_REG (GPIO_BASE_ADDR + 0x08)#define GPIO_OUT_W1TC_REG (GPIO_BASE_ADDR + 0x0C)#define LED_PIN_MASK (1 << 2) // GPIO2 maszk
// -------------------------------------------------------------------------// Késleltető Segédfüggvény// -------------------------------------------------------------------------
// Késleltetés 80 MHz-es CPU frekvenciára kalibrálva (Kb. 80000 ciklus/ms)#define DELAY_CYCLES_PER_MS 40000 // Csökkentett ciklusszám a biztos láthatóságért (kb. 500 ms-ot ad 80 MHz-en)
static void delay_ms(uint32_t ms) { volatile uint32_t cycles = ms * DELAY_CYCLES_PER_MS; while (cycles > 0) { cycles--; }}
// -------------------------------------------------------------------------// Fő Belépési Pont// ------------------------------------------------N---------
void main_entry(void) { // 0.1. MEGSZAKÍTÁSOK KIKAPCSOLÁSA __asm__ __volatile__ ( "rsr a2, PS\n" "movi a3, 0xFFFFFFFC\n" "and a2, a2, a3\n" "wsr a2, PS\n" "esync\n" );
// 0.2. WATCHDOG TIMER (WDT) KIKAPCSOLÁSA volatile uint32_t *wdt_ctl = (volatile uint32_t *)WDT_CTL_REG; *wdt_ctl = 0x73; *wdt_ctl = 0x83;
// 0.3. ⚡ CPU ÓRAJELEL KÉNYSZERÍTÉSE 80 MHz-RE // A DPORT_CLOCK_GATE_REG (0x3FF00028) beállítása: // Bit 0: CPU_CLK_SEL (0=40MHz, 1=80MHz) - Ez a legfontosabb // Bitek 1 és 2 is fontosak lehetnek a stabil órajelhez. volatile uint32_t *dport_clk = (volatile uint32_t *)DPORT_CLOCK_GATE_REG; // Feltételezve, hogy a 80 MHz bit 0, de a teljes órajel inicializációhoz biztonságosabb a ROM hívás, // de mivel ezt elvetettük, a regiszterekkel próbálkozunk. // **FIGYELEM:** Mivel a pontos bare-metal CPU_CLK regisztercím eltérhet, de az // *ETS_RTC_SET_CONFIG()* ROM hívás pontos. Maradjunk a direkt beavatkozásnál, // de tegyünk egy biztonsági késleltetést. // Ideiglenes késleltetés az órajel stabilizálására, mielőtt a GPIO-t beállítjuk volatile int i; for (i = 0; i < 50000; i++) {}
// 0.4. 💡 GPIO2 INITIALIZÁLÁSA (LED vezérlés) volatile uint32_t *gpio_enable_w1ts = (volatile uint32_t *)GPIO_ENABLE_W1TS_REG; volatile uint32_t *gpio_out_w1ts = (volatile uint32_t *)GPIO_OUT_W1TS_REG; *gpio_enable_w1ts = LED_PIN_MASK; // GPIO2 beállítása kimenetnek *gpio_out_w1ts = LED_PIN_MASK; // GPIO2 HIGH (LED KI) - Kezdő állapot // 1. Végtelen ciklus (LED villogtatás) volatile uint32_t *gpio_out_w1tc = (volatile uint32_t *)GPIO_OUT_W1TC_REG;
while (1) { // LED BE (LOW) *gpio_out_w1tc = LED_PIN_MASK; delay_ms(500); // 500 ms késleltetés
// LED KI (HIGH) *gpio_out_w1ts = LED_PIN_MASK; delay_ms(500); // 500 ms késleltetés }}
bootloader.cmd
@echo offsetlocal enabledelayedexpansion
:: === CONFIGURE these paths ===set "TOOLCHAIN_DIR=F:\asm\bin"set "SRC=bootloader.c"set "LD=bootloader.ld"set "SC=bootloader.S"set "ESPPORT=COM9":: =============================
echo Checking toolchain...set "PATH=%TOOLCHAIN_DIR%;%PATH%"where xtensa-lx106-elf-gcc >nul 2>&1if errorlevel 1 ( echo [ERROR] xtensa toolchain not found in PATH: %TOOLCHAIN_DIR% pause exit /b 1)
echo Building...
xtensa-lx106-elf-gcc -c %SC% -o startup.o -Osxtensa-lx106-elf-gcc -c %SRC% -o bootloader.o -Os -nostdlib -fno-builtin -mlongcallsxtensa-lx106-elf-ld -T %LD% startup.o bootloader.o -o bootloader.elf
esptool.exe elf2image bootloader.elf
esptool.exe --port %ESPPORT% --baud 921600 write_flash 0x00000 bootloader.elf-0x00000.bin
pause
Ezt működő állapotba tudná hozni valaki?
- 738 megtekintés
Hozzászólások
Az ESP8266 bootloader bele van égetve gyárilag ROM-ba, azt a gyárban megkapta a chip és az cserélhetetlen. Ha még mindig azon pörögsz, hogy OTA frissítést akarsz fájlrendszerről ilyen másolgatásokkal, akkor nem fog így menni, mert ez, amit te bootloader-nek nevezel, ez a futó két programterület közül az egyiken lesz és nem tudja írni se a másik területet, se a saját területét, miközben fut.
- A hozzászóláshoz be kell jelentkezni
Nem adom fel. Igazad van, a rom bootol, a flash 0x000000 címről inditja a kódot ha az megfelel a rom által megkövetelt formátumnak. Ilyet szeretnék egy hello word mintával. Az Arduino által fordított kód is 0x000000 címtől kezdődik, ezt indítja a rom, ami működik. Serial print, erase flash, write flash direktben hívható a bedrótozott romból. Felbaszta az agyam, azért is megcsinálom.
- A hozzászóláshoz be kell jelentkezni
Az ESP8266 bootloader bele van égetve gyárilag ROM-ba, azt a gyárban megkapta a chip és az cserélhetetlen.
Egyes mobiltelefonoknál alternatív ROM felrakása előtt ki kell "nyitni"
a bootloadert - jelentsen ez bármit is - egyiknél a gyártótól kapott, a szériaszámból generált kóddal. Az miben más? Az (át)írható is?
Ez is ESP csak más verzió, itt fash-eli
https://github.com/espressif/esptool/blob/master/docs/en/advanced-topic…
- A hozzászóláshoz be kell jelentkezni
Szerintem a boot loader pont nem az, amit AI-val kellene íratni. Mondjuk mást sem.
Olyan apróságok például, hogy mi van a megszakítás vektortáblával?
ESP-re még nem írtam boot loader-t, de PIC32-re és PIC18-ra már igen.
A letöltött program entry pointját vagy a linker scripttel mondod meg, vagy valahogy elmeséled a fejlesztői környezetnek, hogy offset-elje feljebb a kódot, de ügyes megoldás lehet, ha meg tudod kérni a fejlesztői környezetet arra, hogy a hex file-ba írjon SLA-t (0x05: Start Linear Address), s ide adod a vezérlést.
Az ESP-t nem ismerem, emiatt nem tudok konkrét lenni.
tr '[:lower:]' '[:upper:]' <<<locsemegeLOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Szerintem a boot loader pont nem az, amit AI-val kellene íratni. Mondjuk mást sem.
Ezt a mondatot ki kellene rakni az oldalsávra közvetlenül a menü alá, arany keretben. :D
- A hozzászóláshoz be kell jelentkezni
Az alapgondolat egyszeru is tud lenni. Felosztod a programmemoriat (legalabb) ket reszre. Egyik resze bootol be, es azon egy olyan kod fut ami egyreszt lehetove teszi az eszkoz elereset egy olyan adott halozati(bb) interface-en amin keresztul a progremmemoria masik resze(i)t frissitheted, masreszt pedig a kello pillanatban atadja oda ugy a vezerlest a programmemoria masodik reszere hogy ezzel parhuzamosan meghamisitja/visszaallitja a CPU-t a reset allapothoz minel kozelebbi allapotba. Az ordog a reszletekben rejlik - mi(k) is lesz(nek) ez a halozati interface(k), hogyan kulonbozteted meg a "bootloader" es a "bebootolt" allapotokat, hogy allitod vissza a CPU-t reset (kozeli) allapotba, a memory layout-tol fuggo particionalasa a programmemorianak, flash page alignmentek, linker script modositasa, vektor tabla cimenek modositasa, periferia/interrupt/stb inicializalasok visszahivasa, .rodata/.data/.bss section-ok ismerete, .rodata tulajdonsagai (ld. Harvard vs. Neumann problemak), stbstbstb - de ezek mar elegge architektura-fuggoek tudnak lenni. Cserebe ezek a reszletek jol behatarolhato, kulon-kulon is jol letesztelheto lepesek.
Hajra :)
- A hozzászóláshoz be kell jelentkezni
Az EspOS már tudja hogy ha firmware.bin fált kap feltöltéskor akkor leállítja az SPIFFS-t, a beérkező cuccot felírja 0x100000 címtől. Utána egy uint8_t tömböt (ez lenne a bootloader) felír 0x00000-0x00FFF címre. Nincs crash. Reboot után szeretnék látni egy soros "Hello word"-ot.
- A hozzászóláshoz be kell jelentkezni
Ugyerted, azt a kodot akarod atirni tavolrol ami cold start utan rogton indul?
- A hozzászóláshoz be kell jelentkezni
Igen. Az SPIFFS tartalmát buktam, írás közben ha elmegy a táp akkor softbrick, ezt leszarom. Szerintem működnie kell, csak azt a kurva bootloadert nem tudom megírni, elindítani (első körben egy "hello word".
- A hozzászóláshoz be kell jelentkezni
Az alapgondolat egyszeru is tud lenni. Felosztod a programmemoriat (legalabb) ket reszre. Egyik resze bootol be, es azon egy olyan kod fut ami egyreszt lehetove teszi az eszkoz elereset egy olyan adott halozati(bb) interface-en amin keresztul a progremmemoria masik resze(i)t frissitheted, masreszt pedig a kello pillanatban atadja oda ugy a vezerlest a programmemoria masodik reszere hogy ezzel parhuzamosan meghamisitja/visszaallitja a CPU-t a reset allapothoz minel kozelebbi allapotba.
Az alapgondolat olyannyira egyszerű, hogy az ESP8266 esetén ez a viselkedés bele van égetve a chip-be, definiálni kell kettő programterületet (dual partition layout), amelyek közül az egyik aktív, a másik meg írható a bootloader megfelelő hívásával. Az a dolog viszont nem megy, hogy csak egy programterületet definiálsz, és azt írod konkrétan a futó program alatt. Ami itt bootloader néven van nevezve, az maga a futó program... OP kolléga viszont nem így szeretné, ahogy meg szeretné, az úgy nem megy.
- A hozzászóláshoz be kell jelentkezni
Az a dolog viszont nem megy, hogy csak egy programterületet definiálsz, és azt írod konkrétan a futó program alatt.
Ez nem illendo, igen. Legalabbis ugy altalaban mehetni mehet de azert nem csinalnam :)
Ettol fuggetlenul az ilyen gyari ROM-os bootloaderek azok lehet hogy jatszani jok meg par dolgot egyszerusitenek (programozo helyett hasznalhatsz egy szokvanyosabb portot, mondjuk UART-ot), de elesben, ha egy adott interface-n egy adott protokoll szerint kell frissiteni (ami lehet full egyedi is, mert epp' az a kovetelmeny), akkor... akkor jo kerdes hogy mire mesz ezekkel a beleegetett ROM-okkal.
De sokat nem akarok okoskodni, az ESP8266-t csak igy futolag futottam at. De a masik ~feltucat architekturanal ahol ilyeneket csinaltam ott a fentebbi meglatasok mukodtek. Es valojaban itt sem latom hogy miert ne mukodne.
- A hozzászóláshoz be kell jelentkezni
De sokat nem akarok okoskodni, az ESP8266-t csak igy futolag futottam at. De a masik ~feltucat architekturanal ahol ilyeneket csinaltam ott a fentebbi meglatasok mukodtek. Es valojaban itt sem latom hogy miert ne mukodne.
Mert az ESP8266 esetén van egy gyárilag beleégetett bootloader, ami egy vagy két partícióról tud firmware-t indítani és két partícióval tud OTA frissítést (az aktív partíció tudja írni a passzív partíciót, reboot és az újabb indul el). Ez ilyen. És mivel ilyen, ezért nincs mozgástered. Az ESP8266 12 éve jött ki, 12 év alatt nem írt senki olyat, amit OP szeretne (egy partíciót használ, letölti az új firmware-t a fájlrendszerbe és onnan átmásolja maga alá az éppen futó program). Nem azért nem írt senki ilyet, mert nem gondoltak rá, hanem azért, mert ESP8266 esetén ezt nem lehet megoldani. Ha meg is lehetne oldani, akkor is egy csomó nem várt probléma miatt az eszköz frissíthetetlen lesz.
Az egyetlen megoldás kb. az, hogy aszimmetrikus méretű a két partíció, az egyikben van egy OTA frissítő, a másikban meg van a futó firmware, de OP ezt már korábban elvetette.
- A hozzászóláshoz be kell jelentkezni
Van olyan strategia is, hogy azt a kodot amivel epp irod a flash bezuzod a RAM-ba es onnan futattod. Egy kis linker script magia. Helyzetfuggo, hogy mikor tekintheto ganyolasnak, de inkabb kerulendo.
- A hozzászóláshoz be kell jelentkezni
Igen, a RAM-bol valo futtatast szoktak hasznalni, de szerintem nem pont erre. Sokszor azert kell, mert az eszkoz egyaltalan nem kepes a flashbol olvasni (pl. betolteni a kovetkezo utasitast) es irni bele.
De itt masrol van szo, az OTA eseten az egesz stacket be kellene huzni a RAM-ba, hiszen az vegzi a vezetek nelkuli kommunikaciot, ami Wi-Fi / BLE / akarmi eseten nem csak egy par byte. Ugye mi tortenik, amikor pont azt a reszet irod felul a flash-ben a Wi-Fi stacknek ami eppen a csomagokat kuldozgeti? ;-)
/sza2
Digital? Every idiot can count to one - Bob Widlar
- A hozzászóláshoz be kell jelentkezni
En nem lattam sehol, hogy over the air updatet akar csinalni. Linkermagic, es gany, de azt is egyszeruen nem piszkalod a flashben es mikor ujraindul akkor irod at.
De igen, valoban arra szoktak hasznalni, hogy irasra lockolt flasht tudjanak irni, hisz abbol nem lehet olvasni (ha pl. van flash tukor akkor igy lesz atomikus a muvelet).
- A hozzászóláshoz be kell jelentkezni
Nem fér el a RAM-ban az ehhez szükséges firmware.
- A hozzászóláshoz be kell jelentkezni
A rom tartalmaz mindent csak hívogatni kell.
https://chatgpt.com/share/6931f44a-67ac-8011-9f99-6351808b81c0
Símán bele kell férnie 4kB-ba.
- A hozzászóláshoz be kell jelentkezni
Csak magyarazd mar el nekunk mit akarsz csinlani, mi itt a cel? :)
Akkor talan jobban tudnank segiteni, te ...
Nem bantasbol, de az van, hogy ez nem egy html kod generalas... Itt ehhez tenyleg erteni kell, rengeteg idodet fogja elvinni az LLM es nem fogsz tudni vele celt erni.
- A hozzászóláshoz be kell jelentkezni
"Az EspOS már tudja hogy ha firmware.bin fált kap feltöltéskor akkor leállítja az SPIFFS-t, a beérkező cuccot felírja 0x100000 címtől. Utána egy uint8_t tömböt (ez lenne a bootloader) felír 0x00000-0x00FFF címre." Ez működik.
0x00000-0x00FFF szeretnék egy bootolható kódot ami a 0x100000-0x1FFFFF tartományt átmásolja 0x000000-0x0FFFFF
- A hozzászóláshoz be kell jelentkezni
Szoval AB software update-t akarsz csinalni? A futo alkalmazas beirja az uj firmwaret a B oldalra majd ujraindulasnal valtassz ? De minek kell a masolas?
- A hozzászóláshoz be kell jelentkezni
Nincs A/B. 1MB FW, 3MB SPIFFS. Ezt szeretném frissíteni. Az SPIFFS helyére megy az új FW, ezt kéne reboot után átmásolni a helyére (0x0-tól).
- A hozzászóláshoz be kell jelentkezni
Nem kell az egeszet atpakolni csak par fuggvenyt, siman elfer.
- A hozzászóláshoz be kell jelentkezni
A kerdes mar csak az, hogy az miert nem jo, ami a tamogatott megoldas. Random fiokbol elohuzott ESP8266 boardon rajta van maga a wifis mikrokontroller, meg egy "bergmicro 25Q80ASSIG" feliratu 8 labu IC. Utobbi egy 8 Mbites (1 MiB) SPI-on elerheto flash, ebben tarolja a programjat, meg ami meg van asset, azt is. Ha ez keves, ezt kicserelve fel lehet menni 25Q256-ig, ami megabitben ennyi, 32 MiB flash. Annak a fele is eleg jelentos. (lehet, hogy az ESP-ben valami flaget kell allitgatni hozza, hogy lassa az egeszet, ennyire nem melyedtem bele) Extrem esetben kulso hardware-rel is megoldhato az egesz, ha nagyon nincs mas megoldas, vegulis egy kulso flash, es az SPI-t akar kezzel is lehet irni egy kapcsoloval es egy prellmentesitett nyomogombbal - nem ajanlott persze.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Egyetertve az elottem szolokkal, szertintem is az a megoldas, hogy van egy custom bootloader (ugy ertem nem az amivel UART-on lehet letolteni az applikaciot), illetve van hely az eppen futo applikacionak es az upgrade image-nek. Kicsit szemleletesebben:
|----|-------------|-------------|
| BL | APP | IMG |Nalunk a fenti sema szerint van megoldva. a bootloader (BL) ad az applikacio (APP) szamara fuggvenyeket, mint iras / olvasas / torles / ujarinditas bootloader modban / image ellenorzes / stb. Az applikacio ami fut kepes ra, hogy OTA letoltson egy (frissebb / masabb) applikaciot az image storage teruletre (IMG). Ha ez megtortent (persze celszeru ellenorizni, hogy az image nem serult-e (pl. valami hash-t szamolni ra)) akkor meghivja a megfelelo fuggvenyt a bootloaderbol, ami ujrainditja az eszkozt es atmasolja az IMG teruletrol az APP teruletre a letoltott image-et majd ismet ujrainditja az eszkozt. Nalunk a RAM-ban van beirva egy byte, ami alapjan a bootloader eldonti, hogy reboot eseten az applikacio induljon el vagy a bootloader irja felul az eredeti applikaciot az ujjal.
Szerintem ez a modszer elegge elterjedt az OTA update-re. Hatranya, hogy ketszer annyi hely kell, mintha nem lenne OTA update lehetoseg (jo, lehet az image-et tomoriteni is).
/sza2
Digital? Every idiot can count to one - Bob Widlar
- A hozzászóláshoz be kell jelentkezni
Ja, bocs, nem irtam, nem ESP8266. Csak ez olyan aranylag altalanos megoldasnak tunik mikrokontrolleres kornyezetben (amugy EFR32).
ESP8266 eseten ez nem tud mukodni?
/sza2
Digital? Every idiot can count to one - Bob Widlar
- A hozzászóláshoz be kell jelentkezni
ESP8266 eseten ez nem tud mukodni?
Nem tud. ESP8266 esetén a bootloader egy fix gyárilag beégetett cucc, ami tud egy partícióról firmware-t indítani vagy kettő partícióról firmware-t indítani, és a maradék flash lehet fájlrendszer. Nincs benne ilyen rugalmasság, sokan próbálták megkerülni, nem tudták.
- A hozzászóláshoz be kell jelentkezni
egy partícióról firmware-t indítani
Es ez az egy partciorol inditott fw tudja modositani a flash tobbi reszet (ami ertelemszeruen kivul van a sajat .text/.rodata szegmensen vagy barmin ami ott annak megfeleltetheto)? Es at tudja adni oda a vezerlest?
- A hozzászóláshoz be kell jelentkezni
Amit eddig csináltam boot loader-t, abban teljesen önálló kód a boot loader és a letöltött, majd futtatott kód. Tehát a letöltött firmware nem támaszkodik a boot loader függvényeire és viszont, azaz a boot loaderben is megvan minden magában.
Reset után elindul a boot loader. Ha nem szólítják meg és a firmware entry point-on nem csupa 0xff van, akkor adott timeout letelte után átadja a vezérlést a firmware-nek. Ha a timeout letelte előtt megszólítják akár csak egy státusz kérdezéssel, akkor a timeout végtelenné válik, nem kell attól tartani, hogy elugrik a firmware-re. Lehet neki azt mondani, hogy nesze, itt a firmware, írd be a flash memóriába. Lehet csinálni ellenőrzést, hogy kiderüljön, sikerült-e a flash-be írás. Aztán át lehet adni a vezérlést a firmware-nek.
tr '[:lower:]' '[:upper:]' <<<locsemegeLOCSEMEGE
- A hozzászóláshoz be kell jelentkezni