Skip to content
Juan Gonzalez-Gomez edited this page Nov 29, 2022 · 41 revisions

Log

Jueves, 17-Nov-2022

Acabo de recibir el libro "RISC-V assembly Languaje Programming" y la placa ESP32-C3 (ESP32-C3-DevKitM-1) que compré en Elektor en este enlace: https://www.elektor.com/risc-v-assembly-language-programming-using-esp32-c3-and-qemu

Estos son algunos enlaces útiles:

La placa que tengo es la ESP32-C3-DevKitM-1 que lleva el chip ESP32-C3-Min-1 de espressif

Primeras pruebas

Lo he conectado tal cual viene, sin tocar nada. Se enciende un led Rojo, y el led RGB está en color azul claro

En el USB aparece el siguiente dispositivo:

$ lsusb
[...]
Bus 001 Device 008: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
[...]

Instalando el software

Voy a seguir los pasos descritos en el capítulo 2 del libro para instalar las herramientas

La página de Espressif con la documentación para empezar es esta:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html

En el libro hacen la instalación manual, que es la que voy a seguir de momento. Pero aquí se encuentra información para usar VSCOD: https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/tutorial/install.md

Estas son las dependencias a instalar en Ubuntu:

sudo apt-get install git wget flex bison gperf python3 python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0

El software a instalar es el ESP-IDF: Está en este repositorio: https://github.com/espressif/esp-idf

obijuan@Hoth:~/Bin/espc3$ git clone --recursive https://github.com/espressif/esp-idf.git

Para establecer el entorno para trabajar hay que ejecutar este comando:

. $HOME/Bin/espc3/esp-idf/export.sh

Probando el hola mundo

Para probar el hola mundo hacemos lo siguiente

  • Abrimos un terminal nuevo y ejecutamos:
. $HOME/Bin/espc3/esp-idf/export.sh
  • Ahora nos vamos al directorio donde está el Hola mundo. Ya viene uno en el repositorio del esp-idf que hemos clonado:
obijuan@Hoth:~$ cd Bin/espc3/esp-idf/examples/get-started/hello_world/
obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/hello_world$

Configuramos el ejemplo para el esp32c3:

obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/hello_world$ idf.py set-target esp32c3

Ahora ya lo podemos compilar:

obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/hello_world$ idf.py build

Para flashear:

El dispositivo que aparece al conectar la placa es el /dev/ttyUSB0. Primero nos aseguramos que pertenecemos al grupo dialout. Si no es así nos agregamos:

sudo adduser obijuan dialout

(Y será necesario cerrar la sesión y volver a entrar)

Ahora flasheamos con este comando:

idf.py -p /dev/ttyUSB0 flash

Parece que por defecto detecta el puerto /dev/ttyUSB0

En mi caso concreto, aparece esto:

obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/hello_world$ idf.py flash
Executing action: flash
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32-C3
Running ninja in directory /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build
Executing "ninja flash"...
[1/5] cd /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build/esp-idf/esptool_py && /home/obijuan/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/obijuan/Bin/espc3/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 partition --type app /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build/partition_table/partition-table.bin /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build/hello_world.bin
hello_world.bin binary size 0x26860 bytes. Smallest app partition is 0x100000 bytes. 0xd97a0 bytes (85%) free.
[2/5] Performing build step for 'bootloader'
[1/1] cd /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build/bootloader/esp-idf/esptool_py && /home/obijuan/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/obijuan/Bin/espc3/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x0 /home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build/bootloader/bootloader.bin
Bootloader binary size 0x4ef0 bytes. 0x3110 bytes (38%) free.
[2/3] cd /home/obijuan/Bin/espc3/esp-idf/components/esptool_py && /usr/bin/cmake -D IDF_PATH=/home/obijuan/Bin/espc3/esp-idf -D "SERIAL_TOOL=/home/obijuan/.espressif/python_env/idf5.1_py3.10_env/bin/python;;/home/obijuan/Bin/espc3/esp-idf/components/esptool_py/esptool/esptool.py;--chip;esp32c3" -D "SERIAL_TOOL_ARGS=--before=default_reset;--after=hard_reset;write_flash;@flash_args" -D WORKING_DIRECTORY=/home/obijuan/Bin/espc3/esp-idf/examples/get-started/hello_world/build -P /home/obijuan/Bin/espc3/esp-idf/components/esptool_py/run_serial_tool.cmake
esptool esp32c3 -p /dev/ttyUSB0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x0 bootloader/bootloader.bin 0x10000 hello_world.bin 0x8000 partition_table/partition-table.bin
esptool.py v4.3
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-C3 (revision v0.3)
Features: WiFi, BLE
Crystal is 40MHz
MAC: f4:12:fa:17:8e:48
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00004fff...
Flash will be erased from 0x00010000 to 0x00036fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 20208 bytes to 12399...
Writing at 0x00000000... (100 %)
Wrote 20208 bytes (12399 compressed) at 0x00000000 in 0.6 seconds (effective 264.3 kbit/s)...
Hash of data verified.
Compressed 157792 bytes to 85420...
Writing at 0x00010000... (16 %)
Writing at 0x00019d2d... (33 %)
Writing at 0x00020756... (50 %)
Writing at 0x00027726... (66 %)
Writing at 0x0002dec3... (83 %)
Writing at 0x00034fdc... (100 %)
Wrote 157792 bytes (85420 compressed) at 0x00010000 in 2.9 seconds (effective 428.4 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 423.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Done
obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/hello_world$ 

Para ver la ejecución usamos el monitor:

idf.py monitor

Esto es lo que aparece:

obijuan@Hoth:~/Develop/Learn-RISCV-ESP32-C3/Test/hello_world$ idf.py monitor
Executing action: monitor
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32-C3
Running idf_monitor in directory /home/obijuan/Develop/Learn-RISCV-ESP32-C3/Test/hello_world
Executing "/home/obijuan/.espressif/python_env/idf5.1_py3.10_env/bin/python /home/obijuan/Bin/espc3/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix riscv32-esp-elf- --target esp32c3 --decode-panic backtrace /home/obijuan/Develop/Learn-RISCV-ESP32-C3/Test/hello_world/build/hello_world.elf -m '/home/obijuan/.espressif/python_env/idf5.1_py3.10_env/bin/python' '/home/obijuan/Bin/espc3/esp-idf/tools/idf.py'"...
--- idf_monitor on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x16c0
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2e74
entry 0x403cc710
I (30) boot: ESP-IDF v5.1-dev-1840-gaad600c9ca 2nd stage bootloader
I (30) boot: compile time Nov 17 2022 19:12:37
I (31) boot: chip revision: v0.3
I (35) boot.esp32c3: SPI Speed      : 80MHz
I (40) boot.esp32c3: SPI Mode       : DIO
I (44) boot.esp32c3: SPI Flash Size : 2MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (65) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (73) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (80) boot:  2 factory          factory app      00 00 00010000 00100000
I (88) boot: End of partition table
I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=071e8h ( 29160) map
I (105) esp_image: segment 1: paddr=00017210 vaddr=3fc8ac00 size=0157ch (  5500) load
I (110) esp_image: segment 2: paddr=00018794 vaddr=40380000 size=07884h ( 30852) load
I (123) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1358ch ( 79244) map
I (138) esp_image: segment 4: paddr=000335b4 vaddr=40387884 size=03280h ( 12928) load
I (144) boot: Loaded app from partition at offset 0x10000
I (144) boot: Disabling RNG early entropy source...
I (158) cpu_start: Pro cpu up.
I (167) cpu_start: Pro cpu start user code
I (167) cpu_start: cpu freq: 160000000 Hz
I (167) cpu_start: Application information:
I (170) cpu_start: Project name:     hello_world
I (175) cpu_start: App version:      v5.1-dev-1840-gaad600c9ca
I (182) cpu_start: Compile time:     Nov 17 2022 19:12:27
I (188) cpu_start: ELF file SHA256:  50ff8dcfdcbcb42f...
Warning: checksum mismatch between flashed and built applications. Checksum of built application is 8f564f66f76d5f40ffef7cc639e50064633245c267bd6277e92de7d1b6841cc6
I (194) cpu_start: ESP-IDF:          v5.1-dev-1840-gaad600c9ca
I (200) cpu_start: Min chip rev:     v0.3
I (205) cpu_start: Max chip rev:     v0.99 
I (210) cpu_start: Chip rev:         v0.3
I (215) heap_init: Initializing. RAM available for dynamic allocation:
I (222) heap_init: At 3FC8D010 len 0004F700 (317 KiB): DRAM
I (228) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (235) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM
I (242) spi_flash: detected chip: generic
I (246) spi_flash: flash io: dio
W (249) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (263) cpu_start: Starting scheduler.
Hello world!
This is esp32c3 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.3, 2MB external flash
Minimum free heap size: 328536 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...

La salida del programa "hola mundo" es:

[...]
Hello world!
This is esp32c3 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.3, 2MB external flash
Minimum free heap size: 328536 bytes

Espressif en el VSCODE

Voy a probar a instalarlo en el VSCode... Sigo las instrucciones que están en este enlace:

https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/tutorial/install.md

Ya está instalado! Ha sido muy fácil....

Ya he ejecutado el blink, y lo he flasheado... Aunque de momento voy a seguir desde el terminal

Capítulo 3: Instalando QEMU

El repositorio del autor de libro es este: https://github.com/ve3wwg
Ahí tiene todos los ejemplos usados en el libro

Lo he clonado aquí: ~/Develop/risc-v

Instalamos QEMU con este comando:

sudo apt install qemu-system-misc

Ahora comprobamos que está disponible la versión para RISC-V:

$ qemu-system-riscv64 --version
QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.5)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers

Hay que bajar imágenes de fedora de esta url: https://dl.fedoraproject.org/pub/alt/risc-v/repo/virt-builder-images/images/

obijuan@Hoth:~/Develop/risc-v$ wget https://dl.fedoraproject.org/pub/alt/risc-v/repo/virt-builder-images/images/Fedora-Minimal-Rawhide-20200108.n.0-fw_payload-uboot-qemu-virt-smode.elf

obijuan@Hoth:~/Develop/risc-v$ wget Fedora-Minimal-Rawhide-20200108.n.0-fw_payload-uboot-qemu-virt-smode.elf.CHECKSUM

obijuan@Hoth:~/Develop/risc-v$ wget https://dl.fedoraproject.org/pub/alt/risc-v/repo/virt-builder-images/images/Fedora-Minimal-Rawhide-20200108.n.0-sda.raw.xz

Ahora descomprimimos la imagen del disco:

obijuan@Hoth:~/Develop/risc-v$ unxz Fedora-Minimal-Rawhide-20200108.n.0-sda.raw.xz

Editamos el fichero boot.sh para que los nombres de los ficheros sean los mismos que los bajados. Y ahora ya se puede arrancar la máquina:

obijuan@Hoth:~/Develop/risc-v$ ./boot.sh

OpenSBI v0.5 (Jan  7 2020 00:00:00)
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name          : QEMU Virt Machine
Platform HART Features : RV64ACDFIMSU
Platform Max HARTs     : 8
Current Hart           : 0
Firmware Base          : 0x80000000
Firmware Size          : 120 KB
Runtime SBI Version    : 0.2

PMP0: 0x0000000080000000-0x000000008001ffff (A)
PMP1: 0x0000000000000000-0xffffffffffffffff (A,R,W,X)


U-Boot 2020.01 (Jan 07 2020 - 00:00:00 +0000)

CPU:   rv64imafdcsu
Model: riscv-virtio,qemu
DRAM:  2 GiB
In:    uart@10000000
Out:   uart@10000000
Err:   uart@10000000
Net:   
Warning: virtio-net#2 using MAC address from ROM
eth0: virtio-net#2
Hit any key to stop autoboot:  0 

Device 0: QEMU VirtIO Block Device
            Type: Hard Disk
            Capacity: 3072.0 MB = 3.0 GB (6291456 x 512)
... is now current device
Scanning virtio 0:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
580 bytes read in 1 ms (566.4 KiB/s)
Ignoring unknown command: ui
Ignoring malformed menu command:  autoboot
Ignoring malformed menu command:  hidden
Ignoring unknown command: totaltimeout
[...]
Fedora/RISC-V
-------------
Koji:               http://fedora.riscv.rocks/koji/
SCM:                http://fedora.riscv.rocks:3000/
Distribution rep.:  http://fedora.riscv.rocks/repos-dist/
Koji internal rep.: http://fedora.riscv.rocks/repos/
fedora-riscv login:

¡Se está ejecutando un Fedora en una máquina virtual de RISC-V!

Tarda un poco en arrancar. Hay un punto en el que se queda como "colgado", pero sólo hay que esperar un poco

El login lo hacemos con el usuario riscv y el password: fedora_rocks!. Entramos y nos sale el prompt:

[riscv@fedora-riscv ~]$ 
[riscv@fedora-riscv ~]$ ls
[riscv@fedora-riscv ~]$ pwd
/home/riscv
[riscv@fedora-riscv ~]$

Pero también se puede entrar por ssh!!!!:

obijuan@Hoth:~$ ssh -p 10000 riscv@localhost
The authenticity of host '[localhost]:10000 ([127.0.0.1]:10000)' can't be established.
ED25519 key fingerprint is SHA256:Mf/5Xm3C1QKxzlqqLCtrKKR5SvS7GyYKRyPFfF7bqQQ.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:10000' (ED25519) to the list of known hosts.
riscv@localhost's password: 
Last login: Thu Nov 17 16:07:58 2022
[riscv@fedora-riscv ~]$

Cambiamos al usuario root:

[riscv@fedora-riscv ~]$ sudo -i

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for riscv: 
[root@fedora-riscv ~]#

Ahora instalamos git (hay que clonar el repo del libro en Fedora)

[riscv@fedora-riscv repo]$ sudo dnf -y install git

y ahora ya lo podemos clonar:

[riscv@fedora-riscv repo]$ git clone https://github.com/ve3wwg/risc-v.git -b master ~/riscv/repo

Ahora ya podemos cerrar la sesión con este comando:

[riscv@fedora-riscv repo]$ sudo /sbin/shutdown -h now

Ya está todo listo para empezar!!!

Viernes, 18-Nov-2022

Seguimos por el capítulo 5 para probar los primeros ejemplos

Funcion Add3(). RV64. QEMU

  • Primer ejemplo: función add3(). La probamos en el RV64 de Fedora/Linux

Hay que seguir estos pasos:

  1. Lanzar la máquina virtual:
obijuan@Hoth:~/Develop/risc-v$ ./boot.sh
[...]

  1. Entrar por SSH
obijuan@Hoth:~$ ssh -p 10000 riscv@localhost
riscv@localhost's password: 
Last login: Thu Nov 17 16:10:43 2022 from 10.0.2.2
[riscv@fedora-riscv ~]$
  1. Entrar en el directorio con el ejemplo add3:
[riscv@fedora-riscv ~]$ cd riscv/repo/05/add3/qemu64/
[riscv@fedora-riscv qemu64]$ ls
add3.S  main.c
[riscv@fedora-riscv qemu64]$
  1. Compilar

El comando que usamos para compilar es el siguiente:

[riscv@fedora-riscv qemu64]$ gcc -O0 -g main.c add3.S

Sin embargo, en la imagen NO VIENE EL GCC instalado!. Para instalarlo hay que ejecutar:

[riscv@fedora-riscv qemu64]$ sudo dnf -y install gcc
[...]

Ahora ya podemos compilar:

[riscv@fedora-riscv qemu64]$ gcc -O0 -g main.c add3.S
[riscv@fedora-riscv qemu64]$ ls
add3.S  a.out  main.c
[riscv@fedora-riscv qemu64]$

¡Se nos ha generado el ejecute a.out!

Ahora ya lo ejecutamos directamente:

[riscv@fedora-riscv qemu64]$ ./a.out 
r = 72
[riscv@fedora-riscv qemu64]$

Finalizamos cerrando la máquina:

[riscv@fedora-riscv qemu64]$ sudo shutdown -h now

Domingo, 20-Nov-2022

Funcion Add3(). ESP32-C3

Para probar el ejemplo Add3() en el ESP32-C3 seguimos los siguientes pasos:

  1. Ir al directorio ~/Develop/risc-v/05/add3
  2. Exportar las variables para acceder al ESP-IDF:
. $HOME/Bin/espc3/esp-idf/export.sh
  1. Como es la primera vez, lo configuramos para el ESP32-C3:
obijuan@Hoth:~/Develop/risc-v/05/add3$ idf.py set-target esp32c3
  1. Limpiar el proyecto (La primera vez no es necesario)
obijuan@Hoth:~/Develop/risc-v/05/add3$ idf.py fullclean
Executing action: fullclean
Build directory '/home/obijuan/Develop/risc-v/05/add3/main/build' not found. Nothing to clean.
Executing action: remove_managed_components
Done
  1. Construir el proyecto
obijuan@Hoth:~/Develop/risc-v/05/add3$ idf.py build
  1. Flashear el micro
obijuan@Hoth:~/Develop/risc-v/05/add3$ idf.py -p /dev/ttyUSB0 flash

Si ahora abrimos un terminal serie a la velocidad de 115200 baudios, veremos esta salida (Por ejemplo en el gtkterm)

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x16c0
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2e74
entry 0x403cc710
I (30) boot: ESP-IDF v5.1-dev-1840-gaad600c9ca 2nd stage bootloader
I (30) boot: compile time Nov 20 2022 12:48:02
I (31) boot: chip revision: v0.3
I (35) boot.esp32c3: SPI Speed      : 80MHz
I (40) boot.esp32c3: SPI Mode       : DIO
I (44) boot.esp32c3: SPI Flash Size : 2MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (65) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (73) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (80) boot:  2 factory          factory app      00 00 00010000 00100000
I (88) boot: End of partition table
I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=070f0h ( 28912) map
I (105) esp_image: segment 1: paddr=00017118 vaddr=3fc8ac00 size=0157ch (  5500) load
I (110) esp_image: segment 2: paddr=0001869c vaddr=40380000 size=0797ch ( 31100) load
I (123) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=13308h ( 78600) map
I (138) esp_image: segment 4: paddr=00033330 vaddr=4038797c size=0317ch ( 12668) load
I (144) boot: Loaded app from partition at offset 0x10000
I (144) boot: Disabling RNG early entropy source...
I (158) cpu_start: Pro cpu up.
I (167) cpu_start: Pro cpu start user code
I (167) cpu_start: cpu freq: 160000000 Hz
I (167) cpu_start: Application information:
I (170) cpu_start: Project name:     add3
I (174) cpu_start: App version:      160f3e6-dirty
I (180) cpu_start: Compile time:     Nov 20 2022 12:47:54
I (186) cpu_start: ELF file SHA256:  2cc83eb6d24d4ad9...
I (192) cpu_start: ESP-IDF:          v5.1-dev-1840-gaad600c9ca
I (199) cpu_start: Min chip rev:     v0.3
I (203) cpu_start: Max chip rev:     v0.99 
I (208) cpu_start: Chip rev:         v0.3
I (213) heap_init: Initializing. RAM available for dynamic allocation:
I (220) heap_init: At 3FC8D010 len 0004F700 (317 KiB): DRAM
I (226) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (233) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM
I (240) spi_flash: detected chip: generic
I (244) spi_flash: flash io: dio
W (248) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (261) cpu_start: Starting scheduler.
r = 72

(Es necesario que el DTR esté activado)

Justo al final vemos que aparece el mensaje r=72, que es justamente lo que hace el programa cargado

El mismo resultado se puede lograr con:

obijuan@Hoth:~/Develop/risc-v/05/add3$ idf.py monitor

El listado en asm lo podemos ver con el siguiente comando:

obijuan@Hoth:~/Develop/risc-v/05/add3$ ../../listesp main/add3.S
GAS LISTING /tmp/cckb4e9o.s 			page 1


   1              	# 0 "main/add3.S"
   2              	# 0 "<built-in>"
   3              	# 0 "<command-line>"
   4              	# 1 "main/add3.S"
   1              		.global	add3
   2              		.text
   3 0000 2E95     	add3:	add	a0,a0,a1	# a0 = a0 + a1
   4 0002 3295     		add	a0,a0,a2	# a0 = a0 + a2
   5 0004 8280     		ret			# return value in a0

GAS LISTING /tmp/cckb4e9o.s 			page 2


DEFINED SYMBOLS
         main/add3.S:3      .text:0000000000000000 add3

NO UNDEFINED SYMBOLS
obijuan@Hoth:~/Develop/risc-v/05/add3$

Sin embargo, yo prefiero hacerlo directamente invocando riscv32-esp-elf-gcc

obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-gcc -c -Wa,-a,-ad main/add3.S
[...]

También se puede hacer directamente llamando a riscv32-esp-elf-as

obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-as -a main/add3.S 
GAS LISTING main/add3.S 			page 1


   1              		.global	add3
   2              		.text
   3 0000 3305B500 	add3:	add	a0,a0,a1	# a0 = a0 + a1
   4 0004 3305C500 		add	a0,a0,a2	# a0 = a0 + a2
   5 0008 67800000 		ret			# return value in a0

GAS LISTING main/add3.S 			page 2


DEFINED SYMBOLS
         main/add3.S:3      .text:0000000000000000 add3

NO UNDEFINED SYMBOLS

En este caso no se generan instrucciones comprimidas.

Con la opción -march= establecemos la arquitectura. Así, por ejemplo, vamos a generar los listados para las arquitecturas rv32i y rv32ic (Si no se indica nada, se toma por defecto rv32i)

obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-as -c -march=rv32i -a main/add3.S -o add3.o
GAS LISTING main/add3.S 			page 1


   1              		.global	add3
   2              		.text
   3 0000 3305B500 	add3:	add	a0,a0,a1	# a0 = a0 + a1
   4 0004 3305C500 		add	a0,a0,a2	# a0 = a0 + a2
   5 0008 67800000 		ret			# return value in a0

GAS LISTING main/add3.S 			page 2


DEFINED SYMBOLS
         main/add3.S:3      .text:0000000000000000 add3

NO UNDEFINED SYMBOLS
obijuan@Hoth:~/Develop/risc-v/05/add3$

Y este es con el comprimido:

obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-as -c -march=rv32ic -a main/add3.S -o add3.o
GAS LISTING main/add3.S 			page 1


   1              		.global	add3
   2              		.text
   3 0000 2E95     	add3:	add	a0,a0,a1	# a0 = a0 + a1
   4 0002 3295     		add	a0,a0,a2	# a0 = a0 + a2
   5 0004 8280     		ret			# return value in a0

GAS LISTING main/add3.S 			page 2


DEFINED SYMBOLS
         main/add3.S:3      .text:0000000000000000 add3

NO UNDEFINED SYMBOLS
obijuan@Hoth:~/Develop/risc-v/05/add3$

Add3 en ESP32-C3: Código máquina

Si tenemos el archivo add3.S, lo queremos ensamblar, obtejer el fichero objeto add3.o y luego desensamblarlo para ver su código máquina, hacemos lo siguiente:

#-- Ensamblar
obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-as -march=rv32i  main/add3.S -o add3.o
#-- Ver código máquina
obijuan@Hoth:~/Develop/risc-v/05/add3$ riscv32-esp-elf-objdump -d add3.o 

add3.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <add3>:
   0:	00b50533          	add	a0,a0,a1
   4:	00c50533          	add	a0,a0,a2
   8:	00008067          	ret
obijuan@Hoth:~/Develop/risc-v/05/add3$

Jugando con el Blink

Antes de seguir con el libro, voy a hacer más pruebas con el Blink. El objeto es llegar, en algún momento, en tener el mínimo código posible en asm que se pueda flashear en el esp32-c3. Pero para ello hay que aprener antes muchas cosas

Lo primero es ser capaces de encender un LED...

Para poner en marcha el blink desde cero hacemos los siguiente:

  1. Abrimos un terminal y damos acceso a las toolchains
. $HOME/Bin/espc3/esp-idf/export.sh
  1. Entramos en el directorio del blink:
obijuan@Hoth:~$ cd Bin/espc3/esp-idf/examples/get-started/blink/
  1. Borramos el directorio build, para eliminar todo rastro de una ejecución anterior
rm -r build/
  1. Configuramos para el ESP32-C3
 obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/blink$ idf.py set-target esp32c3
  1. Compilamos el blink
obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/blink$ idf.py build
  1. Flasheamos el blink
 obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/blink$ idf.py flash
  1. Monitorear: Si abrimos el gtkterm a 115200 baudios veremos esto:

Esto es lo que sale al apretar el reset:

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x16c0
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2e74
entry 0x403cc710
I (30) boot: ESP-IDF v5.1-dev-1840-gaad600c9ca 2nd stage bootloader
I (30) boot: compile time Nov 20 2022 14:05:39
I (31) boot: chip revision: v0.3
I (35) boot.esp32c3: SPI Speed      : 80MHz
I (40) boot.esp32c3: SPI Mode       : DIO
I (44) boot.esp32c3: SPI Flash Size : 2MB
I (49) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (65) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (73) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (80) boot:  2 factory          factory app      00 00 00010000 00100000
I (88) boot: End of partition table
I (92) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=08508h ( 34056) map
I (106) esp_image: segment 1: paddr=00018530 vaddr=3fc8ba00 size=015f4h (  5620) load
I (110) esp_image: segment 2: paddr=00019b2c vaddr=40380000 size=064ech ( 25836) load
I (122) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1680ch ( 92172) map
I (140) esp_image: segment 4: paddr=00036834 vaddr=403864ec size=05410h ( 21520) load
I (148) boot: Loaded app from partition at offset 0x10000
I (148) boot: Disabling RNG early entropy source...
I (160) cpu_start: Pro cpu up.
I (169) cpu_start: Pro cpu start user code
I (169) cpu_start: cpu freq: 160000000 Hz
I (169) cpu_start: Application information:
I (172) cpu_start: Project name:     blink
I (177) cpu_start: App version:      v5.1-dev-1840-gaad600c9ca
I (183) cpu_start: Compile time:     Nov 20 2022 14:05:31
I (189) cpu_start: ELF file SHA256:  0f28449b3bd42a23...
I (195) cpu_start: ESP-IDF:          v5.1-dev-1840-gaad600c9ca
I (202) cpu_start: Min chip rev:     v0.3
I (206) cpu_start: Max chip rev:     v0.99 
I (211) cpu_start: Chip rev:         v0.3
I (216) heap_init: Initializing. RAM available for dynamic allocation:
I (223) heap_init: At 3FC8DEA0 len 0004E870 (314 KiB): DRAM
I (229) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (236) heap_init: At 50000020 len 00001FE0 (7 KiB): RTCRAM
I (243) spi_flash: detected chip: generic
I (247) spi_flash: flash io: dio
W (251) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (264) cpu_start: Starting scheduler.
I (269) example: Example configured to blink addressable LED!
I (269) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (279) example: Turning the LED OFF!
I (1279) example: Turning the LED ON!

Luego en la consola veremos todo el rato esto:

I (2279) example: Turning the LED OFF!
I (3279) example: Turning the LED ON!
I (4279) example: Turning the LED OFF!
I (5279) example: Turning the LED ON!
[...]

Ahora voy a modificar el programa principal, que está en c, para modificar la velocidad de parpadeo, a ver si todo va ok

OK. En la línea 89 he cambiado una constante (que valía 1000, por 500):

vTaskDelay(500 / portTICK_PERIOD_MS);

Efectivamente ahora parpadea a mayor frecuencia.

Viendo el código fuente, el LED RBG que tiene instalado es uno de los direccionables, es decir, que NO es el típico led on/off... Voy a conectar en una protoboard un led normal, a otro gpio... a ver si consigo que luzca

El GPIO que voy a usar es el 2 (que se corresponde con el pin "2" de la ESP32, detras del pin "3v3")

OK! Ya tengo el gpio2 parpadeando! Lo he cambiado primero con idf.py menuconfig. Esto lo que hace es que escribe la configuración en el fichero sdkconfig.h que se importa...

Ahora voy a simplificar el código

Esta es la versión "Hola mundo":

#include <stdio.h>
#include "driver/gpio.h"

#define BLINK_GPIO 2

static uint8_t s_led_state = 0;

void app_main(void)
{
    //-- Configure GPIO
    gpio_reset_pin(BLINK_GPIO);

    /* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);

    while (1) {
        gpio_set_level(BLINK_GPIO, s_led_state);
        
        /* Toggle the LED state */
        s_led_state = !s_led_state;

        //-- Wait some time
        volatile int temp = 0;
        for(int i = 0; i<0x008FFFFF; i++) {
            temp = temp * 6;
        }
    }
}

El mapa de periféricos se encuentra en la página 87 del manual técnico. Ahí se puede ver que las direcciones de los GIPIOs están en 0x6000_4000 - 0x6000_4FFF

El registro GPIO_OUT_REG (offset 0x0004) es el que se usa para escribir en los pines. Su valor se saca por los pines

Este programa en C hace un Blink sin usar las bibliotecas, sólo accediendo directamente a los puertos

#include <stdio.h>

static uint8_t s_led_state = 0;

/*--- Peripheral declaration */
//-- Registro de salida de las GPIO. Su valor se escribe en los pines
#define GPIO_OUT_REG    0x60004004 
#define GPIO_ENABLE_REG 0x60004020


void app_main(void)
{
    /* Set the GPIO as a push/pull output */
    *(uint32_t *)GPIO_ENABLE_REG = 0x4;

    while (1) {
        *(uint32_t *)GPIO_OUT_REG = s_led_state << 2;  //0x4;
        
        /* Toggle the LED state */
        s_led_state = !s_led_state;

        //-- Wait some time
        volatile int temp = 0;
        for(int i = 0; i<0x008FFFFF; i++) {
            temp = temp * 6;
        }
    }
}

Este es el ejemplo mínimo en ensamblador

   .global app_main
	.text

app_main:
    # -- Configurar GPIO2 de salida
	li a0, 0x60004004 //-- GPIO_ENABLE_REG
	li a1, 0x04
	sw a1, 0(a0)

	#-- Encender el LED
	li a0, 0x60004020 //-- GPIO_OUT_REG
	li a1, 0x04
	sw a1, 0(a0)
stop:
	j stop

El problema es que se compila y enlaza con las librerias... y se generan muchas cosas. Tengo que ver cómo generar un ejecutable sólo con el código asm mínimo (y nada más)

En este enlace hay un ejemplo de bare metal: https://github.com/bigmagic123/esp32c3_bare_metal
Tengo que estudiarlo y evaluarlo

Aquí hay otro enlace a estudiar: https://github.com/cpq/mdk. Este enlace parece más interesante... seguramente es por el que empezaré, una vez terminado el libro

Lunes, 21-Nov-2022

Capítulo 6: Load and Store Memory

ESP32-C3: Load.S

Probamos el ejemplo 6 en el ESP32-C3.

  1. Abrimos terminal y exportamos:
. $HOME/Bin/espc3/esp-idf/export.sh
  1. Compilamos y ejecutamos

En el terminal vemos esto:

loadb() = 00000001
loadh() = FFFFF509
loadw() = 0708090A
loadd() = 00CCBBAA99887766

Lo interesante de este ejemplo es que se usan pseudo-instrucciones de load

	.global	loadb,loadh,loadw,loadd

	.text
loadb:	lb	a0,byte		# Load a byte
	ret
loadh:	lh	a0,hword	# Load half word
	ret
loadw:	lw	a0,word		# Load a word
	ret
loadd:	lw	a0,dword	# Load lower word of dword
	lw	a1,dword+4	# Load upper word of dword
	ret			# return value in a0

	.data
byte:	.byte	1
hword:	.half	0xF509
word:	.word	0x0708090A
dword:	.dword	0xCCBBAA99887766

La primera instrucción de carga es lb a0, byte, donde byte es una etiqueta. Para ver las instruciones básicas reales, hacemos lo siguiente:

obijuan@Hoth:~/Develop/risc-v/06/loads$ riscv32-esp-elf-as  main/loads.S -o loads.o
obijuan@Hoth:~/Develop/risc-v/06/loads$ riscv32-esp-elf-objdump -d loads.o

Las primeras líneas del programa desensamblado son estas:

Disassembly of section .text:

00000000 <loadb>:
   0:   00000517                auipc   a0,0x0
   4:   00050503                lb      a0,0(a0) # 0 <loadb>
   8:   00008067                ret
[...]

Vemos que la pseudo-instrucción lb a0,byte se traduce por las instrucciones reales:

auipc a0, 0x0
lb a0, 0(a0)

La instrucción auipc almacena el valor PC + {imm, 12'd0}. Donde imm en este caso es 0. Entiendo que luego el enlazador cambiará ese offset para que apunte al valor correcto...

ESP32-C3: aligned.S

Es el mismo ejemplo anterior, pero usando la directiva .baligned para indicar que se quiere que los datos estén alineados

QEMU-RV64: Load.S

Vamos a probarlo ahora en el rv64:

  1. Lanzar la máquina virtual:
obijuan@Hoth:~/Develop/risc-v$ ./boot.sh
[...]

  1. Entrar por SSH
obijuan@Hoth:~$ ssh -p 10000 riscv@localhost
riscv@localhost's password: 
Last login: Thu Nov 17 16:10:43 2022 from 10.0.2.2
[riscv@fedora-riscv ~]$
  1. Entrar en el directorio con el ejemplo loads:
[riscv@fedora-riscv ~]$ cd riscv/repo/06/loads/qemu64
[riscv@fedora-riscv qemu64]$ ls
loads.S  main.c
[riscv@fedora-riscv qemu64]$
  1. Compilar y ejecutar:
[riscv@fedora-riscv qemu64]$ gcc -O0 -g loads.S main.c
[riscv@fedora-riscv qemu64]$ ./a.out 
loadb() = 00000001
loadh() = FFFFF509
loadw() = 0708090A
loadd() = 00CCBBAA99887766

ESP32-C3: celsius.S

En este ejemplo se muestra lo que ocurre con la instrucción lw t0, temp_f10. Lo compilamos y lo analizamos con objdump:

obijuan@Hoth:~/Develop/risc-v/06/celsius$ riscv32-esp-elf-as  main/celsius.S -o celsius.o
obijuan@Hoth:~/Develop/risc-v/06/celsius$ riscv32-esp-elf-objdump -d celsius.o

Lo que se obtiene es lo siguiente:

Disassembly of section .text:

00000000 <convtemp>:
   0:   00000297                auipc   t0,0x0
   4:   0002a283                lw      t0,0(t0) # 0 <convtemp>
   8:   ec028293                addi    t0,t0,-320
   c:   00a00313                li      t1,10
  10:   026282b3                mul     t0,t0,t1
  14:   01200313                li      t1,18
  18:   0262c2b3                div     t0,t0,t1
  1c:   00000337                lui     t1,0x0
  20:   00532023                sw      t0,0(t1) # 0 <convtemp>
  24:   00008067                ret

Vemos que el lw se ha traducido como:

aupc t0,0x0
lw t0,0(t0

Sin embargo, el linker lo sustituye por las instrucciones correctas

420067b8 <convtemp>:
420067b8:	8341a283          	lw	t0,-1996(gp) # 3fc8ac34 <temp_f10>

QEMU-RV64: celsius2.S

Vamos al directorio

[riscv@fedora-riscv ~]$ cd riscv/repo/06/celsius2/qemu64/
[riscv@fedora-riscv qemu64]$ ls
celcius2.S  main.c
[riscv@fedora-riscv qemu64]$

y compilamos:

[riscv@fedora-riscv qemu64]$ gcc -O0 -g celcius2.S main.c
[riscv@fedora-riscv qemu64]$ ./a.out 
40.0 F -> 4.4 C
[riscv@fedora-riscv qemu64]$

Depurando con JTAG-USB

En el capítulo 15 hablan sobre cómo depurar con el ESP32-C3 con JTAG... sin embargo esto sólo se puede hacer con la revisión 3 del chip. La revisión que tengo yo es la 0.3... esto se puede ver al flashear:

$ idf.py flash
[...]
esptool.py v4.3
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-C3 (revision v0.3)
Features: WiFi, BLE
Crystal is 40MHz
[...]

Voy a intentar conseguir un ESP32-C3 (rev 3)

Capítulo 7: Calling convention

ESP32-C3: jal

Compilamos y flasheamos el programa:

obijuan@Hoth:~/Develop/risc-v/07/jal$ idf.py build
[...]
obijuan@Hoth:~/Develop/risc-v/07/jal$ idf.py flash

Al ejecutar el programa obtenemos esto:

callme() returned 3

Me resulta muy interesante la idea de hacer llamadas "internas", usanto registros temporales

QEMU-RV64: jal

Accedemos al directorio:

[riscv@fedora-riscv ~]$ cd riscv/repo/07/jal/qemu64/
[riscv@fedora-riscv qemu64]$ ls
jal.S  main.c
[riscv@fedora-riscv qemu64]$

Compilamos y ejecutamos:

[riscv@fedora-riscv qemu64]$ gcc -O0 -g jal.S main.c
[riscv@fedora-riscv qemu64]$ ./a.out 
callme() returned 3
[riscv@fedora-riscv qemu64]$

Vamos a probar el gdb... primero hay que instalarlo. Me ha dado un error (conflictos...) así que he probado con esto:

[riscv@fedora-riscv qemu64]$ sudo dnf -y --allowerasing install gdb
[...]

y Comprobamos si está el gdb:

[riscv@fedora-riscv qemu64]$ gdb --version
GNU gdb (GDB)  12.1-5.0.riscv64.fc33
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[riscv@fedora-riscv qemu64]$

Ahora ya podmeos depurar:

[riscv@fedora-riscv qemu64]$ gdb a.out
GNU gdb (GDB)  12.1-5.0.riscv64.fc33
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "riscv64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) list
1	#include <stdio.h>
2	
3	extern int callme();
4	
5	int
6	main(int argc,char **argv) {
7	
8		printf("callme() returned %d\n",callme());
9		return 0;
10	}
(gdb) 

Ponemos un breakpoint en la función callme() y ejecutamos el ejemplo:

(gdb) b callme
Breakpoint 1 at 0x110d4: file jal.S, line 4.
(gdb) r
Starting program: /home/riscv/riscv/repo/07/jal/qemu64/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/lp64d/libthread_db.so.1".

Breakpoint 1, callme () at jal.S:4
4	callme:	li	a0,1		# a0 = 1
(gdb)

Para ejecutar un paso usamos el comando s:

(gdb) s
5		call	t0,intern	# Call internal
(gdb)

Para ver el contenido de a0 usamos info reg a0

(gdb) info reg a0
a0             0x1	1
(gdb)

Martes, 29-Nov-2022

Ya me han llegado placas nuevas, así que voy a comprobar si son la revisión 3 (o superior) y puedo poner en marcha la depuración con JTAG

Depurando con JTAG-USB

Vaya, la primera placa que pruebo y también es una revisión 0.3....

esptool.py v4.3
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-C3 (revision v0.3)
Features: WiFi, BLE
Crystal is 40MHz
MAC: 58:cf:79:e2:c8:30
Uploading stub...

Voy a probar con la placa "dual", que tiene 2 USB. Uno marcado como "COM" y el otro com "USB"

Esto es lo que me sale al conectarlo:

$ lsusb
[...]
Bus 001 Device 010: ID 1a86:7522 QinHeng Electronics USB Serial
[...]
$ sudo dmesg
[...]
[ 1616.055352] usb 1-5: New USB device found, idVendor=1a86, idProduct=7522, bcdDevice= 2.64
[ 1616.055359] usb 1-5: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 1616.055362] usb 1-5: Product: USB Serial
[ 1616.056677] ch341 1-5:1.0: ch341-uart converter detected
[ 1616.057232] usb 1-5: ch341-uart converter now attached to ttyUSB0

Sale el dispositivo /dev/ttyUSB0... voy a intentar flashear... a ver qué pasa....

El programa que tiene cargado ahora lo que hace es poner el LED rgb a rojo...

Lo voy a flashear a ver que sale...

[...]
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-C3 (revision v0.4)
Features: WiFi, BLE
Crystal is 40MHz
MAC: dc:54:75:62:36:b8
[...]

Me dice que la revisión es la 0.4.... es mayor que la que tengo... pero no sé si me pemitirá usar el JTAG.... Las buenas noticias son que al menos lo he podido flashear...

Lo conecto por el otro USB al pc. Esto es lo que obtengo:

$ lsusb
[...]
us 001 Device 011: ID 303a:1001 Espressif USB JTAG/serial debug unit
[...]
$ sudo dmesg
[...]
[ 2065.756259] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2065.756263] usb 1-5: Product: USB JTAG/serial debug unit
[ 2065.756267] usb 1-5: Manufacturer: Espressif
[ 2065.756270] usb 1-5: SerialNumber: DC:54:75:62:36:B8
[ 2065.788716] cdc_acm 1-5:1.0: ttyACM0: USB ACM device
[ 2065.788792] usbcore: registered new interface driver cdc_acm
[ 2065.788796] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[...]

Bueno... eso me da esperanzas!!!

Esto pinta muy bien!!!! Me ha arrancado el OPENOCD y no da error!!!

$ openocd -f board/esp32c3-builtin.cfg
Open On-Chip Debugger v0.11.0-esp32-20221026 (2022-10-26-14:47)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
Warn : Transport "jtag" was already selected
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : esp_usb_jtag: serial (DC:54:75:62:36:B8)
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 40000 kHz
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : datacount=2 progbufsize=16
Info : Examined RISC-V core; found 1 harts
Info :  hart 0: XLEN=32, misa=0x40101104
Info : starting gdb server for esp32c3 on 3333
Info : Listening on port 3333 for gdb connections

Ahora arranco el gdb:

obijuan@Hoth:~/Bin/espc3/esp-idf/examples/get-started/blink$ idf.py gdb
Executing action: gdb
GNU gdb (esp-gdb) 12.1_20221002
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=riscv32-esp-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
add symbol table from file "/home/obijuan/Bin/espc3/esp-idf/examples/get-started/blink/build/bootloader/bootloader.elf"
0x40000000 in ?? ()
add symbol table from file "/home/obijuan/.espressif/tools/esp-rom-elfs/20220823/esp32c3_rev3_rom.elf"
JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Reset cause (3) - (Software core reset)
Warning: 'flushregs', an alias for the command 'maintenance flush register-cache', is deprecated.
Use 'maintenance flush register-cache'.
--Type <RET> for more, q to quit, c to continue without paging--
Hardware assisted breakpoint 1 at 0x42006836: file /home/obijuan/Bin/espc3/esp-idf/examples/get-started/blink/main/blink_example_main.c, line 13.
[New Thread 1070137292]
[New Thread 1070139264]
[New Thread 1070132784]
[Switching to Thread 1070137292]

Thread 2 "main" hit Temporary breakpoint 1, app_main () at /home/obijuan/Bin/espc3/esp-idf/examples/get-started/blink/main/blink_example_main.c:13
13	{
(gdb) 

En el terminal del OpenOCD aparece esto, a continuación de lo anterior:

Info : accepting 'gdb' connection on tcp/3333
Memory protection is enabled. Reset target to disable it...
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : Reset cause (3) - (Software core reset)
Warn : No symbols for FreeRTOS!
Info : [esp32c3] Found 8 triggers
Info : Flash mapping 0: 0x10020 -> 0x3c020020, 28 KB
Info : Flash mapping 1: 0x20020 -> 0x42000020, 76 KB
Info : Auto-detected flash bank 'esp32c3.flash' size 4096 KB
Info : Using flash bank 'esp32c3.flash' size 4096 KB
Info : Flash mapping 0: 0x10020 -> 0x3c020020, 28 KB
Info : Flash mapping 1: 0x20020 -> 0x42000020, 76 KB
Info : Using flash bank 'esp32c3.irom' size 80 KB
Info : Flash mapping 0: 0x10020 -> 0x3c020020, 28 KB
Info : Flash mapping 1: 0x20020 -> 0x42000020, 76 KB
Info : Using flash bank 'esp32c3.drom' size 32 KB
Warn : Prefer GDB command "target extended-remote :3333" instead of "target remote :3333"
Info : Detected FreeRTOS version: (10.4.3)
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Info : Reset cause (3) - (Software core reset)

Parece que la cosa ha ido bien!!!

Vamos a probar comandos. Uno es list:

(gdb) list
8	#define GPIO_OUT_REG    0x60004004 
9	#define GPIO_ENABLE_REG 0x60004020
10	
11	
12	void app_main(void)
13	{
14	    /* Set the GPIO as a push/pull output */
15	    *(uint32_t *)GPIO_ENABLE_REG = 0x4;
16	
17	    while (1) {
(gdb)
(gdb) 
18	        *(uint32_t *)GPIO_OUT_REG = s_led_state << 2;  //0x4;
19	        
20	        /* Toggle the LED state */
21	        s_led_state = !s_led_state;
22	
23	        //-- Wait some time
24	        volatile int temp = 0;
25	        for(int i = 0; i<0x008FFFFF; i++) {
26	            temp = temp * 6;
27	        }
(gdb)

El comando frame nos indica donde estábamos:

(gdb) frame
#0  app_main ()
    at /home/obijuan/Bin/espc3/esp-idf/examples/get-started/blink/main/blink_example_main.c:13
13	{
(gdb)

El comando backtrace nos indica qué funciones se han llamado:

(gdb) backtrace
#0  app_main ()
    at /home/obijuan/Bin/espc3/esp-idf/examples/get-started/blink/main/blink_example_main.c:13
#1  0x4201301e in main_task (args=<optimized out>)
    at /home/obijuan/Bin/espc3/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:131
#2  0x40386548 in prvTaskExitError ()
    at /home/obijuan/Bin/espc3/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:132
Backtrace stopped: frame did not save the PC
(gdb)

Para avanzar en la depuracion ejecutamos next:

(gdb) next
15	    *(uint32_t *)GPIO_ENABLE_REG = 0x4;
(gdb)

Tengo que aprener a manejar el gdb... pero parece que funciona!!!!!! vaaaaamos!!!!