Здравствуйте. Недавно занялся процессорами stm32, и вот, хочу поспрашивать про библиотеку LibC.
Портирую проект с OrangePI(клон Raspberry), который ранее работал очень медленно и на AVR. В предыдущих версиях проектов я работал с TFT дисплеем, малельким дисплейчиком, устройствами i2c, uart и консолью через файлы.
На Linux работать с файлами элементарно, и на AVR библиотека LIBC тоже это позволяла без проблем. А на stm32 этот момент как то плохо описан, максимум попадается "прибитие гвоздями" uart к printf.
Хочется перенести код типа такого: Спойлер
Код:
//создаются файлы для работы с устройствами FILE *uart_stream; FILE *log_stream; FILE *lcd_info_stream; FILE *tft_console_stream; ... //есть фунукции работы с железом extern int uart0_putchar(char c, FILE *stream __attribute__ ((__unused__)) ); extern int tft_putchar(char c, FILE *stream __attribute__ ((__unused__)) ); extern int tft_console_putchar(char c, FILE *stream __attribute__ ((__unused__)) ); ... //связываем файловые потоки с "железом" (это пример для AVR, а на linux открываем с помощью fopen файлы устройств) uart_stream = fdevopen(uart0_putchar, uart0_getcharL); //send , receive functions tft_stream = fdevopen(tft_putchar, NULL); //send , receive functions tft_console_stream = fdevopen(tft_console_putchar, keyboard_getchar); //send , receive functions ... //далее работаем с разными устройствами. для примера, пусть будет libc.printf fprintf(log_stream,"some var=%6u",v); fprintf(tft_console_stream,"\e[31mText..");
//при работе с файлами на AVR приходится дополнительно связать структуру stdio.FILE со структурой "FILE" из библиотеки для работы с SD картой. На Lunux лишние действия не требуются.
Рассмотрев библиотеку LIBC для STM32, в упор не заметил работающую структуру FILE. И не обнаружил примеров работающих с stdio.FILE. (Кроме примеров как жестко "повесить" printf на Uart через переопределение функции _write/putchar) А вот примеров создания нескольких потоков FILE для ввода/вывода не нашел. Да, можно сделать ветвление в функции _write, но точно я не буду мешать все устройства и файловые операции придачу в одной функции.
Писать костыли под такую LIBC как то нет желания. Как бы не легче было другую libc прикрутить. Надеюсь, я просто чего то не заметил. Или эта задача делается на stm32 иначе.
Подскажите как правильно делаются потоки ввода вывода на stm32.
Да, библиотеки товарища Чена рабочие, что то я даже использовал. Но проблему с потоками не решал, боле того он их не использовал вовсе.
Обычно, имеющиеся у потока/файла функции чтения, записи и прочие, описаны или в самой структуре или сслылаются на другую структуру устройства(или на драйвер). Всё ,больше о работе с железом знать никому не надо, и библиотеке stdio особенно.
В структуре FILE библиотеки LIBC определены поля _read, _write, но оно не работает, и ни примеров ни описаний.
Да, можно сделать ветвление в функции _write, но точно я не буду мешать все устройства и файловые операции придачу в одной функции.
Ну вот, ядро за вас делает а вы не хотите! Но write(fd) и read(fd) хотите. Не бывает так (UNIX: все есть файл)
_kp писал(а):
a В структуре FILE библиотеки LIBC определены поля _read, _write, но оно не работает, и ни примеров ни описаний.
А что вы в примере ожидаете увидеть?
Посмотрите на реализацию методов в ядре (linux kernel). Ничего там военного нет, вам нужно реализовать несколько syscall'ов. _open, _close, _seek, _write, _read, может быть _flush. и все. Пример с "прибиванием гвоздями printf" вполне релевантен. Он работает с одним fd (скорее всего в вашем в случае примеров что вы видели - тупо забивает на него), вам же нужно расширить поддержку до кастомных дескрипторов связанных с вашей FS. PS: fd - file descriptor, если вы не знаете что это, задача съест много вашего времени
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Нашел как работать с потоками на stm32! Открытие потока со своими функциями делается функцией - fopencookie() Практически, расширенный аналог, того что на avr делала функция fdevopen()
Когда разобрался, то и небольшое количество примеров нашлось, по ключевому слову fopencookie , а в стандартных примерах, почему то вовсе не упоминается столь важная функция.
Итак, решение:
//Создаём функции обычного блочного чтения/записи для работы с железом, но тип аргументов должен совпадать с требуемым в stdio.h //В параметре _cookie можно передать произвольный аргумент, например для однотипных функций, работающих с разным железом (я не использую) ssize_t uart1_write( void *_cookie, const char *buffer, size_t length); ssize_t uart1_read(void *_cookie, char *buffer, size_t length);
//Готово. Можно использовать откуда угодно через потоки. fputs(f_uart1 ,"Text to uart"); fputs(f_tft,"Text to console"); fprintf(tft_console,"\e[%u;%uH\e[%sm%s",y,x,dattr,str );
Примечание. C помощью setvbuf() можно отключить буферизацию на уровне библиотеки stdio. Та буферизация не альтернатива буферизции с помощью DMA/прерываний, а для многопоточного кода. Кроме того, она абсолютно вредна для нетекстовых данных, и быстодействияя не прибавляет, и даже наооборот уменьшает. Но она полезна при записи в один поток данных из многопоточного кода(и только многопоточного), например ведение лог-файла, и при использовании буферизации данные будут смешаны не побайтно, а постройно, то есть будут читаемы.
ps: Потоки хороши тем, что их можно перенаправить, в отличие от жестких функций работы с железом.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 47
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения