ESP8266 bootloader
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?
- Tovább (ESP8266 bootloader)
- 1398 megtekintés