DAP — новый способ реализации printf() для STM32M в Keil
Keil очень хорошо оснащен для отладки. Поддержка многих отладчиков, включая распространенный STLink, реализованная "из коробки" возможность перенаправления printf() через UART или SWV ( Serial Wire Viewer ).
Отладка через UART
Способ вывода отладочной информации через UART - проверенный и надежный. Описаний этого метода немало в интернете. Лично мне понравился один из вариантов, очень хорошо и доступно ( для начинающих ) описанный на этом ресурсе.
Отладка через ITM
Также, есть и более новый способ вывода отладочной информации - через ITM. При этом, также, используется SWV.

Видео с разбором настройки Keil для работы с SWV и ITM
Особенности отладки микроконтроллеров STM32 серий M0, L0, G0
К огромному сожалению, с контроллерами серий M0, L0, G0 способы отладки черезSWV и ITM не работают, из-за отсутствия в них интерфейса SWV.

* Иллюстрации из CubeMX в сатье размещены исключительно для визуализации функционала контроллеров серий М3 и М0, и не имеют отношения к указанным выше возможносnям отладки в Keil, которые хорошо и так описаны в других местах, и не являются целью данной статьи.
У отладки через UART также есть серьезный недостаток - иногда немногочисленные ноги популярных микроконтроллеров серий M0, L0, G0, предназначенные для UART, в конкретном проекте могут оказаться уже заняты.
Отладка через DAP
Лично для меня оказался сюрпризом еще один, совсем новый, способ, описаний которого я почему-то раньше не встречал. Заключается он в выводе отладочной информации c помощью функции printf() через Event Recorder и DAP ( Debug Access Port ). Event Recorder - новый функционал в Keil Vision, и доступен для отладки программ сразу после установки. Этот метод может быть применен для отладки контроллеров ARM не только продвинутых серий М3. М4, М7, но и М0, М0+, L0 . Оне не использует SWV .
Для настройки среды программирования Keil для работы в режиме отладки через Event Recorder и DAP необходимо выполнить следующие действия:
1. Открыть менеджер окружения, и поставить галочки напротив Compiler->Ivent recorder -> DAP и Compiler -> I/O -> STDOUT -> EVR

Отмеченные позиции должны быть в зеленом поле. Если нет, нажать кнопку Resolve.
2. После выполненных действий, в окно проекта, в группу Compiler, автоматически будут добавлены файлы retarget_io.c and Event Recorder.c
3. Подключите файл стандартной библиотеки stdio.h и EventRecorder.h к программе, путем добавления строк #include "stdio.h" и #include "EventRecorder.h" в начале файла программы ( обычно, это main.c ).
4. В тексте программы, сразу после int main(), разместить функцию инициализации EVR - EventRecorderInitialize( EventRecordAll, 1 );

5. Разместить, в нужных местах программы, функцию вывода отладочной информации. Как пример - printf( "The LED is blinking!!! %d\n", myVar ); Перекомпилировать программу.
6. Запустить отладку Debug -> Start/Stop debug session и запустить программу RUN
* Естественно, ST Link должен быть настроен и подключен к компьютеру, а устройство подключено к отладчику.
** Важный нюанс - пункты Trace Use Core Clock в настройках отладчика включать не нужно! Это приведет к ошибкам при запуске отладки.
7. Открываем окно View -> Serial Windows -> Debug printf() Viewer. Получаем отладочную информацию)

* Я не проверял, но, скорее всего, через это же окно можно получать информацию об отладке при работе через UART. но без преобразователя сигналов TTL, и отдельной терминальной программы. Проблема занятых ножек МК, к сожалению, останется.