|
newlib stdio, перенаправление ввода/вывода |
|
|
|
Nov 2 2010, 15:14
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Добрый вечер. Разбираюсь с newlib; сейчас попытался перенаправить стандартный вывод, и столкнулся с такой проблемой: переопределил функции: Код _ssize_t _read_r(struct _reent *r, int file, void *ptr, size_t len); _ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); (и прочие низкоуровневые вызовы для newlib) и вызвал printf(), после чего обнаружил, что _write_r не вызывается. Попробовал так же вместо указанных функций переопределять лишь Код int _read (int file, char *ptr, int len); int _write(int file,char *ptr,int len); результат тот же. Ключи линкера: Код LIBS = -lstdc++ -lc -lgcc -lm LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref $(LIBS) -T$(TARGET).ld В качестве референса использовал этот проект: http://www.siwawi.arubi.uni-kl.de/avr_proj...ects/#gcc_stdioToolchain из последней сборки yagarto. Итак, вопрос: как переопределить стандартный ввод/вывод, и что я делаю не так? upd: версия newlib: 1.18
Сообщение отредактировал Spym - Nov 2 2010, 19:25
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Nov 2 2010, 19:52
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Spym @ Nov 2 2010, 20:14)  Ключи линкера: Код LIBS = -lstdc++ -lc -lgcc -lm LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref $(LIBS) -T$(TARGET).ld Покажите $(TARGET).ld чтоль  Я пробовал переопределять Код int _write(int file, char *buffer, unsigned int count) , работало.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 2 2010, 19:55
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Цитата(AHTOXA @ Nov 2 2010, 22:52)  Покажите $(TARGET).ld чтоль  Запросто.
gcc_freertos_test.ld.txt ( 4.59 килобайт )
Кол-во скачиваний: 253
Сообщение отредактировал Spym - Nov 2 2010, 19:56
|
|
|
|
|
Nov 2 2010, 20:18
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Хм. Не вижу криминала. Вспоминаю, что читал что-то такое про yagarto... Ага, нашёл: Цитата This is because codesourcery build newlib (c library) with --disable-newlib-supplied-syscalls whereas yagarto builds the default system calls. Так что, если это правда, то в yagarto - никак. Берите CodeSourcery, или сборки от klen-а, если есть склонность к экспериментам
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 2 2010, 20:29
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Цитата(AHTOXA @ Nov 2 2010, 23:18)  Так что, если это правда, то в yagarto - никак. Цитата(AHTOXA @ Nov 2 2010, 22:52)  Я пробовал переопределять Код int _write(int file, char *buffer, unsigned int count) , работало. То есть, вы не с yagarto эксперементировали. Ок, благодарю за содействие, сейчас посмотрю, какие есть альтернативы. upd:Посмотрел Вашу ссылку: Цитата Also yagarto is a arm-elf toolchain, and the codesourcery is a arm-eabi toolchain. Это же неверное утверждение. Кстати, тогда вопрос по Yagarto: как там определён стандартный ввод/вывод?
Сообщение отредактировал Spym - Nov 2 2010, 20:36
|
|
|
|
|
Nov 2 2010, 22:40
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Прикрутил вместо yagarto/arm-none-eabi сборку kgp-arm-eabi_x86_32_HALLOWEEN_EDITIION от Klen, результат тот же: stdout не перенаправляется. Я озадачен.
Сообщение отредактировал Spym - Nov 2 2010, 22:41
|
|
|
|
|
Nov 3 2010, 05:55
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Меня немного смущает слово "перенаправляется". Что Вы имеете в виду? printf() выполняет вывод в поток stdout (при наличии перечисленных в документации системных вызовов, а именно, close, fstat, isatty, lseek, read, sbrk, write). Таким образом, перенаправление stdout - это просто присваивание ему другого значения. Может у Вас просто в stdout что-то не то? Покажите, как Вы открываете поток, что присваиваете stdout...
Сообщение отредактировал alx2 - Nov 3 2010, 05:56
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Nov 3 2010, 10:09
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Spym @ Nov 3 2010, 01:29)  Цитата Also yagarto is a arm-elf toolchain, and the codesourcery is a arm-eabi toolchain. Это же неверное утверждение. Так год-то прошлый. Сейчас yagarto перешло на arm-eabi, да. Цитата(Spym @ Nov 3 2010, 03:40)  Прикрутил вместо yagarto/arm-none-eabi сборку kgp-arm-eabi_x86_32_HALLOWEEN_EDITIION от Klen, результат тот же: stdout не перенаправляется. Очень странно. Посмотрите ещё вот в этой теме, я там приаттачивал тестовый проект с printf. Он для cortex-m3, но может поможет. ----- Ещё мысль пришла. Если у вас C++ проект, то функции надо объявлять как extern "C": Код extern "C" int _write(int file, char *buffer, unsigned int count) { for (i=0; i<count; ++i) { lcd_put_char(*buffer++); } return count; }
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 3 2010, 13:22
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Цитата(alx2 @ Nov 3 2010, 08:55)  ...перенаправление stdout - это просто присваивание ему другого значения. Может у Вас просто в stdout что-то не то? Покажите, как Вы открываете поток, что присваиваете stdout... stdout ничего не присваиваю, т.к. достаточно переопределить низкоуровневые функции, которые Вы уже перечислили, разве нет? При входе в main видно, что stdout уже существует (см. ниже). Цитата(AHTOXA @ Nov 3 2010, 13:09)  Очень странно. Посмотрите ещё вот в этой теме, я там приаттачивал тестовый проект с printf. Он для cortex-m3, но может поможет. Посмотрел, принципиальных отличий не нашел. Цитата(AHTOXA @ Nov 3 2010, 13:09)  Ещё мысль пришла. Если у вас C++ проект, то функции надо объявлять как extern "C": Эти функции определены в syscalls.c, всё в порядке. Да, я забыл упомянуть, что при вызове printf управление всё же передавалось в: Код int _fstat_r(struct _reent *r, int file, struct stat *st); int _isatty_r(struct _reent *r, int file); Но вместо _write_r затем уходило в __swrite. Попробовал сейчас перед вызовом printf() руками определить указатель на _write_r(): Код stdout->_write = reinterpret_cast<typeof(stdout->_write)>(_write_r); Пока я этого не сделал, stdout->_write указывал на NULL. Вызвал printf(), смотрю значение stdout->_write - теперь указывает на __swrite.
|
|
|
|
|
Nov 3 2010, 14:53
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Я прозрел; как выяснилось, вывод корректно работает даже в Yagarto. Из первого вызова printf вызывается __sinit, где происходит инициализация stdout/stdin/stderr. После этого stdout->_write указывает на __swrite, откуда как раз и происходит вызов _write_r, а отсюда, в свою очередь, вызывется пользовательский _write; но и _write_r можно переопределить. Моя проблема заключалась в том, что вызов printf, где строка формата не содержит управляющих последовательностей: Код printf("Something string"); в newlib не приводит к выводу этой строки в stdout; после замены на: Код printf("%s", "Just string\r\n"); все ВНЕЗАПНО заработало. Почему так? Ведь в этом случае в stdout должно было уйти "Something string".
|
|
|
|
|
Nov 3 2010, 18:01
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Spym @ Nov 3 2010, 19:53)  Я прозрел; как выяснилось, вывод корректно работает даже в Yagarto. Это радует, значит Yagarto потихоньку движется в сторону, так сказать, общепринятых тенденций. И eabi, и --disable-newlib-supplied-syscalls. Больше тулзов, хороших и разных!  Цитата Почему так? Мне кажется, что это кривизна newlib. Хотя неясно, чем отличается _write из вашего файла syscalls.c от _write дефолтного.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 3 2010, 18:37
|

Группа: Участник
Сообщений: 13
Регистрация: 20-10-07
Пользователь №: 31 533

|
Цитата(Spym @ Nov 3 2010, 17:53)  Почему так? Ведь в этом случае в stdout должно было уйти "Something string". обычная буферизация. попробуйте так Код printf("Something string"); fflush(stdout);
|
|
|
|
|
Nov 3 2010, 19:00
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(Spym @ Nov 3 2010, 01:40)  Прикрутил вместо yagarto/arm-none-eabi сборку kgp-arm-eabi_x86_32_HALLOWEEN_EDITIION от Klen, результат тот же: stdout не перенаправляется. Я озадачен. давайте прикрутим вместе. но после праздникрв пролетариата - я уже пикирую. не думаю что есть проблемы где есть исходный код  всех форумчан с празгиком, история нашего народа однако...
|
|
|
|
|
Nov 4 2010, 11:51
|

Участник

Группа: Участник
Сообщений: 71
Регистрация: 24-02-08
Из: Москва
Пользователь №: 35 348

|
Цитата(r301 @ Nov 3 2010, 21:37)  обычная буферизация. попробуйте так Код printf("Something string"); fflush(stdout); Действительно. Интересно, как я могу управлять размером буфера? И почему использование управляющих последовательностей не приводит к буферизации вывода? Цитата(klen @ Nov 3 2010, 22:00)  давайте прикрутим вместе. В прикручивании как раз проблем не возникло - достаточно указать в PATH путь к toolchain же. Да, кстати, при -O0 ваш KGP собрал 160кБ кода против 202кБ -O0 yagarto (-lc -lm -lgcc -lstdc++) при прочих равных, на первый взгляд всё работало. Хотя это сейчас мало о чем говорит, да и полученный код я не тестировал пока толком.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|