Я пытаюсь выяснить, как использовать функцию printf для печати на последовательный порт.
Моя текущая настройка - это сгенерированный код STM32CubeMX и SystemWorkbench32 с платой обнаружения STM32F407 .
В stdio.h я вижу, что прототип printf определяется как:
int _EXFUN(printf, (const char *__restrict, ...)
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
Что это означает? Где точное местоположение определения этой функции? Каков будет общий смысл выяснить, как использовать эту функцию для вывода?
microcontroller
c
stm32
stm32f4
stm32cubemx
user505160
источник
источник
_write()
функция - это то, что я сделал. Подробности в моем ответе ниже.Ответы:
Я получил первый метод с этой страницы, работающий на моем STM32F072.
http://www.openstm32.org/forumthread1055
Как указано там,
Я использовал STM32CubeMX для настройки USART1 (
huart1
) в качестве последовательного порта. Поскольку я только хотелprintf()
, мне нужно было только заполнить_write()
функцию, что я и сделал следующим образом. Это условно содержится вsyscalls.c
.источник
_EXFUN - это макрос, вероятно, содержащий некоторые интересные директивы, которые сообщают компилятору, что он должен проверить строку формата на предмет совместимости с printf и убедиться, что аргументы printf соответствуют строке формата.
Чтобы узнать, как использовать printf, я предлагаю страницу руководства и немного больше гуглят. Напишите несколько простых программ на C, которые используют printf, и запустите их на своем компьютере, прежде чем пытаться перейти на использование его на микро.
Интересным вопросом будет «куда пойдет напечатанный текст?». В Unix-подобных системах он выходит в стандартное состояние, но у микроконтроллера такого нет. Библиотеки отладки CMSIS могут отправлять текст printf на порт отладки для полухостинга arm, т. Е. В ваш сеанс gdb или openocd, но я понятия не имею, что сделает SystemWorkbench32.
Если вы не работаете в отладчике, возможно, имеет смысл использовать sprintf для форматирования строк, которые вы хотите напечатать, а затем отправлять эти строки через последовательный порт или на любой дисплей, который вы могли подключить.
Осторожно: printf и связанный с ним код очень велики. Это, вероятно, не имеет большого значения для 32F407, но это реальная проблема на устройствах с небольшой вспышкой.
источник
__cdecl
чтобы избежать ошибок. По крайней мере на newlib / cygwin, _EXFUN используется только для установки__cdecl
.Ответ @ AdamHaun - это все, что вам нужно, с помощью
sprintf()
которого легко создать строку и затем отправить ее. Но если вы действительно хотитеprintf()
свою собственную функцию, то Variable Argument Functions (va_list) является подходящим вариантом.С
va_list
пользовательской функцией печати выглядит следующим образом:Пример использования:
Обратите внимание, что хотя это решение предоставляет вам удобную функцию для использования, но оно медленнее, чем отправка необработанных данных или использование даже
sprintf()
. С большим количеством данных я думаю, что этого будет недостаточно.Другой вариант, и, возможно, лучший вариант, это использовать ST-Link, SWD-отладчик вместе с ST-Link Utility. И используйте Printf через SWO viewer , вот руководство по ST-Link Utility , соответствующая часть начинается на странице 31.
источник
printf () является (обычно) частью стандартной библиотеки языка C. Если ваша версия библиотеки поставляется с исходным кодом, вы можете найти реализацию там.
Вероятно, было бы проще использовать sprintf () для генерации строки, а затем использовать другую функцию для отправки строки через последовательный порт. Таким образом, все сложное форматирование сделано для вас, и вам не нужно взламывать стандартную библиотеку.
источник
Для тех, кто борется, добавьте следующее в syscalls.c:
Подключитесь к вашему COM-порту через замазку, и все будет хорошо.
источник
Если вы хотите использовать другой подход и не хотите перезаписывать функции или объявлять свои, вы можете просто использовать их
snprintf
для достижения той же цели. Но это не так элегантно.источник