Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Свой поток ввода/вывода в Си. Возможно?

590
10 октября 2009 года
Gigahard
223 / / 03.04.2006
Собственно вопрос, можно ли в Си создать свой объект потока ввода/вывода для работы с функциями printf, fprintf?
Можно ли заменить стандартный поток вывода у функции printf на свой?

P.S. Интересует только Си. Не C++.
5
10 октября 2009 года
hardcase
4.5K / / 09.08.2005
В Windows это делается созданием именованного или безямянного канала (pipe) и установкой его функцией SetStdHandle как стандартного потока.
602
10 октября 2009 года
KPI Student
265 / / 16.12.2006
Думаю, можно попровать создать именованый пайп через CreateNamedPipe(...), затем сделать fopen( "\\.\pipe\pipename", ... );

Как вариант под никсами - fopen( "./myfifo", .. );

Вариант для юниксов абсолютно штатный, там проблем не будет. Насчет винды думаю тоже пройдет, в любом случае сишная библиотека не сможет открыть файл иначе, чем через CreateFileExW, который в свою очередь вполне подерживает приведенный выше формат имени файла. Хотя если заботливые разработчики Сишной библиотеки под ваш компилятор прикрутили свою проверку валидности имени файла - то пожалуй вам не повезло.

ЗЫ. Я надеюсь, вы не стиральную машину на С программируете? Там точно не прокатит мой вариант... (не хочу сказать ничего обидного, имеется ввиду прошивка)
590
10 октября 2009 года
Gigahard
223 / / 03.04.2006
Не... Речь не про winapi. И не про винду вообще. Речь про Си и стандартную библиотеку ввода вывода. Т.е. про чисто СИшную абстракцию.

KPI Student Программирую почти "стиральную машину". Промышленная автономная железка. Планируется стандартный вывод или на телетайп, или в RS-232 канал.
Хочу унифицировать код, чтоб работать с абстракцией потока вывода и использовать штатные функции ввода вывода Си.
Интуитивно понимаю, что если создать пользовательский объект потока ввода/вывода, который инкапсулирует функции работы с RSом или телетайпом, то можно его будет подсовывать заместо потоков stdout, stderr и FILE, этот юзерский объект.
Только вот я не знаю, где накопать инфу по созданию такого пользовательского объекта ввода/вывода.
Собственно и прошу помощи в данном вопросе :)
43K
10 октября 2009 года
loki231
76 / / 27.09.2009
В порт RS-232:

int fd=open ("/dev/ttyS0", O_WRONLY); // COM1

struct termios tios;
tcgetattr (fd, &tios);
// Устанавливаем скорость, кол-во data-бит, стоп-биты и т.д. и т.п.
tcfsetspeed (&tios, 9600);
....
tcsetattr (fd, TCSANOW, &tios);

FILE *new_stderr=fdopen (fd, "w");
stdout=stderr=new_stderr;

fprintf (stderr, "Hello, world!\n");
260
10 октября 2009 года
Ramon
1.1K / / 16.08.2003
В догонку, freopen.
590
10 октября 2009 года
Gigahard
223 / / 03.04.2006
:)

Народ, я конечно благодарен Вам за помощь, но пожалуйста, вникните в суть вопроса.

freopen и линух с виндой эт конечно круто, но я не совсем о том спрашиваю...

Безотносительно операционки... Стандартная библиотека ввода вывода Си предполагает три встроенных стандартных потока ввода вывода (stdout, stdin и stderr), плюс объект FILE позволяющий работать с потоковым вводом выводом в файл.

Я пишу ПО, для железки, на которой отсутствует операционка как таковая. Соответственно таких функций, как fopen, open, файловой системы, а соответственно и файловых интерфейсов для работы с периферией там нет в принципе.

Собственно и нужно написать свой собственный объект потока, типа FILE (или stdout, stderr и т.п.) и реализовать его с помощью функций обмена данными, специфичными для оборудования.

Но данных о том, что собой представляет сам объект потока в Си, у меня нет. Соответвенно и информации с чего начать, нет тоже. По этому вопросу и прошу помощи :)
Кратенько еще раз. Хочется написать свой пользовательский объект потока, который инкапсулирует специфические железячные функции и предоставляет стандартный СИшный интерфейс для работы с функциями ввода вывода.
Опять возвращаясь к первоначальному вопросу - реально ли создать такой вот пользовательский объект потока, помимо трех стандартных и файлового? Где поискать инфу по тому, что собой этот объект потока должен представлять?

У меня есть кое какие идейки с перенаправлением буферизации стандартных потоков (привязка буфера потока к буферу отправки/приема устройства), но пока они не очень элегантны.
260
10 октября 2009 года
Ramon
1.1K / / 16.08.2003
По сути поток в C представляет из себя буфер + файловый дескриптор.
5
10 октября 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Gigahard
Где поискать инфу по тому, что собой этот объект потока должен представлять?


"Объект потока" в Си - это ничто иное, как некоторый дескриптор соответствующего объекта ОС (потока или файла). Стандартные функции Си просто переадресуют вызов API функциям ОС.

602
11 октября 2009 года
KPI Student
265 / / 16.12.2006
Цитата:
"Объект потока" в Си - это ничто иное, как некоторый дескриптор соответствующего объекта ОС (потока или файла). Стандартные функции Си просто переадресуют вызов API функциям ОС.

Думаю, для стандартных устройств в ОС, под управлением которой работает хитрый девайс должно быть имя файла, через которое можно открыть COM-порт. К примеру, в ДОСе - это может быть COM1, в винде - другое, и линухе - третье.

Я понимаю, что вопрос стоит не в том, как открыть ком-порт в ДОСе, акцентиру ю внимание на том, что скорее всего операционная система предоставляет специальное имя файла, через которое можно его открыть.

Стандартных методов для работы с портами (как com), так и ввода-вывода я не знаю. Возможно, если ось не перекрывает доступ к портам, то можно попробовать прямой доступ к портам ввода-вывода, а оттуда хоть в RS-232, хоть в SATA.

5
11 октября 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: KPI Student
Думаю, для стандартных устройств в ОС, под управлением которой работает хитрый девайс должно быть имя файла, через которое можно открыть COM-порт.

У товарища нету ОС. У него сама программа и есть - ОС, т.е. прошивка.

252
12 октября 2009 года
koderAlex
1.4K / / 07.09.2005
в специфичных Си языках есть функции для инициализации железа . обычно как файловых устройств . внимательнее читай описуху .
для сом порта втроенных устройств это обычно имя "stderr" или "debug" . создай имя (если его ещё нет) "stdout" , переприсвой ему "stderr" или "debug" и будет тебе счастье . )
590
15 октября 2009 года
Gigahard
223 / / 03.04.2006
По большому счету, у меня голый процессор. Инициализацию железа провожу ручками, прямым доступом к регистрам.

Самое обидное, что покопашись на предмет содержимого структуры FILE, (объектами которой являются потоки stdout, stderr, stdin), обнаружил, что на разных системах данная структура реализована по разному. На линуксе по своему, в досе по своему, в винде соответственно тоже.
Т.е. это абстрактный интерфейс, реализация которого зависит от конкретной системы.
По всей видимости и его взаимодействие с функциями работы с потоками, тоже зависит от внутреннего содержимого структуры FILE.

Полазив по иностранным форумам, встретил несколько схожих тем по данному вопросу. Судя по ответам, создание пользовательских потоков в Си не предусмотрено. Если только не через самодеятельность какую. Не хотел употреблять слово хак, но в общем типа того... :)

Допустим я накопаю к своему компилятору содержимое структуры FILE. В принципе, большинство членов этой структуры можно будет привязать к вполне реальной информации (ну там буфер отправки/приема, флаги состояния потока), на часть реализовать заглушки. Единственное, что я не понимаю, это что использовать в качестве дескриптора потока. Ведь операционки нет...


Еще одним вариантом, я еще с самого начала рассматривал применение буферизованого потока. Я сейчас на вскидку не помню название функций. Но там для потока можно задать буфер в оперативке, который по набору или по запросу можно будет опустошать. Я вот подумал, а что если в качестве такого вот буфера применить буфер пересекающийся с буфером отправки com порта?
260
15 октября 2009 года
Ramon
1.1K / / 16.08.2003
Есть язык, а есть его стандартная библиотека, которая обеспечивает некие стандартные интерфейсы. Вот эта библиотека содержит зависимые от платформы компоненты, иными словами связи между структурой FILE и компилятором НЕТ. FILE принадлежит библиотеке, если вы хотите реализовать стандартную библиотеку - вперед вы и опишите структуру FILE и будете ее юзать в своей реализации. А возможно проще будет взять какую нить newlib и портануть ее с учетом конкретных требований.
590
15 октября 2009 года
Gigahard
223 / / 03.04.2006
Я это прекрасно осознаю. Независимость компилятора от стандартной библиотеки. Речь то шла как раз про зависимость структуры FILE от платформы :). Ну а поскольку компиляторы частенько заточены под конкретную платформу то... Ну не столь важно.

Тут важней то, что похоже от стандартной библиотеки у меня только кусок. Который не имеет реализации структуры FILE. Но реализация функций типа printf - есть.
Т.е. определить уж совсем произвольную структуру FILE похоже не получится.
Да и хотелось бы обойтись что называется "малой кровью". Не переписывать всю стандартную библиотеку ввода- вывода, а под уже существующие функции подсунуть только свой объект потока FILE.

Но поскольку стандартная библиотека все же вроде как является частью стандарта ANSI C, то надеялся на то, что структуру FILE как то можно приспособить под пользовательские потоки.

Собственно этому и посвящена тема :)
Просто не знаю, как корректно реализовать объект данной структуры потока. Со списком членов структуры вроде бы определился. Завтра гляну как она выглядит в библиотеке поставляемой со средой разработки для железа.
Единственное, что непонятно - если в той структуре должен быть определен дескриптор потока, то что его будет представлять в случае отсутствия ОС и BIOS?

Ладно. Пока таймаут для кодокопательства... Будет описание структуры, выложу сюда. Пока мыслей дальнейших нет.
260
15 октября 2009 года
Ramon
1.1K / / 16.08.2003
мысли должно быть две. Первая, что из стандартной либы вообще есть. А вторая, что НАДО получить.
252
15 октября 2009 года
koderAlex
1.4K / / 07.09.2005
название железяки в студию .
52K
13 ноября 2009 года
alex_ac
7 / / 29.10.2009
Лучше пиши архитектуру.
#1.Если atmel-avr, то смотри исходники avr-libc, или вообще перейди на c++(существует сборка gcc специально для работы с архитектурой), если там нет посмотри в исходниках, то если сможешь сделать пересекающимися буффер вывода и буффер UART, то вопрос у тебя решён.
#2.Можно просто вместо записи в буффер сразу отсылать в порт.
#3.Можно попробовать установить туда ОС(какую-нить FOS и проч.).
P.S.Только потом отпишись как сделал - мне эта тема интересна.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог