Отладка микроконтроллеров STM8 в Linux, сборка toolchain для STM8

разделы: STM8 , дата: 4 октября 2017г.

До недавнего времени отладка микроконтроллеров STM8 в Linux была невозможна, для этого приходилось использовать Windows, сталкиваясь при этом с ограничениями проприетарного ПО. Например, даже в COSMIC STM8, где формально сняли ограничение на размер кода, при копировании виртуальной машины слетает лицензионный ключ, и его приходится запрашивать заново.

Однако популярность микроконтроллеров STM8, как альтернативы STM32 Cortex-M0, продолжает расти, и нашлись таки светлые головы, которые собрали патчсет для сборки тулчейна STM8.

    Для начала, решим что нам нужно для отладки микроконтроллера:
  • Компилятор с возможностью выдавать ELF файл, а не только голый Intel Hex;
  • Собственно сам отладчик GDB;
  • Сервер для отладчика, который будет обеспечивать связь GDB с микроконтроллером.

В качестве компилятора будем использовать пропатченный SDCC, в качестве сервера OpenOCD, а отладчик GDB придется собирать из binutils.

На главной странице проекта излагаются краткие инструкции по сборке тулчейна:

export PREFIX=

To download, patch and configure:

./patch_binutils.sh
./configure_binutils.sh

./patch_sdcc.sh
./configure_sdcc.sh

Until stm8 openocd official binaries are available:

./patch_openocd.sh
./configure_openocd.sh

Когда я в первый раз увидел это, я не очень понял что к чему. Я бы предпочел скачать исходники и собрать их вместо того чтобы что-то патчить, поэтому далее я опишу краткую инструкцию по сборке тулчейна.

1)Сборка toolchain для STM8

По сборке тулчейна для Ubuntu Linux есть видео на youtube: STM8 Microcontroller Dev Debug Toolchain for Linux. Оно на английском, но можно включить субтитры, и лично мне все понятно, хотя учил я немецкий. В видео показано как установить зависимости для сборки пакетов, эта тема никак не затрагивается в официальном HowTo. Проблемы с зависимостями имеются и в других дистрибутивах и как их решать я не могу предположить, т.к. friendly-user дистрибутивы оказываются совсем не friendly, когда пытаешься в них что скомпилировать. Я буду пользоваться Slackware GNU/Linux в которой, как в старые добрые времена, весь пользовательский софт собирается из исходников, и проблем с зависимостями там нет, потому что этот дистрибутив заточен на то, чтобы самостоятельно все собирать все из исходников, и опять же самостоятельно все опакечивать.

Ок, приступим. Сначала нужно скачать патчсет:

После распаковки архива видим содержимое:

palladium:~/Downloads/stm8-binutils-gdb-sources: ls -l 
итого 36
-rwxr-x--- 1 flanker users 5164 май 25 23:19 README.txt
drwxr-x--- 2 flanker users  140 май 25 23:19 binutils_patches
-rwxr-x--- 1 flanker users  108 май 25 23:19 clean_repos.sh
-rwxr-x--- 1 flanker users  242 май 25 23:19 configure_binutils.sh
-rwxr-x--- 1 flanker users  111 май 25 23:19 configure_openocd.sh
-rwxr-x--- 1 flanker users  467 май 25 23:19 configure_sdcc.sh
drwxr-xr-x 2 flanker users  180 май 25 23:19 openocd_patches
-rwxr-x--- 1 flanker users  181 май 25 23:19 patch_binutils.sh
-rwxr-x--- 1 flanker users  247 май 25 23:19 patch_openocd.sh
-rwxr-x--- 1 flanker users  236 май 25 23:19 patch_sdcc.sh
drwxr-x--- 2 flanker users  140 май 25 23:19 sdcc_patches

Здесь имеется три директории с наборами патчей для binutils, openocd и sdcc. И имеется по паре шелл-скриптов для каждого патчсета: для скачивания исходников, применения к ним своего набора патчей, и конфигурирования опций сборки программ.

Для примера, заглянем в содержимое patch_binutils.sh:

#!/bin/sh
git clone --depth 1 --branch gdb-7.12.1-release -- git://sourceware.org/git/binutils-gdb.git
for f in ./binutils_patches/*.patch
do
patch -N -p 1 -d binutils-gdb <$f
done

Этот скрипт скачивает исходники binutils и затем патчит их. Запускаем скрипт на исполнение:

palladium:~/Downloads/stm8-binutils-gdb-sources: sh ./patch_binutils.sh 
Клонирование в «binutils-gdb»…
remote: Counting objects: 28140, done.
remote: Compressing objects: 100% (23120/23120), done.
remote: Total 28140 (delta 7148), reused 17496 (delta 4107)
Получение объектов: 100% (28140/28140), 51.79 MiB | 2.30 MiB/s, готово.
Определение изменений: 100% (7148/7148), готово.
Примечание: переход на «59b102452f0bdab7a9b19d9fdbb8ce5253f0ce9f».

Вы сейчас в состоянии «отделённого HEAD». Вы можете осмотреться, сделать
экспериментальные изменения и закоммитить их, также вы можете отменить
изменения любых коммитов в этом состоянии не затрагивая любые ветки и
не переходя на них.

Если вы хотите создать новую ветку и сохранить свои коммиты, то вы
можете сделать это (сейчас или позже) вызвав команду checkout снова,
но с параметром -b. Например:

  git checkout -b <имя-новой-ветки>

Распаковка файлов: 100% (28345/28345), готово.
patching file bfd/Makefile.am
patching file bfd/Makefile.in
patching file bfd/archures.c
patching file bfd/bfd-in2.h
patching file bfd/config.bfd
patching file bfd/configure
patching file bfd/configure.ac
patching file bfd/cpu-stm8.c
patching file bfd/cpu-stm8.h
patching file bfd/elf32-stm8.c
patching file bfd/elfcode.h
patching file bfd/libbfd.h
patching file bfd/reloc.c
patching file bfd/targets.c
patching file config.sub
patching file gas/Makefile.am
patching file gas/Makefile.in
patching file gas/config/tc-stm8.c
patching file gas/config/tc-stm8.h
patching file gas/configure.tgt
patching file gdb/configure.tgt
patching file gdb/stm8-tdep.c
patching file include/dis-asm.h
patching file include/elf/stm8.h
patching file include/opcode/stm8.h
patching file ld/Makefile.am
patching file ld/Makefile.in
patching file ld/configure.tgt
patching file ld/emulparams/elf32stm8.sh
patching file ld/scripttempl/elfstm8.sc
patching file opcodes/Makefile.am
patching file opcodes/Makefile.in
patching file opcodes/configure
patching file opcodes/configure.ac
patching file opcodes/disassemble.c
patching file opcodes/stm8-dis.c
patching file opcodes/stm8-opc.c
patching file gdb/infcmd.c
patching file gdb/remote.c
patching file gas/config/tc-stm8.c
patching file gdb/stm8-tdep.c

Все отлично. Перед конфигурацией в официальном HowTo рекомендуется установить переменную окружения PREFIX, и задать ей каталог в которой будет установлен отладчик gdb. Я эту переменную задавать не буду, т.к. по умолчанию выбирается каталог /usr/local/ и меня это устраивает. Хотя, в моем случае префикс можно было бы поменять на /usr т.к. я буду binutils еще "опакечивать", а пакеты можно ставить прямо в /usr.

Следующий скрипт который следует запустить, это configure_binutils.sh. Его содержание такое:

#!/bin/sh
cd binutils-gdb
if [ x$HOST=x"" ]; then
  _HOST=$(./config.guess)
else
  _HOST=$HOST
fi
if [ x$PREFIX != x"" ]; then
  _PREFIX="-prefix=$PREFIX"
fi

./configure --host=$_HOST --target=stm8-none-elf32 $_PREFIX --program-prefix=stm8-

Запускаем его на выполнение:

palladium:~/Downloads/stm8-binutils-gdb-sources: sh configure_binutils.sh
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... stm8-none-elf32
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking whether ln works... yes
checking whether ln -s works... yes
checking for a sed that does not truncate output... /usr/bin/sed
checking for gawk... gawk
checking for x86_64-pc-linux-gnu-gcc... no
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for x86_64-pc-linux-gnu-g++... no
checking for x86_64-pc-linux-gnu-c++... no
checking for x86_64-pc-linux-gnu-gpp... no
checking for x86_64-pc-linux-gnu-aCC... no
checking for x86_64-pc-linux-gnu-CC... no
checking for x86_64-pc-linux-gnu-cxx... no
checking for x86_64-pc-linux-gnu-cc++... no
checking for x86_64-pc-linux-gnu-cl.exe... no
checking for x86_64-pc-linux-gnu-FCC... no
checking for x86_64-pc-linux-gnu-KCC... no
checking for x86_64-pc-linux-gnu-RCC... no
checking for x86_64-pc-linux-gnu-xlC_r... no
checking for x86_64-pc-linux-gnu-xlC... no
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking whether g++ accepts -static-libstdc++ -static-libgcc... yes
checking for x86_64-pc-linux-gnu-gnatbind... no
checking for gnatbind... no
checking for x86_64-pc-linux-gnu-gnatmake... no
checking for gnatmake... no
checking whether compiler driver understands Ada... no
checking how to compare bootstrapped objects... cmp --ignore-initial=16 $$f1 $$f2
checking for objdir... .libs
checking for isl 0.16, 0.15, or deprecated 0.14... no
recommended isl version is 0.16 or 0.15, the minimum required isl version 0.14 is deprecated
checking for isl 0.16 or 0.15... no
checking for default BUILD_CONFIG... 
checking for --enable-vtable-verify... no
checking for bison... bison -y
checking for bison... bison
checking for gm4... no
checking for gnum4... no
checking for m4... m4
checking for flex... flex
checking for flex... flex
checking for makeinfo... makeinfo
checking for expect... expect
checking for runtest... no
checking for x86_64-pc-linux-gnu-ar... no
checking for ar... ar
checking for x86_64-pc-linux-gnu-as... no
checking for as... as
checking for x86_64-pc-linux-gnu-dlltool... no
checking for dlltool... dlltool
checking for ld... (cached) /usr/lib64/gcc/x86_64-slackware-linux/7.1.0/../../../../x86_64-slackware-linux/bin/ld
checking for x86_64-pc-linux-gnu-ld... (cached) /usr/lib64/gcc/x86_64-slackware-linux/7.1.0/../../../../x86_64-slackware-linux/bin/ld
checking for x86_64-pc-linux-gnu-lipo... no
checking for lipo... no
checking for x86_64-pc-linux-gnu-nm... no
checking for nm... nm
checking for x86_64-pc-linux-gnu-ranlib... no
checking for ranlib... ranlib
checking for x86_64-pc-linux-gnu-strip... no
checking for strip... strip
checking for x86_64-pc-linux-gnu-windres... no
checking for windres... windres
checking for x86_64-pc-linux-gnu-windmc... no
checking for windmc... windmc
checking for x86_64-pc-linux-gnu-objcopy... no
checking for objcopy... objcopy
checking for x86_64-pc-linux-gnu-objdump... no
checking for objdump... objdump
checking for x86_64-pc-linux-gnu-readelf... no
checking for readelf... readelf
checking for stm8-none-elf32-cc... no
checking for stm8-none-elf32-gcc... no
checking for stm8-none-elf32-c++... no
checking for stm8-none-elf32-g++... no
checking for stm8-none-elf32-cxx... no
checking for stm8-none-elf32-gxx... no
checking for stm8-none-elf32-gcc... no
checking for stm8-none-elf32-gcj... no
checking for stm8-none-elf32-gfortran... no
checking for stm8-none-elf32-gccgo... no
checking for stm8-none-elf32-ar... no
checking for stm8-none-elf32-as... no
checking for stm8-none-elf32-dlltool... no
checking for stm8-none-elf32-ld... no
checking for stm8-none-elf32-lipo... no
checking for stm8-none-elf32-nm... no
checking for stm8-none-elf32-objcopy... no
checking for stm8-none-elf32-objdump... no
checking for stm8-none-elf32-ranlib... no
checking for stm8-none-elf32-readelf... no
checking for stm8-none-elf32-strip... no
checking for stm8-none-elf32-windres... no
checking for stm8-none-elf32-windmc... no
checking where to find the target ar... just compiled
checking where to find the target as... just compiled
checking where to find the target cc... pre-installed
checking where to find the target c++... pre-installed
checking where to find the target c++ for libstdc++... pre-installed
checking where to find the target dlltool... just compiled
checking where to find the target gcc... pre-installed
checking where to find the target gcj... pre-installed
checking where to find the target gfortran... pre-installed
checking where to find the target gccgo... pre-installed
checking where to find the target ld... just compiled
checking where to find the target lipo... pre-installed
checking where to find the target nm... just compiled
checking where to find the target objcopy... just compiled
checking where to find the target objdump... just compiled
checking where to find the target ranlib... just compiled
checking where to find the target readelf... just compiled
checking where to find the target strip... just compiled
checking where to find the target windres... just compiled
checking where to find the target windmc... just compiled
checking whether to enable maintainer-specific portions of Makefiles... no
configure: creating ./config.status
config.status: creating Makefile

После чего нужно зайти в каталог с binutils и запустить сборку командой make:

$ cd binutils-gdb
$ make

После завершения сборки следует установить собранный пакет командой:

$ make install

Но в моем случае, т.к. я собираюсь собирать пакет, я установлю собранную программу в отдельный каталог:

$ mkdir /tmp/stm8-binutils
$ make install DESTDIR=/tmp/stm8-binutils

Проверяем:

$ tree /tmp/stm8-binutils/usr/local/bin/
/tmp/stm8-binutils/usr/local/bin/
├── stm8-addr2line
├── stm8-ar
├── stm8-as
├── stm8-c++filt
├── stm8-elfedit
├── stm8-gdb
├── stm8-gprof
├── stm8-ld
├── stm8-ld.bfd
├── stm8-nm
├── stm8-objcopy
├── stm8-objdump
├── stm8-ranlib
├── stm8-readelf
├── stm8-size
├── stm8-strings
└── stm8-strip

0 directories, 17 files

Команды создания пакета относятся только к Slackware-based дистрибутивам:

$ cd /tmp/stm8-binutilds
$ /sbin/makepkg -l y -c n /tmp/binutils_stm8-7.12.1-x86_64-my_1.tgz

Вуаля, и на выходе я имею готовый пакет с отладчиком gdb для stm8!

Пакеты sdcc и openocd собираются аналогичным образом, в упомянутом выше видео показана сборка всех трёх программных пакетов, но я томить не буду.

2) Отладка микроконтроллеров STM8 в Linux

2a) Отладка микроконтроллера STM8S103F3P6

Для начала работы, кроме упомянутых gdb, openocd и sdcc, должен быть установлен stm8flash и udev правила для st-link v2. На всякий случай приведу свой набор правил:

/etc/udev/rules.d/49-stlinkv1.rules

# stm32 discovery boards, with onboard st/linkv1
# ie, STM32VL

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", \
    MODE:="0666", \
    SYMLINK+="stlinkv1_%n"

# If you share your linux system with other users, or just don't like the
# idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with
# GROUP:="somegroupname" and mange access using standard unix groups.

/etc/udev/rules.d/49-stlinkv2-1.rules

# stm32 nucleo boards, with onboard st/linkv2-1
# ie, STM32F0, STM32F4.
# STM32VL has st/linkv1, which is quite different

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \
    MODE:="0666", \
    SYMLINK+="stlinkv2-1_%n"

# If you share your linux system with other users, or just don't like the
# idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with
# GROUP:="somegroupname" and mange access using standard unix groups.

/etc/udev/rules.d/49-stlinkv2.rules

# stm32 discovery boards, with onboard st/linkv2
# ie, STM32L, STM32F4.
# STM32VL has st/linkv1, which is quite different

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", \
    MODE:="0666", \
    SYMLINK+="stlinkv2_%n"

# If you share your linux system with other users, or just don't like the
# idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with
# GROUP:="somegroupname" and mange access using standard unix groups.

Испытовать будем на микроконтроллерах stm8s103f3p6 и stm8l151c8t6.

плата с микроконтроллером stm8s103f3p6

Для stm8s103f3p6 создадим новый каталог проекта и поместим туда main.c такого содержания:

// Blink for stm8s103f3p6
#define PB_ODR *(unsigned char*)0x5005
#define PB_DDR *(unsigned char*)0x5007
#define PB_CR1 *(unsigned char*)0x5008

#define P5 5
#define LED P5

static void delay(unsigned int t)
{
    while(t--);
}

int main( void )
{
    // GPIO setup
    PB_DDR|=(1<<LED);
    PB_CR1|=(1<<LED);
    // main loop
    for(;;){
        PB_ODR ^= (1<<LED);
        delay(60000);
    }
}

Компилируем:

$ sdcc -mstm8 ./main.c

Смотрим список поддерживаемых флешером чипов:

$ stm8flash -l
stlux???a stm8af526? stm8af528? stm8af52a? stm8af6213 stm8af6223 stm8af6223a stm8af6226 stm8af624? stm8af6266 stm8af6268 stm8af6269 stm8af628? stm8af62a? stm8al313? stm8al314? stm8al316? stm8al3l4? stm8al3l6? stm8l051f3 stm8l052c6 stm8l052r8 stm8l101f1 stm8l101?2 stm8l101?3 stm8l151?2 stm8l151?3 stm8l151?4 stm8l151?6 stm8l151?8 stm8l152?4 stm8l152?6 stm8l152?8 stm8l162?8 stm8s003?3 stm8s005?6 stm8s007c8 stm8s103f2 stm8s103?3 stm8s105?4 stm8s105?6 stm8s207c8 stm8s207cb stm8s207k8 stm8s207m8 stm8s207mb stm8s207r8 stm8s207rb stm8s207s8 stm8s207sb stm8s207?6 stm8s208c6 stm8s208s6 stm8s208?8 stm8s208?b stm8s903?3 stm8splnb1 stm8tl5??4 stnrg???a 

Прошиваем:

$ stm8flash -c stlinkv2 -p stm8s103f3 -w ./main.ihx 
Determine FLASH area
Writing Intel hex file 211 bytes at 0x8000... OK
Bytes written: 211

Если все было сделано как надо, то зеленый светодиод на плате начнет часто мигать.

На странице проекта тулчейна приводятся следующие инструкции по использованию:

USAGE EXAMPLES

Compiling with sdcc and debug info:

sdcc -mstm8 led.c --out-fmt-elf --all-callee-saves --debug --verbose --stack-auto --fverbose-asm  --float-reent --no-peep

launch openocd in a second shell:

openocd.exe -f interface/stlink-v1.cfg -f target/stm8s105.cfg -c "init" -c "reset halt"


or if you will be using stlink-v2:

openocd.exe -f interface/stlink-v2.cfg -f target/stm8s105.cfg -c "init" -c "reset halt"

or if you prefer the vanilla configuration (for medium size flash stm8s)

openocd.exe -f interface/stlink-v2.cfg -f target/stm8.cfg -c "init" -c "reset halt"

Currently config files for stm8s003, stm8s105 and stm8l152 are available. Feel free to submit new configuration files to
the stm8-binutils-gdb discussion forum.

Then start gdb:

stm8-gdb test.elf --tui
start

or if you prefer to load manually:

stm8-gdb test.elf --tui
target extended-remote localhost:3333
load
break main
continue

Ок, предполетный инструктаж прошли, очищаем директорию проекта:

$ rm main.??? main.??
удалён 'main.asm'
удалён 'main.cdb'
удалён 'main.ihx'
удалён 'main.lst'
удалён 'main.map'
удалён 'main.rel'
удалён 'main.rst'
удалён 'main.sym'
удалён 'main.lk'

Компилируем в ELF:

$ sdcc -mstm8 ./main.c --out-fmt-elf --all-callee-saves --debug --verbose --stack-auto --fverbose-asm  --float-reent --no-peep
sdcc: Calling preprocessor...
sdcc: sdcpp -nostdinc -Wall -std=c11 -obj-ext=.rel -D_FP_=4 -D__SDCC_STACK_AUTO -D__SDCC_CHAR_UNSIGNED -D__SDCC_INT_LONG_REENT -D__SDCC_FLOAT_REENT -D__SDCC_ALL_CALLEE_SAVES -D__SDCC=3_6_0 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=6 -D__SDCC_VERSION_PATCH=0 -DSDCC=360 -D__SDCC_REVISION=9615 -D__SDCC_stm8 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem /usr/local/bin/../share/sdcc/include/stm8 -isystem /usr/local/share/sdcc/include/stm8 -isystem /usr/local/bin/../share/sdcc/include -isystem /usr/local/share/sdcc/include  ./main.c 
sdcc: Generating code...
sdcc: Calling assembler...
sdcc: sdasstm8 -plosgffwy "main.asm"
sdcc: Calling linker...
sdcc: sdldstm8 -nf "main.lk"

Смотрим, что получилось:

$ ls -l
итого 136
-rw-r--r-- 1 flanker users  8360 окт  4 10:39 main.asm
-rw-r--r-- 1 flanker users   397 окт  4 09:57 main.c
-rw-r--r-- 1 flanker users    43 окт  4 10:39 main.cdb
-rw-r--r-- 1 flanker users  4917 окт  4 10:39 main.elf
-rw-r--r-- 1 flanker users   154 окт  4 10:39 main.lk
-rw-r--r-- 1 flanker users 29160 окт  4 10:39 main.lst
-rw-r--r-- 1 flanker users 14371 окт  4 10:39 main.map
-rw-r--r-- 1 flanker users  8888 окт  4 10:39 main.rel
-rw-r--r-- 1 flanker users 29160 окт  4 10:39 main.rst
-rw-r--r-- 1 flanker users 12242 окт  4 10:39 main.sym

Как видно у нас появился elf-файл и пропал ihx. Теоретически, из эльфа можно получить файл прошивки:

$ stm8-objcopy -O ihex main.elf main.ihx

Но если попытаться прошить такой файл, то получим ошибку:

$ stm8flash -c stlinkv2 -p stm8s103f3  -w ./main.ihx 
Determine FLASH area
Writing Intel hex file Address 0001 is out of range at line 1

В прошивке указан неверный старовый адрес 0х0001 вместо должного 0x8000. Это можно поправить если в текстовом редакторе исправить адрес в первой строке файла:

:03000100000000FC

на:

:03800000000000FC

После этого прошивка нормально прошивается и работает, по крайней мере, в случае этого простого примера. Но захочется ли этом заниматься постоянно? Да и размер прошивки изменился...

Ок, немного отвлеклись. Посмотрим для каких чипов stm8 у нас имеются конфигурации openocd:

$ ls -l /usr/local/share/openocd/scripts/target/stm8*
-rw-r--r-- 1 flanker users 1842 окт  2 21:30 /usr/local/share/openocd/scripts/target/stm8.cfg
-rw-r--r-- 1 flanker users  226 окт  2 21:30 /usr/local/share/openocd/scripts/target/stm8l152.cfg
-rw-r--r-- 1 flanker users  183 окт  2 21:30 /usr/local/share/openocd/scripts/target/stm8s003.cfg
-rw-r--r-- 1 flanker users  144 окт  2 21:30 /usr/local/share/openocd/scripts/target/stm8s105.cfg

Конфигурация для stm8s003 должна подойти для 103-го чипа. Пробуем:

openocd -f interface/stlink-v2.cfg -f target/stm8s003.cfg -c "init" -c "reset halt"
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: RCLK - adaptive
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 0 kHz, using 5 kHz
Info : Unable to match requested speed 0 kHz, using 5 kHz
Info : RCLK (adaptive clock speed) not supported - fallback to 5 kHz
Info : STLINK v2 JTAG v27 API v2 SWIM v6 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.256802
target halted due to debug-request, pc: 0x00008000

Если светодиод на st-link начал часто мигать, а на плате stm8103f3 наоборот остановилась, значит связь установилась. В другом окне запускаем отладчик:

stm8-gdb ./main.elf --tui

Получаем такое окно:

жмем Enter, и перед нами появляется текст исходной программы:

Далее, следуя инструкции, последовательно: 1)подключаемся к серверу - openocd:

(gdb) target extended-remote localhost:3333
Remote debugging using localhost:3333   
0x00008000 in ?? ()

2) загружаем прошивку в микроконтроллер:

(gdb) load
Loading section SSEG, size 0x3 lma 0x1
Loading section HOME, size 0x83 lma 0x8000
Loading section GSINIT, size 0x1e lma 0x8083
Loading section GSFINAL, size 0x3 lma 0x80a1
Loading section CODE, size 0x60 lma 0x80a4 
Start address 0x8083, load size 263
Transfer rate: 295 bytes/sec, 52 bytes/write.

3) ставим точку остановки:

(gdb) break main
Breakpoint 1 at 0x80d3

4) запускаем прошивку на выполнение:

(gdb) continue
Continuing.

Breakpoint 1, main () at ./main.c:17

После последней программы, курсор текущей команды установится на первую строку функции main():

Начать процесс трассировки можно вводя несколько раз команду next или просто n, и если зеленый светодиод на плате будет последовательно загораться и гаснуть, значит все в порядке, отладка работает.

2б) Отладка микроконтроллеров L-серии

плата с микроконтроллером stm8l151c8t6

Для примера возьму чип stm8l151c8. Blink для него ничем не отличается от варианта для stm8s103f3:

// blink for stm8l151c8t6
// compile: sdcc -mstm8 ./main.c
#define PB_ODR *(unsigned char*)0x5005
#define PB_DDR *(unsigned char*)0x5007
#define PB_CR1 *(unsigned char*)0x5008

#define P1 0x01
#define LED P1

static void delay(unsigned int t)
{
    while(t--);
}

int main(){
    // GPIO setup
    PB_DDR|=(1<<LED);
    PB_CR1|=(1<<LED);
    // main loop
    for(;;){
        PB_ODR ^= (1<<LED);
        delay(60000);
    }
}

Светодиод можно было оставить и на пятом пине, но пин PB0 мне удобнее, она располагается на 25-ой ножке микросхемы, т.е. он крайний.

Компиляция в elf-файла идентична предыдущему варианту:

sdcc -mstm8 ./main.c --out-fmt-elf --all-callee-saves --debug --verbose --stack-auto --fverbose-asm  --float-reent --no-peep

В openocd есть только один профиль для L-серии, по-моему он должен подходить для всех "эльек":

openocd -f interface/stlink-v2.cfg -f target/stm8l152.cfg -c "init" -c "reset halt"

В остальном все абсолютно идентично предыдущему случаю.

Остальная работа с gdb типична как для stm32 или msp430, а по тулчейну для stm8 мне больше добавить нечего.

поделиться: