92 / 19 / 3
Регистрация: 11.04.2015
Сообщений: 1,000
Записей в блоге: 1
1

Очередной раз про printf()

30.11.2023, 20:10. Показов 647. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте !

В очередной раз не работает функция printf(). Нашел, что подфункция int __io_putchar(int ch) ,необходимая для ее реализации, вызывается из функции _write(), расположенной в файле syscalls.h. Но не могу отследить деббагером выполнение этой самой функции _write(), дебаггер в нее не заходит.

Как сделать, чтобы дебаггер заходил внутрь функции _write() ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.11.2023, 20:10
Ответы с готовыми решениями:

Очередной раз ds18b20 & STM32f103c8 (решено)
Добрый день! Уважаемые форумчане, подскажите пожалуйста где я туплю, уже сил моих нет! Суть...

В очередной раз про автозаполнение
Доброго времени суток. Когда-то это делал, теперь забыл. Есть две таблицы: справочникМО и...

Компьютер несколько раз отключался после чего в очередной раз потух и больше не включался.
У меня возникла такая проблема. Компьютер несколько раз отключался после чего в очередной раз потух...

очередной вопрос про системы счисления
есть код #include <cstddef> #include <cstdio> #include <cstring> #include <cassert> #include...

19
Заблокирован
01.12.2023, 08:03 2
max_sk, ну и какая IDE?
1
92 / 19 / 3
Регистрация: 11.04.2015
Сообщений: 1,000
Записей в блоге: 1
01.12.2023, 08:28  [ТС] 3
VladimirU, STM32CubeIDE
0
315 / 184 / 44
Регистрация: 25.08.2011
Сообщений: 1,220
01.12.2023, 08:34 4
Цитата Сообщение от max_sk Посмотреть сообщение
В очередной раз не работает функция printf()
Что значит не работает??

Цитата Сообщение от max_sk Посмотреть сообщение
Как сделать, чтобы дебаггер заходил внутрь функции _write() ?
Врядли получиться так далеко копнуть. Скорее всего код лежит в какой нибудь статической библиотеке без исходников. Да и маловероятно что там будет какая то проблема требующая редактировать функционал.
1
92 / 19 / 3
Регистрация: 11.04.2015
Сообщений: 1,000
Записей в блоге: 1
01.12.2023, 08:43  [ТС] 5
Worldmaster, printf() не выводит текст на терминал PuTTY.

Я сделал перенаправление функции printf() с помощью следующего стандартного кода, который прописал у себя в файле uart.c :

C
1
2
3
4
5
6
int __io_putchar(int ch)
 {
    //uart2_write(ch);
    HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,10);
    return ch;
 }
Так вот. Когда я хочу деббагером проследить выполнение функции HAL_UART_Transmit() и ставлю на нее брейкпоинт, то в этот брейкпоинт никогда не заходит. И я не могу проверить почему printf() не выводит текст...
0
Эксперт .NET
10556 / 6483 / 1503
Регистрация: 25.05.2015
Сообщений: 19,644
Записей в блоге: 14
01.12.2023, 08:47 6
Цитата Сообщение от max_sk Посмотреть сообщение
ставлю на нее брейкпоинт, то в этот брейкпоинт никогда не заходит
Видимо, функция просто не вызывается. Если всё-таки вызываете printf, значит переопределение функции не сработало.
Можете в ассемблерном листинге посмотреть.

Цитата Сообщение от max_sk Посмотреть сообщение
Я сделал перенаправление функции printf()
Можно через snprintf выводить в заранее выделенный буфер и его отправлять в UART сразу весь.
1
315 / 184 / 44
Регистрация: 25.08.2011
Сообщений: 1,220
01.12.2023, 08:49 7
Цитата Сообщение от max_sk Посмотреть сообщение
HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,10);
А вы правильно настроили УАРТ? Скорость, биты и прочее?
А если просто сделать отправку HAL_UART_Transmit и отправить массив байт то какой результат она вернет и приходят ли данные?

УАРТ с прерыванием работает? Попробуйте замкнуть RXTX будет ли прилетать данные в приемник?

Цитата Сообщение от max_sk Посмотреть сообщение
HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,10);
Почему таймаут такой маленький? Поставьте вы побольше для уверенности 0xFFFF
1
92 / 19 / 3
Регистрация: 11.04.2015
Сообщений: 1,000
Записей в блоге: 1
01.12.2023, 08:56  [ТС] 8
Rius, почему то это перенаправление в других упражнениях работает, а в этом нет. Могу выложить код, но какие именно файлы ?

Добавлено через 5 минут
Worldmaster, если встраиваю HAL_UART_Transmit() непосредственно в код, то все работает.

Увеличение таймаута не помогло...
0
315 / 184 / 44
Регистрация: 25.08.2011
Сообщений: 1,220
01.12.2023, 09:00 9
Цитата Сообщение от max_sk Посмотреть сообщение
если встраиваю HAL_UART_Transmit() непосредственно в код, то все работает.

Так сделайте как Rius, сказал. Напишите свою функцию printf и внутри делайте буфер и scanf
1
Заблокирован
01.12.2023, 09:51 10
При компеляции IDE хоть какие нибудь предупреждения выдаёт?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
01.12.2023, 10:39 11
Цитата Сообщение от max_sk Посмотреть сообщение
Нашел, что подфункция int __io_putchar(int ch)
как узнал? Например для Keil я переделывал функцию int fputc(int ch, FILE *f)
а и еще подключал #include <stdio.h>
для
Цитата Сообщение от max_sk Посмотреть сообщение
STM32CubeIDE
не использовал printf если будет время, завтра-послезавтра, попробую

Добавлено через 1 минуту
Цитата Сообщение от VladimirU Посмотреть сообщение
компеляции
компиляции
правила п 5.2
Запрещено использовать нецензурные выражения в любом виде, оскорблять других участников форума, умышленно использовать выражения, противоречащие правилам русского языка, в том числе "олбанский" язык.
0
204 / 139 / 23
Регистрация: 26.11.2022
Сообщений: 625
01.12.2023, 12:12 12
а можно взять исходники printf которые есть специально в двух вариантах для микроконтроллеров - с поддержкой float и без (для экономеии места), и работать с этим гораздо удобнее. потому как вы сами знаете куда и что передаётся и кольцевые буферы для uart работают
0
Eddy_Em
01.12.2023, 12:21
  #13

Не по теме:

Идеальный вариант - вообще не использовать printf!

0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
03.12.2023, 11:33 14
Цитата Сообщение от ValeryS Посмотреть сообщение
если будет время, завтра-послезавтра, попробую
попробовал
почитал интернет
вот первый вариант
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...................
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "usart.h"
/* USER CODE END Includes */
..................
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
 
PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  return ch;
}
.............................................
 
 printf("La_LA_La =%2.2lf\n\r");
проект создавал с нуля для нуклео stm32f303
из настроек подключил только поддержку float для printf

Добавлено через 33 минуты
второй вариант: подмена "слабой"(weak) функции _write

C
1
2
3
4
5
6
7
8
9
10
11
12
13
int _write(int file, char *ptr, int len)
{
  (void)file;
  int DataIdx;
 
  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
 
      HAL_UART_Transmit(&huart2, (uint8_t *)ptr++, 1, HAL_MAX_DELAY);
 
  }
  return len;
}
0
204 / 139 / 23
Регистрация: 26.11.2022
Сообщений: 625
03.12.2023, 21:12 15
А где в этой реализации FIFO буферы на приём и передачу?
или скорость работы программы будет определяться скоростью uart ? ))
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
03.12.2023, 22:00 16
Aledveu, ты у кого спрашиваешь?
если у меня то скоростью uart. у меня скорость 115200
если желаешь можешь сделать и FIFO
C
1
2
3
4
      int start = DWT->CYCCNT;
      printf("La_LA_La =%2.2lf\n\r",d);
      int end1 = DWT->CYCCNT;
      printf ("tik =%d\n\r",end1-start);
скорость у меня
на реализацию printf уходит 32745 тактов с поддержкой float
и 21444 тактов без поддержки float
0
204 / 139 / 23
Регистрация: 26.11.2022
Сообщений: 625
03.12.2023, 22:21 17
ValeryS,
В предложенных вами вариантах printf будет блокирующей?
если да - то количество тактов будет определяться скоростью передачи по уарт.
соответственно даже самый мощный процессор при такой реализации превращается нечто совсем медленное, а вывод нескольких переменных вообще может нарушить нормальную работу программы.

во втором варианте вы подменяете _write
тоесть файловый ввод-вывод уже не организовать?

мне кажется такие решения больше запутывают чем объясняют как сделать хорошо.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
03.12.2023, 23:36 18
Цитата Сообщение от Aledveu Посмотреть сообщение
В предложенных вами вариантах printf будет блокирующей?
мне хватает
Цитата Сообщение от Aledveu Посмотреть сообщение
если да - то количество тактов будет определяться скоростью передачи по уарт.
"давайте решать проблемы по мере их возникновения" почему это передача usart стала блокирующей? закинул данные в регистр а дальше уже аппаратные устройства пускай передают.
никто не мешает сделать потоковую ОС(FreeRTOS)
Цитата Сообщение от Aledveu Посмотреть сообщение
во втором варианте вы подменяете _write
тоесть файловый ввод-вывод уже не организовать?
а часто в микроконтроллере нужны Файлы?
Цитата Сообщение от Aledveu Посмотреть сообщение
мне кажется такие решения больше запутывают чем объясняют как сделать хорошо.
никто не мешает сказать как "сделать хорошо"
0
204 / 139 / 23
Регистрация: 26.11.2022
Сообщений: 625
04.12.2023, 00:41 19
Цитата Сообщение от ValeryS Посмотреть сообщение
почему это передача usart стала блокирующей? закинул данные в регистр а дальше уже аппаратные устройства пускай передают.
никто не мешает сделать потоковую ОС(FreeRTOS)
типичное применение функции printf в микроконтроллере - вывести что-то на терминал. При этом обычно эта функция вызывается несколько раз подряд с разными аргументами. Если результат этой функции по одному байту записывается в регистр то приходится ждать пока каждый символ передастся и после этого записывать следующий. Использовать ПДП не получится поскольку реазизация printf обычно не содержит в памяти результат в виде строки, а если даже и содержит, то последовательный вызов нескольких printf приводит опять к ожиданию передачи предыдущей строки

правильная реализация для микроконтроллера должна быть такой :
printf -> printf_put_char (как склейка между между модулем printf и uart) -> uart_put_char -> fifo_buffer -> uart_irq_handler

собственная реализация printf без float для stm32 занимает 800 байт - так что для простых случаев можно и отказаться от стандартной библиотеки.

Цитата Сообщение от ValeryS Посмотреть сообщение
а часто в микроконтроллере нужны Файлы?
если ваше устройство работает с накопителями - то да.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,519
04.12.2023, 09:15 20
Цитата Сообщение от Aledveu Посмотреть сообщение
типичное применение функции printf в микроконтроллере
какое? типичное? а часто ли это нужно?
Цитата Сообщение от Aledveu Посмотреть сообщение
вывести что-то на терминал
а если вывести на дисплей? а если в отладочный терминал (SWO)?
Цитата Сообщение от Aledveu Посмотреть сообщение
если ваше устройство работает с накопителями - то да.
В общем "Сам себе придумал проблемы, сам героически их преодолеваешь"
и какое отношение все эти размышления имеют к вопросу TC
Цитата Сообщение от max_sk Посмотреть сообщение
В очередной раз не работает функция printf().
...
Как сделать, чтобы дебаггер заходил внутрь функции _write() ?
0
04.12.2023, 09:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.12.2023, 09:15
Помогаю со студенческими работами здесь

очередной вопрос про ключевики в титле
есть два запроса: запчасти мерседес запчасти mercedes оба запроса...

очередной вопрос про системы счисления
есть код #include &lt;cstddef&gt; #include &lt;cstdio&gt; #include &lt;cstring&gt; #include &lt;cassert&gt; #include...

Очередной Сабж Про Dialog Box
Есть довольно простая задача: Есть кнопка, по клику на нее должно открываться окно (DialogBox) с...

Union в очередной раз
Здравствуйте! Решил на практике попробовать этот самый union. Программа должна выводить число...

очередной раз hook
Доброго времени суток! Я новенький в WinAPI, но все же мне интересно, хоть и тяжело. Мое желание -...

в очередной раз рекурсия
функция f(n) определяется рекурсивно f(2*n)=f(n),f(2*n+1)=f(n)+f(n+1),f(0)=0,f(1)=1, Написать...

Деревья в очередной раз
Здравствуйте, есть вот такое задание. Создайте предикат, переписывающий дерево в двоичный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru