Spym 0 2 ноября, 2010 Опубликовано 2 ноября, 2010 (изменено) · Жалоба Добрый вечер. Разбираюсь с 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_stdio Toolchain из последней сборки yagarto. Итак, вопрос: как переопределить стандартный ввод/вывод, и что я делаю не так? upd: версия newlib: 1.18 Изменено 2 ноября, 2010 пользователем Spym Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 2 ноября, 2010 Опубликовано 2 ноября, 2010 · Жалоба Попробую издалека: Поднимите руки, кто использует yagarto и printf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 2 ноября, 2010 Опубликовано 2 ноября, 2010 · Жалоба Ключи линкера: 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) , работало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 2 ноября, 2010 Опубликовано 2 ноября, 2010 (изменено) · Жалоба Покажите $(TARGET).ld чтоль:) Запросто. gcc_freertos_test.ld.txt Изменено 2 ноября, 2010 пользователем Spym Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 2 ноября, 2010 Опубликовано 2 ноября, 2010 · Жалоба Хм. Не вижу криминала. Вспоминаю, что читал что-то такое про yagarto... Ага, нашёл: This is because codesourcery build newlib (c library) with --disable-newlib-supplied-syscalls whereas yagarto builds the default system calls. Так что, если это правда, то в yagarto - никак. Берите CodeSourcery, или сборки от klen-а, если есть склонность к экспериментам:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 2 ноября, 2010 Опубликовано 2 ноября, 2010 (изменено) · Жалоба Так что, если это правда, то в yagarto - никак. Я пробовал переопределять 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: как там определён стандартный ввод/вывод? Изменено 2 ноября, 2010 пользователем Spym Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 2 ноября, 2010 Опубликовано 2 ноября, 2010 (изменено) · Жалоба Прикрутил вместо yagarto/arm-none-eabi сборку kgp-arm-eabi_x86_32_HALLOWEEN_EDITIION от Klen, результат тот же: stdout не перенаправляется. Я озадачен. Изменено 2 ноября, 2010 пользователем Spym Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 (изменено) · Жалоба Меня немного смущает слово "перенаправляется". Что Вы имеете в виду? printf() выполняет вывод в поток stdout (при наличии перечисленных в документации системных вызовов, а именно, close, fstat, isatty, lseek, read, sbrk, write). Таким образом, перенаправление stdout - это просто присваивание ему другого значения. Может у Вас просто в stdout что-то не то? Покажите, как Вы открываете поток, что присваиваете stdout... Изменено 3 ноября, 2010 пользователем alx2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Also yagarto is a arm-elf toolchain, and the codesourcery is a arm-eabi toolchain. Это же неверное утверждение. Так год-то прошлый. Сейчас yagarto перешло на arm-eabi, да. Прикрутил вместо 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба ...перенаправление stdout - это просто присваивание ему другого значения. Может у Вас просто в stdout что-то не то? Покажите, как Вы открываете поток, что присваиваете stdout... stdout ничего не присваиваю, т.к. достаточно переопределить низкоуровневые функции, которые Вы уже перечислили, разве нет? При входе в main видно, что stdout уже существует (см. ниже). Очень странно. Посмотрите ещё вот в этой теме, я там приаттачивал тестовый проект с printf. Он для cortex-m3, но может поможет. Посмотрел, принципиальных отличий не нашел. Ещё мысль пришла. Если у вас 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Я прозрел; как выяснилось, вывод корректно работает даже в 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". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Я прозрел; как выяснилось, вывод корректно работает даже в Yagarto. Это радует, значит Yagarto потихоньку движется в сторону, так сказать, общепринятых тенденций. И eabi, и --disable-newlib-supplied-syscalls. Больше тулзов, хороших и разных! :) Почему так? Мне кажется, что это кривизна newlib. Хотя неясно, чем отличается _write из вашего файла syscalls.c от _write дефолтного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gopher 0 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Почему так? Ведь в этом случае в stdout должно было уйти "Something string". обычная буферизация. попробуйте так printf("Something string"); fflush(stdout); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 3 ноября, 2010 Опубликовано 3 ноября, 2010 · Жалоба Прикрутил вместо yagarto/arm-none-eabi сборку kgp-arm-eabi_x86_32_HALLOWEEN_EDITIION от Klen, результат тот же: stdout не перенаправляется. Я озадачен. давайте прикрутим вместе. но после праздникрв пролетариата - я уже пикирую. не думаю что есть проблемы где есть исходный код :) всех форумчан с празгиком, история нашего народа однако... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spym 0 4 ноября, 2010 Опубликовано 4 ноября, 2010 · Жалоба обычная буферизация. попробуйте так printf("Something string"); fflush(stdout); Действительно. Интересно, как я могу управлять размером буфера? И почему использование управляющих последовательностей не приводит к буферизации вывода? давайте прикрутим вместе. В прикручивании как раз проблем не возникло - достаточно указать в PATH путь к toolchain же. Да, кстати, при -O0 ваш KGP собрал 160кБ кода против 202кБ -O0 yagarto (-lc -lm -lgcc -lstdc++) при прочих равных, на первый взгляд всё работало. Хотя это сейчас мало о чем говорит, да и полученный код я не тестировал пока толком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться