C/C++

STM32 arm debuggolás

Fórumok

Bare metal szintről próbálok beletanulni az ST arm alapú processzorainak debuggolásának. A fejlesztő rendszer egy Debian 12 gépen fut.
Az első a tool chain és aztán a jó öreg "blinky" és miután ez működik jöhet a debugger.. Miután fe
Több bare metal ismertetőt átolvastam mindegyik arra fut ki, hogy addjam ki a parancsot:

$ arm-none-eabi-gdb main.elf

Úgy tűnik ez elavult, a tool chain megvan, azonban a gdb ügyében a Debian elküld, hogy telepítsem fel az arm architecturát. Csináltam már ilyesmit, de konkrétan a debuggolás viszonylatában nem :(
Nem találok hozzá leírást.

Ha feltelpítem az arm architecturát hogy indíthatok egy debug sessiont?

STM32F051 CMSIS bare metal header files

Fórumok

Bare metal programming -hoz keresem a megfelelő CMSIS fájlokat, arm-none-eabi tool chain, de eltévedtem az erdőben.

STM32F051 -es MCU-hoz keresem a megfelelő CMSIS fájlokat. Az egyik git repoban találtam olyat, hogy stm32f031x6.h (ezzel sikerült is egy kínai gyártmányú kis panelt a blink-ig felébreszteni).
A google a developper.arm.com -ot dobja fel, de az mintha a keil-hez fűződne ill. valami olyan ide-hez ami kezeli a (számomra szokatlan) .pack fájlt.
Megint a google feldob egy kimondottan az STMicroelectronics "cmsis_core" repót a git-en. Viszont itt nyoma nincs az ilyen nevesített fájloknak amit idéztem, olyat látok benne mint az stm32f0xx.h -t (amit az előzőleg idézett blinky repo is használ).

Két, jónak mondható bare metal programming guide-t is találtam, az egyik a git "cpq" nevével illetve a másik "független" a Vivonomicon sorozata.
Először a cpq verzióval indultam el (persze ott sincs pont az F051 mcu) de még nem sikerült működésre bírni vele a kártyámat.
Találtam egy igen régi csomagot is egy bizonyos "Frank Duignan" blogja - több stm gyártmányú arm-al is foglalkozik, viszont igen régi, és persze nincs ott sem szó az F051-ről.

Hogy lehet összerakni, egy használható fejlesztői CMSIS fájl készletet az STM32F051 -hez?

local/label szimbolumok es/vagy szimbolum-mintak kiszedese

Fórumok

Sziaztok!

Valamiert bizonyos architekturakon (pl msp430) szeret a GCC ilyen .L* lokalis szimbolumokat beletenni a text szegmensbe. Pelda: 

$ nm main.elf | sort 
[...]
0000cb34 t transmit_get_iface_by_name
0000cb3e t .L8
0000cb58 t .L6
0000cb5e T testled_init
[...]

amik szepen megjelennek az objdump + disassembly kimenetben is:

0000cb34 <transmit_get_iface_by_name>:
    cb34:       2a 15           pushm   #3,     r10     ;16-bit words
    cb36:       08 4c           mov     r12,    r8      ;
    cb38:       39 40 5c 20     mov     #8284,  r9      ;#0x205c
    cb3c:       4a 43           clr.b   r10             ;

0000cb3e <.L8>:
    cb3e:       0d 48           mov     r8,     r13     ;
    cb40:       2c 49           mov     @r9,    r12     ;
    cb42:       b0 12 72 f0     call    #-3982          ;#0xf072
    cb46:       0c 93           cmp     #0,     r12     ;r3 As==00
    cb48:       07 24           jz      $+16            ;abs 0xcb58
    cb4a:       1a 53           inc     r10             ;
    cb4c:       39 50 36 00     add     #54,    r9      ;#0x0036
    cb50:       3a 90 06 00     cmp     #6,     r10     ;
    cb54:       f4 23           jnz     $-22            ;abs 0xcb3e
    cb56:       3a 43           mov     #-1,    r10     ;r3 As==11
 
0000cb58 <.L6>:
    cb58:       0c 4a           mov     r10,    r12     ;
    cb5a:       28 17           popm    #3,     r10     ;16-bit words
    cb5c:       30 41           ret
 
0000cb5e <testled_init>:
    cb5e:       d2 d3 04 02     bis.b   #1,     &0x0204 ;r3 As==01
    cb62:       30 41           ret

Ha meg itten ezeket fel is oldana az ugyan legalabb valamit segithet az ertelmezesben (lasd: 0xcb54-es cimen  az a `jnz $-22` ehelyett mondjuk `jnz .L8` is lehetne), de mivel meg az sem, ezert ez ugy erosen ront a kimenetek (nm, objdump) olvashatosagan mar egy kozepes projektnel is... :( Peldaul itten most ennel a projektnel:

$ nm main.elf | grep " T " | wc -l
103
$ nm main.elf | grep ".L" | wc -l
645

azaz minden valodi text szimbolumra jut valamivel tobb mint 6 ilyen label-szeruseg... aztan talaljunk meg valamit itten a szenakazalban...  Szoval az X problema az hogy hogyan lehetne azt elerni hogy ezek mar bele se keruljenek a *.o/*.elf-be, az Y problema pedig hogy hamar belekerultek, hogyan lehet kiszedni es/vagy megszabadulni? Az objcopy peldaul tud section pattern-ekre szurni (lasd: `objcopy -j '*' -j '!.persist*' -j ...`), de szimbolum patternre lehet? Tulajdonkeppen semmi nem erdekel ami .L* :] Mas embedded/cross architekturakon (avr, rv32, armv6/v7) nem lattam meg ilyet, de msp430-nal ez most kifejezetten nyugos ha valami szitu van :/

thx, A.

AddressSanitizer:DEADLYSIGNAL végtelen loop

Fórumok

Hátha érdekel valakit, elkerülendő a szívás ....

Ubuntu 22.04.1, gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0. Az Ubuntu egy i5 Macbookon fut Parallels virtualizáció.

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.17
Release-Date: 2022-01-05

Van két rövid C program(ocska), semmi extra, parancssoros fordítás: gcc -Wall -Werror -pedantic -Wextra -fsanitize=address ... -lcurl -lm, weboldal lekérés és feldolgozás. Fordítás során semmit nem ír ki, nincs hiba, nincs megjegyzés.

A két fájl a fő funkciók tekintetében ugyanaz.

Elindítod az egyik fájlt, minden OK, teszi amit tenni kell, lefut, kilép hiba nélkül.

Elindítod a másodikat, kiírja a konzolra: AddressSanitizer:DEADLYSIGNAL végtelen loop-ban, abba sem akarja hagyni.

 

Megoldás:

sudo sysctl -w vm.mmap_rnd_bits=28

Innen szedtem a megoldást, miután feladtam a kód milliomodik átnézését:

https://stackoverflow.com/questions/77672217/gcc-fsanitize-address-resu…

Egészségetekre!

#define trükk

Fórumok

Sziasztok!

Letre kene hoznom par ilyesmi szimbolumot C preprocessz soran:

#define XYZ_WHAT  XYZ_42WHAT
#define XYZ_EVER  XYZ_42EVER
#define XYZ_LOLZ  XYZ_42LOLZ

Ahol a "42" az egy elore adott konstans, amit 1x szeretnek csak definialni az elejen. Ilyesmivel probalkoztam hogy:

#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(42,WHAT)
#define XYZ_EVER __xyz_def(42,EVER)
/* ... */

Ez itten fentebb mar ugye egy fokkal - jobb de a preprocessz alatt nem tudom beleirni azt hogy:

#define NUM  42
#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(NUM,WHAT)
/* ... */

Mi is volt erre a trukk? :) Vagy legalabbis ugy remlik hogy volt erre valami, de sehol sem lelem... 

Thx, A.

gcc: __attribute__ (( ... )) minden fuggvenyre?

Fórumok

Sziasztok!

Lehet hogy tul trivialis a kerdes, de azt hogyan tudom elerni mondjuk leginkabb `gcc` forditasi parameterekkel hogy egy adott *.c => *.o forditas soran minden fuggveny egy bizonyos __attribute_--t (azon belul is most konkretan __attribute__ (( section (".whatever") ))-t) kapjon? Csak a fuggvenyek, szoval a .text(.*) vagy a (.*).text-be meno szimbolumok... Most csak a section-ok szempontjabol erdekes de lehet hogy kesobb mas kapcsan is erdekes lehet.

thx, A.

ld + _start + .text + ordering

Fórumok

Sziasztok!

Szinten RISC-V (32bites, beagyazott) tema: probalok egy sima mezei programot leforditani az xpack-riscv-none-elf toolchain segitsegevel. A forditas kapcsan alapjaraton minden jonak tunik, kiveve az hogy a linkeles utan ezt kapom:

$ nm main.elf  | sort | grep " T "
20000000 T exit
20000026 T main
20000092 T _start
20000116 T main_task
[...]

Ami ugye erosen nem jo, es ezzel egyetertesben a `readelf --file-header main.elf` is ezt mondja:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
[...]
  Entry point address:               0x20000092
[...]

Merthat a processzor (vagyis annak a bootromja) az olyan hogy 0x20000000-rol szeret(ne) indulni. Ami megfurcsabbba teszi a dolgot, hogy a main() es a main_task() ugyanabbol a forras-modulbol jon, szoval meg egy *.o-bol jovo fuggvenyek koze is teszi be a linker a _start szimbolumnak megfelelo valamit. Ezutobbi papiron lehetne a forditas + linkeles soran kiadott `-ffunction-sections` + `-Wl,--gc-sections` eredmenye is (akar), de ha ezutobbiakat kikapcsolom akkoris ugyanez a helyzet :/ Akkor is ide (egyebkent pont a 0x...92-es cimre) kerul a _start. 

Ez az xPack az a newlib-et hasznalja. Eddig csak picolibc-t hasznaltam RISC-V-s projektekre, szoval lehet hogy ez a newlib kinja ugy altalaban (es pl ARMv6-M vagy ARMv7-M eseten is "ilyen"). 

Mit lehetne itten tenni? Hogyan tudnam eroltetni az linkert (pl a megfelelo -Wl,... kapcsoloval) hogy marpedig a _start az legyen a 0x20000000 cimen es/vagy a .text legelejen? Fuggetlenul attol hogy a .text melyik subsection-jeben mi van? (( Mondjuk ettol fuggetlenul ha atirom a bootrom-ban hogy a 0x20000092-es cimrol induljon a program, akkor sem indul - meg - el, szoval vsz lesz itt mas turpissag is, de ez mas kerdes... ))

Maga a szerkesztes egyebkent olyan hogy a text is a RAM-ba (a 0x20000000-s cimre) van eroltetve, szoval a beagyazott rendszer jelleg ellenere ez most egy teljesen "von Neumann" linkeles: azaz mind a text, mind a data meg a bss (meg a heap) az a 0x20000000 cimtartomanyban van (alul a text, felul a tobbi). Es ez a "von Neumann" linkeles szepen mukodik picolibc eseten, szoval ezzel nem kene hogy gond legyen. Csak a newlib-nek nem tetszik.

thx, A.

[megoldva] beágyazott matek

Fórumok

RISC-V alá próbálom itten beizzítani a klasszikus matek könyvtárakat, egyelőre inkább kevesebb mint több sikerrel. Konkértan az van hogy sima integer architektúra alatt használnám (pl) az sqrtf() függvényt. Ha csak úgy simán linkelem, akkor nem találja:

main.c:(.text+0x116): undefined reference to `sqrtf'

Ha kézzel hozzáadom a megfelelő libm.a file-t a teljes path-tal (/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32imac/ilp32/libm.a, itt konkrétan), akkor sem találja. Ha ebből a libm.a-ból kiveszem a megfelelo *.o-t (ef_sqrt.c.o, ebben van a T: sqrtf szimbolum), azt adom hozzá linkelés során akkor minden fasza. Szoval azért nem rossz a helyzet, de ez így minden csak nem elegáns, pláne nem hordozható.

A megfelelő specs file-ban (picolibc.specs: /usr/lib/picolibc/riscv64-unknown-elf/picolibc.specs) van egy ilyen sor:

--start-group %(libgcc)  -lc %{-oslib=*:--undefined=_exit} %{-oslib=*:-l%*} --end-group

Ezen felbuzdulva a linerknek átadtam a -Wl,-oslib=m opciót, mondván hogy a {-oslib=*:-l%*} direktíva a -lc-hez meg az -lgcc (libgcc)-hez hasonlóan akkor hozzáadja a -lm-et is. De sajnos ez sem elég, ugyanúgy undefined reference to `sqrtf' lesz a vége, pedig ez mig egy vállalhatóan kultúrált/hordozható opció lehetne:

riscv64-unknown-elf-gcc \
        -march=rv32imac -mabi=ilp32 \
        -Wl,-oslib=m -specs=/usr/lib/picolibc/riscv64-unknown-elf/picolibc.specs \
        -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x10000 -Wl,--defsym=__stack_size=0 \
        -T./picolibc_ram.ld \
        -o main.elf main.o vector.o rtos/libfreertos.a

Ugyan a newlib-et nem próbáltam ki, de azt látom hogy akár ARM-nél is teljesen hasonlóan megy a minden. Szoval (feltételezem) hogy ARM-nál (arm-none-eabi-gcc) is ezt és/vagy ilyesmit kéne csinálni (ha pl. Cortex-M0 alatt akarnánk floating point math library-t használni).

Bármi ötlet? Thx, A.
 

gcc bug vagy en vagyok a hulye (szokas szerint)?

Fórumok

Van egy kb 25 eve irt kodreszlet, ami akkoriban (2.9x gcc-vel) mukodott jol, most pedig gcc 11.x-el mar nem mindig (nehez reprodukalni, nem mindig szar csak ritkan). Ha belerakok egy printf-et akkor viszont jol mukodik, ezert gondolom h valami optimalizalasi bug lehet. Probaltam volatile-t is irni a deklaraciohoz, bar elvileg nem kene, de az sem segitett rajta. Ha a hibakezelest (if..return 0) is kivettem, akkor se lett jobb.

Mi a hiba? :)

 

INLINE static int afs_fread_dword(dword *ptr,int s1,int s2,afs_FILE *f){
  int s=s1*s2/4;
  while(s>0){
    volatile dword c;
    if(afs_fread(&c,sizeof(c),1,f)!=1) return 0;
    printf("   s=%d c=0x%08X ptr=%p\n",s,c,ptr);
#ifdef REVERSE_BYTEORDER
    c= ((c>>24)&0xFF) | (((c>>16)&0xFF)<<8) | (((c>>8)&0xFF)<<16) | ((c&0xFF)<<24);
#endif
    *ptr=c; ++ptr;
    --s;
  }
  return s2;
}

 

kiirattam a parameteretekt, az s2 mindig 1, az s1 pedig 4/8/12/16/32 tehat nem lehet az a baja, hogy nem oszthato 4-el (dword merete)

ha az egesz fuggveny belsejet kicserelem erre az 1 sorra, akkor is jol mukodik:   return afs_fread(ptr,s1,s2,f);