C/C++

ESP8266 bootloader

Fórumok

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 off
setlocal 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>&1
if 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 -Os
xtensa-lx106-elf-gcc -c %SRC% -o bootloader.o -Os -nostdlib -fno-builtin -mlongcalls
xtensa-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?

Atomikus műveletvégzést ki lehet kényszeríteni?

Fórumok

PIC32M, 32 bites MIPS architektúra. Van neki egy WDTCON 32 bites regisztere, little endian, s a watchdog timer visszatörlése úgy néz ki, hogy a regiszter felső felébe 0x5743-at kell írni. Ez valahogy így nézne ki:

*((volatile uint16_t *) &WDTCON + 1) = 0x5743;

Viszont nem működött, watchdog reset lett belőle. Korábbi fordítóval ez a megoldás működőképes volt. Nem néztem meg, mivé fordult, de szinte biztos, hogy byte-osával, egyenként, két gépi ciklusban írta ki az adatot, de ez nem jó, mivel hardware-t vezérel, vélhetően röptében dekódolja egy 16 bemenetű ÉS kapu - amelynek egyes bemenetei negáltak - a megfelelő szám meglétét.

Aztán az MCU-hoz tartozó header-ben láttam, hogy bitmezőként is deklarálva van ez. Így már működött:

WDTCONbits.WDTCLRKEY = 0x5743;

Az első esetben a fordítót rá lehet kényszeríteni, hogy az értékadás művelet egyetlen gépi ciklusban, atomikusan történjen?
 

Nano QR kód generáló

Fórumok
Mivel több HUP-os fórumtárs is mikrokontrollerezik, ezért gondoltam megosztom, hátha másnak is hasznos lesz. Összedobtam egy minimalista QR kód generálót ANSI C-ben, kifejezetten URL-ek kódolására: - Szabad és Nyílt Forráskódú, MIT licenszű - irtó kicsi (kb. 150 SLoC), egyetlen egy függvény csak - nincs semmi függősége (még libc se, de még csak libc fejlécek sem kellenek neki) - nem foglal memóriát egyáltalán - csak pár bájtot eszik a veremből - pofon egyszerű használni, nem kell konfigurálni - egy 53 x 53 pixeles szürkeárnyalatos képet köp ki (csak 0 (előtér) ill. 255 (háttér) színekkel) - a bemenete egy legfeljebb 128 bájtos URL (vagy hát bármilyen UTF-8 sztring igazából) Példa használatra (csak példa, semmilyen domain sem query paraméter nincs a függvénykönyvtárban, bármi lehet):
#define NANOQR_IMPLEMENTATION
#include "nanoqr.h"

uint8_t image[53][53];
nanoqr(image, "https://gitlab.com/bztsrc/nanoqr?errcode=1234&errpos=1234&when=1234");
Ennyi. Aztán a megadott URL-re lehet rakni egy JavaScriptet, ami megcsócsálja és ember számára érthető hibaüzenetekké formálja az URL paraméterében megadott kódokat. Technikai részletek: QR version 9-et generál (mert a 128 bájtos tárhely elfogadhatónak tűnt, a 53 x 53 pixeles méret meg elég kicsi ahhoz, hogy elférjen LCD-kre, de akár LED-es kijezlőkre is). A hibajavító kód QUARTILE (eggyel rosszabb csak, mint a legjobb opció), a maszkszint fixen 1-es, az adathalmaza pedig bájt (mert az alfanumerikusból hiányzik a ?, &, =, szóval nemigazán kódolható vele URL). Ezeket bedrótoztam az egyszerűség kedvéért, hogy ne kelljen semmit állítgatni. Ha valakinek ez nem felelne meg, akkor nekik ott a Nayuki QR kódgeneráló, de az többet eszik és bonyibb használni is. SZERK: lett nagytesója, MiniQR, ez kb ugyanaz használni, de az összes QR verziót tudja (V1-től V40-ig), dinamikusan méretezi a kimeneti képet (21-től 177 pixelig), a bemenete meg egészen elképesztő 1663 bájtos is lehet. Ja, és ez bűntetőpontokat számol a maszkokra, és asszerint választja ki. Mindezért cserébe kb. kétszer akkora a kód, 300 SLoC, és több memóriát is igényel, valamint már nemcsak egyetlen függvényből áll (a publikus API-ja továbbra is egyetlen fgv.).
#define MINIQR_IMPLEMENTATION
#include "miniqr.h"

uint8_t image[177 * 177];
int wh = miniqr(image, "https://gitlab.com/bztsrc/nanoqr?errcode=1234&errpos=1234&when=1234");
A visszaadott kép "wh" x "wh" pixeles, lehet hogy csak 53 x 53.

GCC/binutils bug reporting

Fórumok

Sziasztok!

Van-e valakinek tapasztalata a targybeli folyamattal? Ugy nez ki sikerult kifognom az elso ilyen esetet. A hiba a linkerben (ld) van, amit ugye nem a GCC, hanem binutils, de nyilvan `gcc`-bol kiihivva ugyanugy elojon a dolog. Kicsit niche a dolog, nagyon szerencsetlen osszeallitasban jon elo a bug (csak msp430-elf targeten, ott is sokmindennek kell egyuttallnia). A "mar nem lehet weben regisztralni, irj emailt ide meg ide, 24 oran belul kapsz accountot a bugzillahoz" reszen mar tulvagyok. Konkretan 48 oraja semmi sem jott, de tegyuk fel hogy jon majd (lasd meg: szep nap). Hogy erdemes rakeszulni egy ilyenre? Minimum reproducible example megvan, szepen mutatja a dolgot (nehany soros shell szkript ami leforditja + linkeli kulonbozo parameterekkel plusz 2x10 soros C kod ami elohozza a hibat). Mi kellhet meg?

koszi, A.

ESP8266 alternatív OTA

Fórumok

A partíció 1MB FW 3MB SPIFFS. A Firmware ~900kB
Ehhez szeretnék valami WiFi-s frissítést.
A normál OTA esélytelen. Arra gondoltam ha a rendes FW által AsyncWebServer segítségével fogadott fájl pl "update.bin" akkor lezárja a fájlrendszert és kiírja 0x100000-tól a bin-t a flesbe. Fájlokat buktam, leszarom, az új FW formatálja. Ez egy AsyncElegantOTA firmware lenne. Az eredeti FW setup első sora megnézi az eepromot amiből kiderül hogy frissíteni kell-e, ha igen akkor 0x100000 címen levő kódot futtatja. Lehet egy .ino-t fordítani úgy hogy a 0x100000 címen kezdődjön és setupból indítható legyen?

Segítség kérés SDL fordítás Androidra

Fórumok
Csinált már valaki ~t? Van valamelyik fórumtársnak ilyenben tapasztalata? Próbálom kihámozni a lényeget, de finoman szólva is egy overcomplicated agyfasz ez az egész Android buildelés. Ami nekem kéne, az minimális dependency-vel annyi, hogy a letöltött SDL.so-ból, a kigenerált main.so-ból és még néhány asset fájlból összerakjon nekem egy .apk fájlt. Tehát lehetőleg C és Java fordítás nélkül, csak a csomagolást oldja meg. Ha itt-ott generálni kell egy xml-t app specifikus sztringekkel a bemenetben hozzá, az nem probléma, azt megoldom, de elsőre az is elég, ha minden egyedi sztringje "helloworld". FONTOS: semmilyen más függőség nincs, csakis az SDL alapfüggvénykönyvtár. Nézegettem a doksikat és forrásokat, de egy irtó katyvasz az egész, pláne ahhoz képest, hogy az .apk lényegében csak egy zip archívum. Az SDL hivatalos doksi itt van, a hozzá tartozó repó meg itt. Ezzel az a bajom, hogy egy dependency hell fos az egész, kell neki ndk, cmake, make, ant, gradle, prefab, python meg még isten tudja mi. Ez instant bukó, túl sok verzió, túl sok függőség, túl sok hibalehetőség. (És akkor arról még nem is beszéltem, hogy a forrásba egy csomó helyen bele van égetve ez-az, túl sok helyen kell belőle a helloworld-öt kiirtani, még xml stroke path-ok is bele vannak vasalva, meg nem használ main()-t, szóval kiiunduló sablonnak totál szar.) A legjobb megoldás eddig, amit találtam, az ez. Ez SDL2-höz van, de az nem baj, sőt, ahogy nézem kevesebb szívás, úgyhogy jobb is. Ennek nem kell se gradle, se cmake, se python, se stb. és stroke pathok sincsenek beleégetve. Csak ndk kell neki, mert forrásból fordítja az SDL-t. Namost én nem akarom forrásból fordítani, nekem teljesen jó a hivatalos bináris, akár az .aar verzió, akár az, hogy kézzel berakom az ARM-re fordított libSDL.so-t a jni mappába. Nem akarom ráhagyni a program fordítását se, azt is megoldom inkább magamtól gradle meg minden más fos nélkül. Simán fordítok ezek nélkül egy main.so-t, ami shared library main() függvénnyel ARM architectúrán. Arra is oda tudok figyelni, hogy adott verziójú SDL-lel fordítsam, és simán be tudom másolni az eredményt a jni mappába python meg cmake meg a többi szotty nélkül. Tudna segíteni valaki ebben, csinált már valaki ilyent? Már az is irtó nagy segítség lenne, ha valaki le tudná fordítani az SDL_helloworld vagy sdl2_on_android repókat és belinkelné ide a letölthető eredmény .apk-t, hogy aztán szétcincálhassam és összevethessem a forrásával. (ps: amihez kéne, hogy a projektemben generálok egy main.so-t, és ebből meg pár előre legyártott fájlból csináljon nekem egy működő .apk-t. Az egyetlen függőség a libc-n túl az SDL2 vagy 3.)

SMGUI frissítés

Fórumok
Emlékeztetőül, MIT licenszű, Szabad és Nyílt forráskódú, ANSI C-ben írt, single header lib UI toolkit többféle backenddel és konfigurálható modulokkal: SMGUI Kicsit frissítettem monstanában, akit érdekel: - atrex66 kolléga unszolására (és ezer hála a tesztelésért) lett Linux framebuffer backend támogatás 32 bit, 16 bit és 15 bites pixelekkel - a fájlválasztó nem szűri a könyvtárakat, csak a fájlokat, ha van megadva kiterjesztésszűrés - a könyvtárlétrehozást újraírtam, most a listában jelenik meg neki a névbeviteli mező, nem a keresés mezőben - táblázat akkor is megjelenik, ha az adata NULL pointer (igaz, üresen, de legalább megjelenik) - táblázat fejléce külön igazítható (UI_LEFT, UI_CENTER és UI_RIGHT), nemcsak az adatoszlop - táblázat fejlécének megadható egyetlen UNICODE karakter (pl. U+02706, telefon ikon), nemcsak lefordított szöveg - gomboknál külön állítható a felső és alsó árnyék színe (és külön ki-be kapcsolható) - Windows-os fordításnál rendesen kezeli az "%ll"-t - az SDL backend átírva, hogy működjön továbbra is az SDL2 és ugyanakkor a legfrissebb SDL3 alatt is (volt pár breaking módosítása Samnek). - meg még egy csomó pici javítás, pár pixel itt meg ott, ilyenek - a dokumentáció is frissítve lett.

Egy par linkeleses tema/kerdes

Fórumok

Ket apro, valojaban nem eletbevago de (talan) erdekes kerdes merult fel, GCC toolchainnel valo jatszadozas soran.

Az egyik a reszleges linkelessel kapcsolatos. Tegyuk fel hogy van egy forras, van benne nehany fuggveny, pl igy:

int funct1(int x)
{
 return(2*x);
}
int funct2(int y)
{
 return(y+10);
}
int entry(int z)
{
 int c;
 c=0;
 while ( 1 )
  {  sleep(1);
     printf("%d\n",funct2(c));
     c++;
  }
}

Ezt leforditjuk `gcc -ffunction-sections -fdata-sections` modon. A *.o-ban igy lesz a fentieknek megfeleloen harom .text jellegu section (.text.funct1, .text.funct2, .text.entry). Ebbol `ld -r|--relocatable` modon csinalnek egy masok objectet, ugy hogy a 

SECTIONS
{
 .text :
  {     *(.text.* .text)
  }
}

linker scriptnek megfeleloen osszevonom a .text.* section-okat egyetlenegy darab .text section-ba. Ez szuper, el is keszul a *.o/*.elf, minden oke. Viszont a fenti peldaban a funct1()-et nem hivja meg senki, igy szeretnek egy olyan *.o-t (is) amben ez nincs benne. Ha a sima teljes erteku linkelesnek megszokott modon megadom a --gc-sections opciot, akkor az hianyol egy entry-t, ertheto okokbol. Megadon --entry-nek az entry()-t. Igy lefut a reszleges linkeles, lesz is egy darab .text section, de a funct1 az meg mindig benne marad. Probalkoztam KEEP()-ekkel meg ENTRY()-kel a *.lds linker szkriptben is, de az sem segit. Barmi otlet?  (( A fenti eljaras nem csak veletlenul hasonlit arra, ahogy a linux kernel modulok, a *.ko-k keszulnek. ))

A masik kerdes meg arrol szol(na), hogyha van egy nagyobb forras, van benne egy fuggveny, amit nehanyszor meghivnak akkor az a teljes forditas + linkeles soran elfordul(hat) hogy a vegso *.elf-bol eltunik, mert az optimalizcio mindenfele inline-ositas miatt a garbage collector a vegen egyszeruen kiszedi azt a section-t. Az teljesen oke. Van-e valami __attribute__ vagy barmi hasonlo amit meg lehet adni hogy ez a fuggveny az legyen "exportalva", azaz kesobbiekben hivhato legyen? A noinline az talan jo is lehetne, de valojaban nem azt akarom (es ugy latom hogy az nem is oldja meg ezt a problemat). Szoval felolem lehet inline ha az ugy jobb/gyrosabb/kisebb (-Ox-tol fuggoen), de maradjon meg a fuggveny a vegso ELF-ben (aztan meg emiatt a vegso binary/hex image-ben).

Thx, A.

[MEGOLDVA] Kis github segítséget kérnék

Fórumok
Szeretnék egy kis segítséget kérni egy olyan HUP-os fórumtárstól, akinek van github accountja. Én sajnos nem tudok belépni, különben megcsinálnám magam (egész pontosan identification kódot kér, de az azt tartalmazó email sehogy nem akar megérkezni már egy ideje). Szóval arról lenne szó, hogy 1. klónozni kéne a mapeditor repót 2. bemásolni az src könyvtárat ebből a repóból (a repó README-jét hagyd ki) 3. beküldeni az eredményt PR-ként nekik. Ez egy új fájlformátum exportot ad a Tiled-hez, ami a lehető legfaékebb egyszerűségű: egy fix méretű, 16 bájtos fejléc és tömörítetlenül a tile id-k 2 bájtonként, oszt ennyi. Rengeteg alkalmazásnak nem is kell ennél több, nincs szükségük a variálható property-kre és egyébként is iszonyat macerás TMX-t betölteni (a Tiled alapértelmezett formátuma XML alapú agymenés). Ellenben ez a bináris térkép formátum teljesen dependency mentes, gyakorlatilag parszeolni sem kell, csak belapátolni a memóriába és kész is. (ps: a formátumot implementáltam extension-ként is, de abban nagyon nem bízok, valahogy nem akarnak stimmelni a tile id-k a C++-ban lekért tile id-kkal, ezért lenne jobb, ha lefordított pluginként is elérhető lenne.)

C++ vector

Fórumok

Arduino-ban mi a különbség?

 

1) std::vector<String> cmd(1);

2) String data[500];

 

Első esetben dinamikusan nő a tömb cmd.push_back(""); utasítással a program elején, később nem változik.

A második esetben lehet az első változó a data[328] lesz, ehhez jobb a vector data.resize(329); , vagy inkább a String data[500]; a helyes megoldás?

Ezt a vektor izét nem ismerem, nem találtam hozzá számomra érthető leírást.

Ne ChatGPT-t, nem jött be.

Köszönöm a rám fordított időt a válaszolónak.