![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Софт установили, начнём играться с платой. План будет следующий:
В каждой плате присутствует начальный загрузчик, который умеет загружать новую прошивку. Его можно активировать при включении. Если вынуть кабель USB из платы, нажать кнопку BOOTSEL и при нажатой кнопке вставить кабель, то загрузчик перейдёт в специальный режим, когда он прикидывается диском для компьютера. Диск имеет имя RPI-RP2. На нём находятся два файла с информацией о плате:
Также в этот режиме можно пользоваться утилитой picotool. Она общается с бутлоадером через его протокол, и умеет много полезных вещей. Например, выдать подробную информацию о прошитой программе:
Чтобы повторить прошивку после изменения программы, надо опять вынуть кабель USB, нажать кнопку BOOTSEL и при нажатой кнопке вставить кабель.
Польза от такого подхода тройная:

Можно просто припаять проводки, а можно обойтись макетной платой. У меня получилась такая конфигурация:

Теперь прошьём плату слева, которая станет адаптером отладки. Прошивку для неё (picoprobe) мы приготовили в предыдущий раз. Подключите кабель USB к левой плате, предварительно нажав кнопку BOOTSEL. После этого скопируйте на неё прошивку:
Командная строка слишком громоздкая получается, поэтому для себя я сварганил более удобный шелл-скрипт: pico-prog.
В отдельном окошке запускаем openocd в режиме сервера. Он обеспечивает интерфейс между GDB и USB-адаптером picoprobe:
При вызове отладчика нужно дать ему тот самый ELF-файл, который вы прошивали в плату:
Мультиплатформенный отладчик на маке называется просто gdb, а на Линуксе gdb-multiarch. Устанавливается он, соответственно, на маке:
- Как загрузить прошивку в плату: два способа
- Blink: прошиваем через бутлоадер
- Прилаживаем адаптер picoprobe
- Hello_serial: прошиваем через picoprobe
- Подсоединяем консольный порт
- Сбрасываем плату из командной строки
- Подключаем отладчик
Два способа загрузить прошивку в плату
Загрузить прошивку в плату можно двумя способами: через бутлоадер или через отладочный порт.В каждой плате присутствует начальный загрузчик, который умеет загружать новую прошивку. Его можно активировать при включении. Если вынуть кабель USB из платы, нажать кнопку BOOTSEL и при нажатой кнопке вставить кабель, то загрузчик перейдёт в специальный режим, когда он прикидывается диском для компьютера. Диск имеет имя RPI-RP2. На нём находятся два файла с информацией о плате:
Но самое главное: если записать на этот диск файл в формате *.uf2, то он будет прошит в память процессора как программа для выполнения. Этот способ хорош тем, что не требует никаких дополнительных прибамбасов. Но нужно иметь возможность физически нажать кнопку на плате и передёрнуть питание.$ ls -l /Volumes/RPI-RP2
total 1
-rwxrwxrwx 1 vak staff 241 Sep 5 2008 INDEX.HTM
-rwxrwxrwx 1 vak staff 62 Sep 5 2008 INFO_UF2.TXT
$ cat /Volumes/RPI-RP2/INFO_UF2.TXT
UF2 Bootloader v3.0
Model: Raspberry Pi RP2
Board-ID: RPI-RP2
Также в этот режиме можно пользоваться утилитой picotool. Она общается с бутлоадером через его протокол, и умеет много полезных вещей. Например, выдать подробную информацию о прошитой программе:
Есть и другой способ прошивки: через отладочный порт SWD. Это три контакта на торце платы, противоположном разъёму USB. Но требуется отдельный адаптер: про него я расскажу ниже. Также будет нужна утилита openocd.$ picotool info -a
Program Information
name: hello_serial
web site: https://github.com/raspberrypi/pico-examples/tree/HEAD/hello_world/serial
features: UART stdin / stdout
binary start: 0x10000000
binary end: 0x100053fc
Fixed Pin Information
0: UART0 TX
1: UART0 RX
Build Information
sdk version: 1.3.1
pico_board: pico
boot2_name: boot2_w25q080
build date: May 20 2022
build attributes: Debug
Device Information
flash size: 2048K
ROM version: 3
Blink: прошиваем через бутлоадер
Опробуем прошивку через бутлоадер. Загрузим в плату пример blink: он мигает светодиодом. Его мы скомпилировали в прошлый раз:Определите, где у вас в файловой системе смонтировался диск платы Pico. У меня это /Volumes/RPI-RP2. Скопируйте бинарный файл программы (в формате uf2) на этот диск:$ cd ~/Project/Pico/pico-examples/build/blink
$ ls -l blink.uf2
-rw-r--r-- 1 vak staff 41984 May 21 00:39 blink.uf2
Обратите внимание на светодиод на плате: он должен начать мигать. Диск при этом RPI-RP2 автоматически отмонтируется.cp blink.uf2 /Volumes/RPI-RP2
Чтобы повторить прошивку после изменения программы, надо опять вынуть кабель USB, нажать кнопку BOOTSEL и при нажатой кнопке вставить кабель.
Прилаживаем адаптер picoprobe
Дальнейшие шаги возможны, если у вас имеется не одна, а _две_ платы Raspberry Pico. Хитрость в том, что одну плату мы превратим в USB-адаптер для прошивки и отладки второй платы. Подробности смотрите в статье: Raspberry Pi Pico and RP2040 - C/C++ Part 2: Debugging with VS Code.Польза от такого подхода тройная:
- Можно прошивать плату без необходимости нажимать кнопку и передёргивать питание.
- Можно отлаживать программу на плате с помощью отладчика GDB.
- Можно подключаться к серийному порту UART0 платы.

Можно просто припаять проводки, а можно обойтись макетной платой. У меня получилась такая конфигурация:

Теперь прошьём плату слева, которая станет адаптером отладки. Прошивку для неё (picoprobe) мы приготовили в предыдущий раз. Подключите кабель USB к левой плате, предварительно нажав кнопку BOOTSEL. После этого скопируйте на неё прошивку:
Светодиод должен загореться. Адаптер готов к работе. На вашем компьютере появится новый виртуальный последовательный порт. В моём случае это /dev/tty.usbmodem14301. Он нам будет нужен ниже.cd ~/Project/Pico/picoprobe/build
cp picoprobe.uf2 /Volumes/RPI-RP2
Hello_serial: прошиваем через picoprobe
Теперь мы можем прошить вторую плату (справа) через наш свежеиспечённый адаптер. Возьмём другой пример, который выдаёт текстовое сообщение на серийный порт. Делается это таким образом:Процесс прошивки должен завершиться сообщениями:cd ~/Project/Pico/pico-examples/build/hello_world/serial
openocd -f interface/picoprobe.cfg -f target/rp2040.cfg -c "program hello_serial.elf verify reset exit"
Заметьте: мы используем утилиту openocd, и прошиваем бинарный файл в формате elf (а не uf2, как с бутлоадером).** Programming Started **
Info : RP2040 B0 Flash Probe: 2097152 bytes @10000000, in 512 sectors
...
** Programming Finished **
** Verify Started **
...
** Verified OK **
** Resetting Target **
...
Командная строка слишком громоздкая получается, поэтому для себя я сварганил более удобный шелл-скрипт: pico-prog.
Подсоединяем консольный порт
Пример hello_serial, который мы прошили в плату, выдаёт сообщения в последовательный порт UART0, подсоединенный к контактам GP0 и GP1 на плате. Адаптер picoprobe даёт возможность подсоединиться к этому порту через USB. Нужен какой-то эмулятор терминала: я рекомендую minicom. Его можно установить на маке командой:На Линуксеbrew install minicom
Подсоединяемся к серийному порту Pico:sudo apt-get install minicom
В вашем случае имя устройства может быть другим. На Линуксе обычно /dev/ttyACM0. На экране должно повторяться сообщение:minicom -D /dev/tty.usbmodem14301 -b 115200
Hello, world!
Hello, world!
Hello, world!
...
Сбрасываем плату из командной строки
Если есть необходимость сбросить программу на плате (послав виртуальный сигнал Reset), это можно сделать через адаптер отладки:Для удобства я засунул эту команду в шелл-скрипт: pico-reset.openocd -f interface/picoprobe.cfg -f target/rp2040.cfg -c init -c reset -c exit
Подключаем отладчик
Но конечно, самая мощная функция адаптера picoprobe - отладка через GDB. Методика отладки детально описана в документации Raspberry Pico, а здесь я покажу, как происходит подключение к плате.В отдельном окошке запускаем openocd в режиме сервера. Он обеспечивает интерфейс между GDB и USB-адаптером picoprobe:
При вызове openocd выдаст сообщение:openocd -f interface/picoprobe.cfg -f target/rp2040.cfg
То есть он принимает вызовы от отладчика GDB на локальном порту TCP с указанным номером.Info : accepting 'gdb' connection on tcp/3333
При вызове отладчика нужно дать ему тот самый ELF-файл, который вы прошивали в плату:
Ну и так далее.$ gdb hello_serial.elf GNU gdb (GDB) 12.1 ... Reading symbols from hello_serial.elf... (gdb) target extended-remote :3333 Remote debugging using :3333 warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread time_reached (t=...) at pico-sdk/src/rp2_common/hardware_timer/include/hardware/timer.h:116 116 uint32_t hi_target = (uint32_t)(target << 32u); (gdb) bt #0 time_reached (t=...) at pico-sdk/src/rp2_common/hardware_timer/include/hardware/timer.h:116 #1 sleep_until (t=...) at pico-sdk/src/common/pico_time/time.c:361 #2 0x10000e78 in sleep_us (us=>optimized out<) at pico-sdk/src/common/pico_time/include/pico/time.h:102 #3 0x10000eb2 in sleep_ms (ms=ms@entry=1000) at pico-sdk/src/common/pico_time/time.c:393 #4 0x1000032a in main () at pico-examples/hello_world/serial/hello_serial.c:15 (gdb) i reg r0 0xf480f 1001487 r1 0x1e8a44 2001476 r2 0x0 0 r3 0xd0000128 -805306072 r4 0xf4239 999993 r5 0x0 0 r6 0x1e8a4a 2001482 r7 0x0 0 r8 0xffffffff -1 r9 0xffffffff -1 r10 0xffffffff -1 r11 0xffffffff -1 r12 0x20041f60 537141088 sp 0x20041fa8 0x20041fa8 lr 0x100010ab 268439723 pc 0x10000e0c 0x10000e0c >sleep_until+192< xPSR 0x61000000 1627389952 msp 0x20041fa8 0x20041fa8 psp 0xfffffffc 0xfffffffc primask 0x0 0 basepri 0x0 0 faultmask 0x0 0 control 0x0 0 (gdb) monitor resume (gdb) _
Мультиплатформенный отладчик на маке называется просто gdb, а на Линуксе gdb-multiarch. Устанавливается он, соответственно, на маке:
На Линуксе:brew install gdb
На этом подготовка инструментария для Pico закончена. В следующий раз займёмся изучением архитектуры процессора Cortext-M0+, в частности переключением контекста.sudo apt-get install gdb-multiarch
no subject
Date: 2022-05-23 11:42 (UTC)`screen /dev/tty.usbmodem14301 115200`
no subject
Date: 2022-05-23 19:10 (UTC)no subject
Date: 2022-05-24 01:11 (UTC)no subject
Date: 2022-05-24 01:57 (UTC)no subject
Date: 2022-05-24 02:31 (UTC)no subject
Date: 2022-05-24 04:42 (UTC)Но кермит стал пропадать из пакетов...