Відповісти

Введіть повідомлення і натисніть Надіслати
Параметри

Назад

Огляд теми (нові повідомленні вгорі)

jokeer
Вчора 23:03:37

Хм, цікаві досліди wink спробую відтворити.
Там ще є логування в uart, відключене через #if 0
Треба подивитись, може там є щось цікаве.

dimich
Вчора 21:54:37

Вирішив теж спробувати цей picorvd. Довелось обробити напильником, щоб зібрати під сучасним Arch.

По-перше, в pico_sdk_import.cmake замінив PicoSDK на 2.3.0, бо з 1.5.1 виникала помилка через версію cmake. Ще і з нею розбиратись не хотілось, тому просто бампнув тег на останній, там версію cmake уже пофіксили.

По-друге, в example/build замінив префікс тулчейна на riscv64-elf-, та шлях до хедерів newlib на /usr/risc64-elf/include, де воно в мене і лежить.

Також поправив blink.cpp, щоби блимало PC4, а не PD0 та PD4. Бо LED у мене на PC4, а на PD4 SWIO.
Прошилось і навіть щось запрацювало.

dimich пише:

А, бачу, воно вже з -O0 компілиться. Але ж агрумент все одно через регістр передається: https://godbolt.org/z/o5YYEjYEK

Тут трохи не додивився: аргумент-то передається в регістрі, але в самій функції потім кладеться в стек.
При blink зібраному з "-ggdb -Og" навіть значення аргумента показує правильно.

$ riscv32-elf-gdb ./bin/blink.elf 
Reading symbols from ./bin/blink.elf...
(gdb) target extended-remote /dev/ttyACM0
Remote debugging using /dev/ttyACM0
0x0000019e in busywait (x=x@entry=300000) at blink.cpp:8
8          for (volatile int i = 0; i < x; i++) {
(gdb) p x
$1 = 300000
(gdb) info frame
Stack level 0, frame at 0x200007f0:
 pc = 0xd28 in busywait (blink.cpp:8); saved pc = 0xdb4
 called by frame at 0x200007fc
 source language c++.
 Arglist at 0x200007f0, args: x=x@entry=300000
 Locals at 0x200007f0, Previous frame's sp is 0x200007f0
(gdb) bt
#0  0x00000d28 in busywait (x=x@entry=300000) at blink.cpp:8
#1  0x00000db4 in main () at blink.cpp:35

При зупинці по брекпоінту перестає, "Breakpoint 1, busywait (x=<error reading variable: Cannot access memory at address 0xfffffff0>) at blink.cpp:8"
А от якщо при збірці blink прибрати garbage collection секцій (при цьому розмір blink зростає майже до 4 кб), то початкове вхідне значення показує правильно, а поточне відповідає значенню регістра, в якому передавався аргумент:

(gdb) break 8
Breakpoint 1 at 0xd24: file blink.cpp, line 8.
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) continue 
Continuing.

Breakpoint 1, busywait (x=32800, x@entry=300000) at blink.cpp:8
8          for (volatile int i = 0; i < x; i++) {
(gdb) info registers
ra             0xda4    0xda4 <main()+108>
sp             0x200007f0       0x200007f0
gp             0x20000800       0x20000800
tp             0x804e06a4       0x804e06a4
t0             0x1a0    416
t1             0x40014281       1073824385
t2             0x5b763111       1534472465
fp             0x0      0x0 <InterruptVectorDefault>
s1             0x40011000       1073811456
a0             0x8020   32800
a1             0x4002200c       1073881100
a2             0x8000d40        134221120
a3             0x50000  327680
a4             0x10040  65600
a5             0x90000  589824
pc             0xd2e    0xd2e <busywait(int)+12>

"monitor reset" працює, покрокове виконання працює.

dimich
2026-07-29 21:46:47
jokeR пише:

Через файл gdbinit wink

А, ну якщо там є target remote / extended-remote, і gdb запускаєте з '-x gdbinit', то має зʼєднуватись.
Не знаю, чи лежить він там у вас як ~/.config/gdb/gdbinit і ваш gdb-multiarch автоматично виконує його при старті, чи потрібно в командному рядку кожний раз передавати.

jokeR пише:

Походу його не навчили цьому sad

Код для ресету там є: src/RVDebug.cpp:95. А

"monitor" command not supported by this target.

- це про команду "monitor", яка не supported, поки target не визначений. Тому логічно припустити, що gdb просто нікуди не підключений в цей момент.

jokeR пише:

а що debug не працює - незручно sad

По факту він-то працює. На брекпоінті зупинився ж якось. Регістри та машинний код показує? Ну а змусити значення змінних показувати, коли вони у регістрах - це навіть на рідній хостовій системі не завжди вдається.

jokeR
2026-07-29 20:54:35

Ну gdb-multiarch має ж якось взнати, що є ttyACM0, на якому його будуть слухати.

Через файл gdbinit wink

Магічний пристрій і є монітор, який реалізує протокол gdb-сервера.

Походу його не навчили цьому sad

Ну reset то таке.. можна і руками.. а що debug не працює - незручно sad

dimich
2026-07-29 20:18:51
jokeR пише:

У нас є gdb-multiarch, є ttyACM0

Ну gdb-multiarch має ж якось взнати, що є ttyACM0, на якому його будуть слухати.

jokeR пише:

є магічний пристій, що слухає ttyACM0 і смикає CH32V003 за SDIO.

Магічний пристрій і є монітор, який реалізує протокол gdb-сервера. В "класичній" конфігурації цю роль виконує openocd, який в свою чергу вже спілкується з залізом по іншом протоколу, наприклад, по JTAG.

jokeR
2026-07-29 20:07:42

А ви gdb з монітором зʼєднали?

Складно wink
У нас є gdb-multiarch, є ttyACM0, є магічний пристій, що слухає ttyACM0 і смикає CH32V003 за SDIO.

dimich
2026-07-29 18:12:29
jokeR пише:

ніт, "monitor" command not supported by this target.

А ви gdb з монітором зʼєднали?

After that run "gdb-multiarch {your_binary.elf}" and type "target extended-remote /dev/ttyACM0" to connect to the debugger (replace ttyACM0 with whatever port your Pico shows up as).

jokeR пише:

$CC -g -O0

Так, уже побачив, відредагував.

jokeR
2026-07-29 17:51:41

А "monitor reset" працює?

ніт, "monitor" command not supported by this target.

потрібно збирати з -Og,

$CC -g -O0 -ffunction-sections -static-libgcc -lgcc -march=rv32ec_zicsr -mabi=ilp32e -I/usr/include/newlib -nostdlib -I. -Wall -c ch32v003fun.c -o obj/ch32v003fun.o

щось недороблене sad

dimich
2026-07-29 17:28:47
jokeR пише:

Трохи дивує що заливається не .bin, а .elf.

Gdb бере elf на вхід. З нього ж таблицю символів читає для дебага, і дебажні символи, якщо є, і цільову архітектуру для multiarch.
Сирий бінарик прошити можна командою restore.

jokeR пише:

Десь під капотом повинна бути магія objcopy?

Та яка там магія. Заголовок, секції з атрибутами, таблиця символів. Avrdude ж теж elf шʼє.

jokeR пише:

Ага, трохи роз"ясняється. picorvd - заливає прошивку правильно, але в кінці не робить reset.

А "monitor reset" працює?

jokeR пише:

ardulink, походу, робить reset через живлення wink

WCH-LinkE теж вміє живленням смикати. Корисно коли нема NRST.

jokeR пише:

Note: automatically using hardware breakpoints for read-only addresses.

Дивно, в README picorvd пишуть же:

The CH32V003 chip does not support any hardware breakpoints.

jokeR пише:

0x000001e4 in busywait (x=<error reading variable: Cannot access memory at address 0xfffffff4>) at blink.cpp:4

Скоріш за все той аргумент x зник ще на етапі компіляції. Але чому gdb в неіснуючу памʼять лізе, замість того щоб сказати value optimized out - то вже х.з. 
Взагалі, щоб більш-менш адекватний рантайм дебаг отримати, потрібно збирати з -Og, або хоча б -fno-omit-frame-pointer.
UPD: А, бачу, воно вже з -O0 компілиться. Але ж агрумент все одно через регістр передається: https://godbolt.org/z/o5YYEjYEK

jokeR
2026-07-29 10:03:43
gdb-multiarch -x gdbinit -ex 'load' -ex 'detach' -ex 'quit' bin/blink.elf

Трохи дивує що заливається не .bin, а .elf. Десь під капотом повинна бути магія objcopy?

А якщо той же бінарик зашити заздалегідь робочим програматором?

Зашивається, працює

Через ardulink, зроблений з arduino, і пише і читає. Ок wink

Ага, трохи роз"ясняється. picorvd - заливає прошивку правильно, але в кінці не робить reset. ardulink, походу, робить reset через живлення wink Якщо ребутнути через power - blink запускається. Але з debug - облом sad

GNU gdb (xPack GNU RISC-V Embedded GCC x86_64) 12.1
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-pc-linux-gnu --target=riscv-wch-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"...
Reading symbols from bin/blink.elf...
0x000001e4 in busywait (x=600000) at blink.cpp:4
4	   for (volatile int i = 0; i < x; i++) {
(gdb) break 10
Breakpoint 1 at 0x212: file blink.cpp, line 10.
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) break 11
Breakpoint 2 at 0x214: file blink.cpp, line 13.
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x000001e4 in busywait (x=<error reading variable: Cannot access memory at address 0xfffffff4>) at blink.cpp:4
4	   for (volatile int i = 0; i < x; i++) {
(gdb) 

Щось там недороблено sad

dimich
2026-07-28 20:06:13
jokeR пише:

blink наче заливає, але рівень на пінах не міняється.

На пінах цільового CH32? А якщо той же бінарик зашити заздалегідь робочим програматором?
Впевніться, що дивитесь на тому ж піні, яким цей blink дригає. На різних платах LED на різних пінах може бути, це ж не ардуіно. 

jokeR пише:

Що хотів сказати автор issue.. Не та версія компілятора? gdb? А яка потрібна?

А х.з., у нього треба питати. Мабуть тулчейн мається на увазі, бо в xpack і компілятор, і gdb.
Теоретично, на момент написання того комента уже був gdb 13-ї версії, а може й 14-ї. А platformio досі ставить 12.1.

jokeR пише:

Жаль що до кінця ту штуку не доробили sad

Я б не покладав сподівань на проект, в якому приклад blink лінкується з libgcc.a, що лежить в цьому ж репозиторії.

jokeR
2026-07-28 16:19:43

хттпс://github.com/aappleby/picorvd
Надибав таке. Виглядає непогано, і rp2040 в хазяйстві є wink
Але не працює sad
blink наче заливає, але рівень на пінах не міняється.
При спробі debug - відтворюється хттпс://github.com/aappleby/picorvd/issues/8
Що хотів сказати автор issue.. Не та версія компілятора? gdb? А яка потрібна? ..
Жаль що до кінця ту штуку не доробили sad

jokeer
2026-07-27 15:53:01

Ну коли замість програматора за 300 грн UART за 50 - в принципі непогано..

dimich
2026-07-27 14:54:55
jokeer пише:

Няп тут про bootloader,  який переводиться в режим dfu підтяжкою одної ноги. Для 8-ногого контроллера 3 ноги віддати для програмування це по багатому wink

Ну 2 з них - UART, як і в ардуіні. Атмегу ж теж можна хоч по ISP, хоч одним проводом по debugWIRE прошивати, але не всі хотять додаткові провода, хотять бутлоадер і аплоад з IDE. В деяких випадках так зручніше.
Колись хотів детально розібратись, які там є доступні варіанти прошивки окрім SWIO, але руки не дійшли. З WCH-LinkE запрацювало, цього було достатньо. Але надибав такий опис: WCH CH32V003 Factory Bootloader - The Missing Manual.

jokeer
2026-07-27 09:27:51

Follow this document to flash the USART IAP boot-loader using WCH-LinkE hardware

Няп тут про bootloader,  який переводиться в режим dfu підтяжкою одної ноги. Для 8-ногого контроллера 3 ноги віддати для програмування це по багатому wink можна, звичайно, вивернутись, вкрутити резисторів.. але wch-linke все одно потрібен.

Підвал форуму