Оглавление
Два типа сборки: управляемая (GUI) и не управляемая (make).
Ссылки проекта (Referring Project)
Отключение ненужных предупреждений (Treat Linker Warnings as Errors).
Размещение с помощью malloc (Page Size Allocation for Malloc).
Удаление «мертвого» кода (Dead Code Removal).
Подключение дополнительных объектных файлов (Include Additional Object Files).
Создать новый.(Generate a New Linker Script)
Изменение существующего линкер-скрипта (Modify Existing Linker Script).
Размещение переменных по определенному адресу (Place variables at specific addresses).
Закрепление кода в произвольном месте.
Сообщения компилятора. Разбор частых событий.
Установка STLink Utility – внешняя утилита отладки.
Переустановка отлодочных инструментов при сбоях в отладке.
Восстановление отладочной конфигурации STLink Utility из расшареных файлов настроек.
Останов, пересбор, запуск — в один кликл. Цепочка: остановить, пересобрать и перезапустить.
Отладка без загрузки. Присоединение к работающей прошивке МК.
Окно со значениями переменных.
Окно дизасемблера. Disassemble listing
Немного важной теории.
Проекты бывают управляемые и не управляемые. Управляемые полностью настраиваются в GUI — всяческих окнах настроек. Не управляемые должны получать настойку из make-файлов. Настройки сборки проекта, относящиеся как к проектам в управляемом режиме, так и к проектам в неуправляемом режиме собираются на панели Target Settings.
@C/C++ Build – Setting - Target Settings
$CONFIGURING THE PROJECT’S BUILD SETTINGS
Любые изменения на вкладке Target Settings будут отражаться в настройках создания проекта, так же будут причиной нового линкер скрипта. Однако библиотеки, заголовки и прочее требуется добавлять вручную. Каждый проект может иметь любое количество конфигураций построения. Это удобно, например, для сжатия или защиты кода в релизной конфигурации. А вот отлаживаться с такой настройкой не всегда возможно.
Открыть проект.
Запуск существующего проекта производится двойным щелчком на .project и действительно открывает, предварительно требуя указать где размещается или где разместить (если нет) воркспейс. Обратите внимание, что если обозреватель файлов настроен так, чтобы не отображать расширения файлов, в списке файлов появятся два безымянных значка, представляющих файлы .project и .cproject. Использование файлов без имени файла является печальным наследием инфраструктуры ECLIPSE ™ (дословная цитата).
$Using an existing project
make-файл можно создать из проекта.
$ Creating a Makefile Project From Existing Code
elf файл откуда появляется
Основным результатом сборки является .elf файл. Этот файл используется для создания файлов прошивок типа .hex и .bin. В каком-то смысле, .elf это тот же бинарник что и .hex, но в формате unix. В частности, STLinkUtility его шить не хочет. Из вторичных целей его бытия, .elf используется для создания красивых полосок и полезных циферок в Build Analiser, Static Stack Analiser и возможно каких то других. В сухом остатке имеем равенство - «сделать прошивку = сделать .elf файл».
$Create a New Build Configuration for Release
.h файлы внешних библиотек не пересканируются,
так как считается что они сторонние и меняться не будут.
$ Include Libraries
Уровень оптимизации.
Его можно задать как
отдельно для функций или блоков кода так для файлов или проекта в
целом. Выбрать вид оптимизации для блока кода, можно применив такую
конструкцию
void __attribute__((optimize("O1")))
myFunc(unsigned char data) {
// The code the needs to have the –O1 optimizing
где O1 — уровень «без оптимизации»
У меня это один из самых спасительных действий в случае глюков отладки. А именно:
Отключить оптимизацию для файла
поставить в целевой функции выражение - __attribute__((optimize("O1"))) .
$Compiler Optimization
Версия toolchane когда проектом пользуются из разных версий Atollic-a.
При работе с системой контроля версий в команде вариант - «Fixed TrueSTUDIO version» рекомендуется для проекта. Таким образом, все разработчики будут использовать один и тот же набор инструментов, даже если используются разные версии Atollic TrueSTUDIO.
$Changing Toolchain Version
Подключение внешних библиотек.
Тут описано как ссылаться на либы созданные в других проектах.
Порядок включения библиотеки в проект. Правой мышью нажать на проекте в который библиотека должна быть включена:
Properties - C/C++ Build — Settings.
Tool Settings-tab - C Linker, Libraries.
О сборке и пересборке.
Различия этих процессов.
При сборке среда пытается прилинковать только измененные файлы и файлы связанные с измененными. Этим и объясняется то, что иногда не верно собирается в этом режиме — видимо не все связи отслеживается. При пересборке все файлы линкуются — собираются независимо от того какие менялись.
Вывод: можно всегда пользоваться сборкой, пока нормально собирается.
После изменения файлов внешней программой требуется пересборка (опытным путем).
Параллельная сборка сильно снижает время сборки.
Количество потоков нужно делать равным количеству ядер на компьютере. Проверил это утверждение — получил 1.5-кратный рост скорости построения.
$Enable Parallel Build
Debug и Release — почти стандарт любой среды разработки. На эти два режима можно подвесить разную логику работы сборщиков. Не использую его, так как обычно требуются десятки разновидностей или еще большее количество сочетаний разновидностей отладочных и «боевых» режимов работы прошивок. Наверняка можно скриптами пробросить состояние Debug / Release внутрь исходников, но пока не пробовал.
Безголовая сборка.
Безголовая сборка нужна для того, чтобы автоматически собирать проекты без участия IDE.
$Headless Build
Логи сборок.
Нужны тогда, когда не понятно что происходит. Или когда нужно отвлечься от мрачных мыслей о нелегкой доле разработчика).
"D:\PROJECTS\Atollic\01 CEmbProj\.metadata\.plugins\org.eclipse.cdt.ui\CEmbPrj.build.log"
лог последней сборки — то, что видим в окне консоль
"D:\PROJECTS\Atollic\01 CEmbProj\.metadata\.plugins\org.eclipse.cdt.ui\global-build.log"
логи всех сборок
Отдельно замечу, что некоторые ошибки линкера не выводятся в окно Problems и спасает только окно Console с его логами. Познавательно и захватывающе временами туда заглядывать.
$Logging
Для каждого файла можно посмотреть размер его объектного файла
$The Build Size
Сборка одного файла.
Полезная штука — сборка одного файла. В IAR постоянно этим пользовался.
$Building One File
.h файлы внешних библиотек не пересканируются,
так как считается что они сторонние и меняться не будут.
Место, начало, размер блоков памяти, функций, переменных.
Этот вид получается из .elf файла. Если в той же папке лежит еще и .map файл то и из него. Этом случае будет дополнительная информация о чем то.
В анализаторе есть две вкладки.
Memory Regions. Общая инфа, размер свободных и несвободных блоков и типов памяти
Memory Details – тут можно найти размер и положение каждой функции (зеленые значки) и переменной (синий значок). Стандартная маркировка объектов Attolic описание которой я пока не отыскал. Даже объектный файл тут можно оценить если выбрать.
Чтобы обновить данные в виде, можно кликнуть любой файл и сбилдить проект или выбрать .ela или .o файл в проекте. Инфа не обновляется для PC проектов.
$Build Analyzer
Иерархия вызовов (Стек).
Можно щелкать на функции и смотреть иерархию вызовов Ctrl+Alt+H. Клевая удобная фича.
Добавлять сторонние библиотеки лучше на вкладке References. Тогда будут верно работать фишки вроде построения иерархии вызовов, поиска и прочее.
$Referring Project
Отключение предупреждений.
Можно задавить сообщения предупреждений. Полезно, если приходится мириться с хорошо известным, но трудно убираемым предупреждением. Конечно, такое никому не нравится и это плохо, но порой — необходимо.
Размер «куска» для malloc.
Размер «куска» в байтах для функции malloc(). т.е. когда вызываем эту функцию и передаем ей число, то выделяется место именно под N * «размер куска». Доступны, например, 128 или 4096 байт на один «кусок».
Штатно он удаляется. По умолчанию галка выставлена и происходит игнорирование не задействованного кода. Мертвый — тот, что есть в исходниках, но не задействован по разным причинам. Например из-за не активных дефайнов.
Подключение внешних объектников без сырцов.
Можно использовать внешние объектные файлы, без использования исходного кода для них, созданные в других средах. Пока не приходилось использовать, но хорошо что такое есть.
Связь .ld и .startup.
Содержимое линкер скрипта и его связь со стартап файлом — отдельный большой вопрос. Пометим, что создать его можно, как указано в этой главе руководства - Generate a New Linker Script.
.ld как, когда создается.
Линкер файл может быть создан двумя путями:
При смене камня спросят об этом и создадут.
Можно принудительно, как в пункте выше.
Размещаем переменные по произвольным адресам.
Первым шагом при размещении переменных по произвольным адресам памяти является создание нового региона памяти с помощью линкер скрипта .ld. Посмотрите пример скрипта содержащего как раз такие регионы
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
Новый регион можно добавить поправив этот файл. В нашем примере мы добавляем MYVARS регион.
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
MYVARS (x) : ORIGIN = 0x08010000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
Заметим! Переменные и функции не могут быть размещены в одной и той же области памяти.
Теперь добавим секцию памяти. Размещаем следующий кусок далее внизу в скрипте, между .data{..} и .bss{..} секциями.
.myvars :
{
*(.myvars*);
} > MYVARS
Это вызовы линкера для размещения всех секций с названиями .myvars* из входящих в .nyvars выходной секции в регионе MYVARS, которые определят стартовый адрес памяти 0x8010000.
Теперь переменные нужно положить в регион.
Чтобы быть абсолютно уверенным, что порядок останется неизменным, даже если они распределены по нескольким файлам, добавьте каждую переменную в отдельный раздел.
Карта порядка переменных в линкер скрипте.
Вот пример, код может быть такой:
__attribute__((section(".myvars.VERSION_NUMBER"))) uint32_tVERSION_NUMBER;
__attribute__((section(".myvars.CRC"))) uint32_t CRC;
__attribute__((section(".myvars.BUILD_ID"))) uint16_t BUILD_ID;
__attribute__((section(".myvars.OTHER_VAR"))) uint8_t OTHER_VAR;
А затем решить порядок в линкер скрипте при добавлении определенных именованных секций типа:
.myvars :
{
*(.myvars.VERSION_NUMBER)
*(.myvars.CRC)
*(.myvars.BUILD_ID)
*(.myvars*);
} > MYVARS
Формируется по умолчанию. Вроде бы считается более полным, чем elf.
В блоке Linker script and memory map содержится разбивка памяти для каждого файла.
Разберем на примере.
.text 0x00000000 0xf080
*(.text*)
.text 0x00000000 0x310 /cygdrive/c/Program Files (x86)/FTDI/FT90x Toolchain/Toolchain/tools/bin/../lib/gcc/ft32-elf/5.0.0/crti-hw.o
0x00000000 _start
0x00000090 _exithook
0x000000fc _exit
0x0000030c nullvector
0x00000310 __gxx_personality_sj0
.text.StaticFunc
0x00000310 0x20 ./main.o
.text.GlobalFunc
0x00000330 0x20 ./main.o
0x00000330 GlobalFunc
.text.main 0x00000350 0x44 ./main.o
0x00000350 main
.text.StaticFunc
0x00000394 0x38 ./test.o
.text.Test 0x000003cc 0x14 ./test.o
0x000003cc Test
....
.text начинается с 0x00000000 и длина его 0xF080 байт.
Первый модуль — это файл ctri-hw.o и в нем есть 4 глобальные функции.
Команда --ffunction-sections удостоверится что каждая функция скомпилирована в раздельные секции, которые позволяют линкеру (ia -Wl,--gc-sections) позднее удалить некоторые функции которые не используются.
Некоторая информация о .data и .bss сегментах. Однако статичные символы в bss сегментах отсутствуют.
Разместить новый .ld файл в папке проекта.
C C++ Build Settings – Tool Settings – C Linker – General
в CUBE IDE: C C++ Build - Settings – Tool Settings(вкладка) – MCU GSS Linker - General – Linker Script
В поле Linker Skript заменить название файла на новый
Проект должен скомпилиться и в окне Build Andliser нужно удостоверится в изменениях если таковые были в .ld скрипте
Закрепляет код в определенной части памяти программ.
Поможет, например, при работе с загрузчиком. Опция компилятора fPIE включает этот режим. Удостоверится в указателе стека.
$Position Independent Code
сообщение |
перевод |
Значение и описание. Когда может возникнуть. |
Безобидные но иногда докучные |
||
unused variable 'NameOfFunction' |
Переменная не используется |
Не всегда это так. Использование значит считывание из переменной куда нибудь. Иногда используется в цикле |
Problems encountered during text search. |
Проблемы, возникшие во время текстового поиска. |
Обычно в расшифровке повторяющиеся причины File 'name_file.c' has been skipped, problem while reading: для решения можно попробовать
|
|
|
|
опасные |
||
expected declaration or statement at end of input |
ожидаемое объявление или утверждение в конце ввода ожидается? |
|
object has been skipped, problem while reading |
объект был пропущен, проблема при чтении |
|
implicit declaration of function 'NameOfFunction' |
неявное объявление функции NameOfFoonctions |
Если в файл где сделан вызов функции не проброшена связь от самой функции. Т.е. в этом исходнике не видно определения этой функции и |
incompatible types when assigning to type 'SPI_HandleTypeDef * {aka struct __SPI_HandleTypeDef *}' from type 'SPIDrv {aka struct <anonymous>}' Driver.c |
несовместимые типы при назначении этого типа.(он же вот какой тип) из типа |
Когда тупо пытаемся присвоить значение из переменной одного типа в переменную другого типа. |
passing argument 1 of 'SPIInit' from incompatible pointer type [-Wincompatible-pointer-types] my_main.c |
передача аргумента 1 'SPIInit' из несовместимого типа указателя [-Wincompatible-pointer-types] my_main.c / имя_какойто_папки / Users / Src / common line 102 Проблема C / C ++ |
|
passing argument 2 of [NameFunction] discards 'const' qualifier from pointer target type |
при передаче аргумента 2 из функции такой то отбрасывается квалификатор 'const' из целевого типа указателя |
|
|
|
|
уровень опасности не ясен |
||
assignment makes integer from pointer without a cast |
присвоение делает целое число из указателя без приведения |
|
критичные — без них не собирается |
||
error: duplicate case value |
Повторяющееся значение кейса |
|
pointer targets in passing argument 2 of 'strcat' differ in signedness |
вt целевые объекты указателя при передаче аргумента 2
'strcat' отличаются по знаку |
передавался тип uint8_t в параметр с типом char[] |
При любом намеке на некорректную работу точек останова и подобных проб леммах, рекомендую выставлять у функций подобный атрибут.
__attribute__((optimize("O0")))
В больших проектах перестает работать предустановленный отладчик. В Atollic-e это правило работает всегда, только мелкие проекты удается отлаживать. В CUBE IDE не сталкивался с подобными проблемами.
Вам придется отлаживаться через этот способ в сколько нибудь серьезном проекте. Если начинаются глюки при отладке, следует попробовать перейти на отладку в этом режиме.
Добавить внешний инструмент.
Run - External Tools - External Tools Configurations — Program – New (или двойной левый клик )
указать пути к вреншему отладчику и к elf файлу
C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility\ST-LINK_CLI.exe
C:\Program Files (x86)\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility
-c ID=0 SWD UR LPM -P ${workspace_loc}\Proj\Debug\Proj.hex
\путь\Debug\имя.hex — путь начиная с папки проекта
Задать формат выходного файла
Project - Build settings — C/C++ Build - Settings - Tool Settings, Other - Output format.
В CUBEIDE -> Project - Build settings — C/C++ Build - Settings - Tool Settings — MCU Post built options – Convert to Intel Hex File.
Выбрать - Intel Hex
В случае генераци из CUBEMX создать новый .elf файл. (смотреть в дополнении главу «Переустановка отлодочных инструментов при сбоях в отладке.»)
Сделать копию .elf файла и выключить загрузку в отладочной конфигурации.
Configure Debug – Embedded C/C++ Application.
Выделить существующую отладочную конфигурацию.
Заметим. Отладочная конфигурация создается например при генерации кода CUBE-ом. Либо при создании проекта в Atollic TS.
Duplicate.
Добавить _NOLoad в название.
Закомментить «load» и «monitor reset».
Создать группу запуска.
Добавить конфигурацию запуска.
Пиктограмма Configure Debug – Launch Group
– New – Add.
Откроется окно «Add Launch Configuration”
Launch Mode = run
Выделить launch конфигурацию с красным чемоданом New_configuration
Lounch Mode = run.
Post launch action = Wain until terminated
OK
появится в окне новая отладочкая конфигурация
Добавить и настроить elf скрипт.
Вкладка Launches - Add
выбрать elf который NOLOAD
Lounch Mode = debug, Post launch action = none
ОК
появится выбранный elf файл
Активировать кнопки меню.
Открыть вкладку Common и поставить галочки
Enable Display in favorites menu = Run
Enable Display in favorites menu = Debug
Click Apply
Например может понадобиться после формирования дефолтной конфигурации кубом. В этом случае создается файл формата NameProject.elf.launch — это и есть отладочная конфигурация. Она содержит настройки и ссылки на .elf файл.
Очистка.
Выйти из TS
Удалить действующий .elf файл. Для этого удалить папку Debug
Удалить файлы рабочего пространства - .settings
Удалить файлы типа имя_какойто_папки.elf.launch
Загрузить TS и удостоверится что внешние отладочные инструменты, elf файлы,
Добавление отладочной конфигурации — Embedded C/C++ Application
Configure Debug — Окно Debug Configurations – Embedded C/C++ Application
New
Добавится файл с настройками по умолчанию.
В том числе в поле C/C++ Application должен возникнуть Debug\Name.elf
При этом в папке проекта появится файл типа NameProject Debug.launch в папке .metadata/.plugins/org.eclipse.debug.core/.launches/.
Если текстовые поля вкладки Main будут пустыми.
Скомпилить проекет. Project – Browse – выбрать проект. Должны заполнится.
Можно также нажать Search Project и выбрать проект. Должен появиться путь
Если пусто поле C C++ Application
Найти .elf файл, являющийся результатом успешной компиляции. Обычно лежит в Debug
Подключив его урезав путь до вида Debug\DBGOnNuclL476.elf
Сохранение настроек в файл.
Отладочная конфигурация
Configure Debug — Окно Debug Configurations – Embedded C/C++ Application — Выбрать конфигурцию — Common
Переключить на Shared File:
Browse – Выбрать проект нажать ОК
Появится файл NAME.launch. Все файлы создаваемые при действиях описанных ниже имеют расширение - .launch
Повторить для NO_LOAD
Группа запуска
Configure Debug – Launch Group – Выбрать группу — Common
Расшарить по аналогии.
Повторить для всех подобных объектов.
Утилита
Run - External Tools - External Tools Configurations — выбрать инструмент — Common
Расшарить по аналогии.
Повторить для всех подобных объектов.
Восстановление.
Открыть воркспейс и экспортировать проект.
Удостоверится что отладочные конфигурации, конфигурации запуска и конфигурации внешних утилит в наличии на своих местах.
Однократно запустить отладки из меню Configure Debug – Launch Group – Выбрать группу — нажать Debug. После этого группа запуска появится в Debug History и можно продолжать пользоваться запуском как привык.
Эта фича нужна для того чтобы после изменений которые внесены за отладку в сырцы, одним нажатием, остановить, пересобрать и сразу запустить камень.
$Terminate, Rebuild and Re-launch
Прошивки должны точно совпадать.
Configure Debug – оба? узла открыть и закоментировать (#) в Start Scripts строки:
monitor reset, load, monitor reset, tbreak main.
Смотрим переменные.
Это окно позволяет отображать локальные и глобальные переменные, регистры и даже пользовательские выражения с участием всех этих объектов. Информация обновляется всякий раз когда отладчик приостанавливается. Можно даже отобразить группу переменных отфильтрованных по регулярным выражениям. В этом и подобных окнах, описанных ниже, можно смотреть переменые в hex, bin, dec формате. Выделяем несколько строчек с переменными и внизу в текстовом окне для них всех показывается инфа
$ Expressions
Смотрим переменные в реальном времени.
Все тоже самое что и в Expressions, с большим исключением. Выбираются значения постоянно при выполнении. От количества и сложности выражений зависит тормознутость выборки. Если верно понимаю, для этого нужна активация SWV режима.
$ Live Expressions
Смотрим локальные переменные. Список строится автоматически. Может быть удобным когда требуется смотреть локальные переменные разных функций.
$ Local Variables
В этом виде показаны регистры железа. Можно использовать фильтр по имени. Можно переключать системы счислений. Удобная маска для отображения битов. Кнопка RD активирует силовое чтение, если ReadAction атрибут активен все равно прочитает.
Содержимое и структура вида зависит от файла .svd. Чтобы все работало должен быть хороший Device File. По умолчанию он такой есть. Рекомендуют использовать самый свежий.
Так же есть Custom File. Через него можно настроить сокращенный список избранных регистров и он выведется вверху. Также можно вкрячить свое видение каких нибудь регистров, ну там битики, наверно, выделить не так как выделяет заводской .svd файл. В итоге получается невероятная гибкость для настройки отображения регистров, те кто много работает с ними непосредственно оценят эту фичу по достоинству.
$ SFRs
Точки останова делятся на железные и софтовые. Железные зависят от реализации. ARM 7/9 = 2 штуки, Cortex M = 4 для 6? штук. ST-Link GDB сервер может использовать только железные точки останова и их количество ограничено шестью.
$Breakpoints
Поставьте точку останова и правой мышью откройте свойства. Breakpoint Properties – Common. В поле Conditiotion: поставить выражения типа [название переменной] == [значение останова]
Можно использовать даже в RTOS если в его ядре есть переменная на которой можно проверять условие точки останова. Перейти можно нажав правой мышью по полосе точек останова и выбрав Breakpoint Properties
$Conditional Breakpoint
Обычно, при отладке можно ходить только по окну редактора. Для того чтобы ходить по дизассемблеру нужно нажать спецкнопку i→
$Disassembly View
Открывает окно ассемблерного кода
Окно ассемблерного кода. В нем можно отлаживаться. Сюда придется «спустится» для поиска самых тяжелых и не понятных багов проекта. Но это не страшно, ведь операторов ассемблера всего несколько десятков штук, а реально используемых — всего несколько штук.
$Disassemble/List Object and Elf Files
Представление FA помогает разработчикам определить и разрешить трудно обнаруживаемые системные сбои, возникающие когда проц переходит в состояние сбоя. FA интерпретирует информацию из вложенного контроллера прерываний MVIC в контексте определения причин происшествия.
• обращение к неправильному месту в памяти
• обращение к ячейкам памяти на смещенных границах (не понял чем отличается от предыдущего)
• выполнение неизвестной инструкции
• деление на ноль
$ Fault Analyzer
Можно производить любым HW отладчиком, правда есть два ограничения.
• Обычно в МК рам меньше флеша, поэтому всю прогу не сохранишь в нем.
• Cortex M0 Не возможно использовать прерывания когда весь код лежит в рам.
• Надо править gdb script.
$Debugging Code in RAM
Дополнительные моменты.
Частота
Частота Debug Configurations – Debugger - Core clock должна соответствовать системной частоте
узнать ее можно посмотреть содержимое SystemCoreClock
Запустить отладку
Открыть SWV Console
Для использования системного анализа и отладки в реальном времени процессоров совместимых с ARM, взаимодействуют несколько технологий. SWV последовательный проводной обзор, SWD последовательная проводная отладка и SWO последовательный проводной вывод. Эти технологии являются частью ядра отладчика ARM и будут освещены ниже.
SWD это порт отладки подобный JTAG, и позволяющий выполнять отладочные операции (запуск, останов,однократный останов), но с несколькими точками. Он заменяет разъем JTAG на 2-контактный интерфейс (один тактовый вывод и один двунаправленный вывод данных). SWD порт сам не обеспечивает трассировку в реальном времени, таким образом расширая отладочный интерфейс на 3 ноги. Сочетание ног SWD и SWO включает SWV отладку реального времени в случае ARM процессора.
Заметьте, что SWO только одна нога и это что проц легко может нафигачить столько данных что через нее не всё пролезет.
SWO нога может быть задействована в сочетании с SWD и использована процессором для отдачи данных уже в реальном времени
сообщение |
перевод |
Значение и описание. Когда может возникнуть. |
Program received signal SIGTRAP, Trace/breakpoint trap. |
|
При запуске ПО через отладку. Это описание https://stackoverflow.com/questions/9809413/program-received-signal-sigtrap-trace-breakpoint-trap оказалось правдивым. PC просто достиг некоей точки останова. Перед этим баловался с точками останова по значению в переменных.
|
Error in initializing ST-Link device. Reason: (1) Failed to connect to device. Please check power and cabling to target. |
|
При установленной защите от чтения прошивки. |
|
|
При внезапной остановке отладки, реально gdb сервер может ее продолжать. в этом случае все последующие операции с отладчиком могут приводить к глюкам. для проверки такого состоянии удостовериться что нет запущенного процесса « arm-atollic-eabi-gdb.exe» |
?
смотрим lr.
Адрес в disassembly
Флаг RCC_CSR нужно чистить т. к. он может сохранять старые значения.
Для того, чтобы понять что перезагрузка произошла по срабатыванию IWDG (да и WWDG) нужно следить за регистром Control/status register (RCC_CSR). Там есть биты IWDG RSTF (WWDG RSTF). Если он выставлен в 1, то перезагрузка произошла по нему. Чтобы его сбросить нужно в этом же регистре в бит RMVF записать 1 (как я понял, она обнуляет весь регистр).
Прочитали RCC_CSR как можно скорее после запуска, прежде чем инициализировать любое другое периферийное устройство. Сначала безопасно инициализировать ваши системные часы (что делается в SystemInit (), если вы используете библиотеки ST).
Читать можно как можно быстрее сразу после заупска, до инициализации какойто другой перифирии.
В Disassembly шагает не там где указывает что шагает в редакторе
выключить оптимизацию для файла, сделав по умолчанию, поставить для интересующей функции __attribute__((optimize("O0")))
искать логические ошибке в коде, отключая свежие куски
оттолкнуться от работающей версии
Как узнать какая каллбэк функция сохранена в переменной?
закинуть переменную в «вотч»
скопировать число из колонки Value
перейти в disassembly к такому адресу — получим первую строчку функции
Не наблюдается изменение счетчиков и подобные, хотя операторы суммирования и прочие выполняются
Выключить оптимизацию для функции
Если не по могло выключить оптимизацию для файла и для функции.
кроме выбора оптимизации
для проекта или файлов можно выбрать оптимизацию для блока кода
применив такую конструкцию:
void
__attribute__((optimize("O1"))) myFunc(unsigned char data)
{
// The code the needs to have the –O1 optimizing
v2.