KnightIgor 2 20 января, 2011 Опубликовано 20 января, 2011 · Жалоба Привет форумчанам. Итак, имеем STM32F103RB, хотя в данном случае не принципиально, т.к. вопрос о функциях поддержки ввода-вывода (ключевое слово printf()) на консоль с одновременным использованием файловой системы FlashFS из RL-ARM 4.12 от ARM/KEIL. Чтобы дойти до сути вопроса, надо немного рассказать о предыстории и моем понимании понятия retarget. Информация черпалась из помощи, прилагаемой к uVision4 с ARM Tool Chain, и отсюда: RL-ARM Итак, хотим выводить на Hyperterminal с микроконтроллера. Для этого подсоединяем его UART к COM-порту компа, а в программе микроконтроллера используем printf(). Поскольку библиотека ARM не зависит о периферии конкретного камня, надо бы рассказать ей, что хотим посылать символы, "генерируемые" в недрах printf(), через, скажем, UART1. Для этого, как описывается в помощи и примерах, необходимо реализовать/перехватить функцию fputc(). Как правило, такой "перехват" помещается в retarget.c, а кто хочет стройный код, выделяет все, что касается UART, отдельно в файл serial.c. Примерно так: RETARGET.C ... #include <stdio.h> #pragma import(__use_no_semihosting_swi) // // To be implemented elsewhere (here - in Serial.c): // extern int sendchar(int c); extern int getkey(void); // ... struct __FILE { int handle; // Add whatever you need here }; FILE __stdout; void _sys_exit(int return_code) { while (1); // endless loop } // -------------------------------------------- // Reimplementation for printf() // int fputc(int c, FILE *f) { sendchar(c); } В SERIAL.C будет имплементирован sendchar(), который работает с железом UART1. Все получилось и работает, хотя вся эта муть с #pragma import(__use_no_semihosting_swi) и struct __FILE {...} мне до конца не понятна. Это был бы первый подвопрос. Теперь наступает следующий этап: хотим пользовать RL-ARM FlashFS конкретно с SD-картой на SPI. Смотрим RL-ARM и видим, что, якобы, все просто: 1). Копируем File_Config.* в свой проект, настраиваем File_Config.С 2). Используем SPI_STM32F103.c или пишем что-то свое для реализации функции spi_init (), spi_ss(), spi_hi_speed() и spi_send() (по сути аналог serial.c для UART1) 3). Подстыковываем библиотеку FS_CM3.lib 4). В коде вызываем finit(), когда SD-карточка вставлена, после чего... 5). пользуем файловую систему. Так вот, пока ограничивался finit(), ffind() и ffree() для посмотреть каталог SD-карточки и количества свободного места, все транслировалось, компоновалось и работало. Как только захотел что-то читать, то есть ввел в код обращения к fopen(), fread() и fclose(), компоновщик заголосил: Error: L6915E: Library reports error: __use_no_semihosting_swi was requested, but _sys_open was referenced А если взять из примера, приданого к RL-ARM FlashFS, реализацию этой самой функции со всеми там для нее важными определениями и заголовками, то компоновщику уже слишком много: Error: L6200E: Symbol _sys_open multiply defined (by sys_io.o and retarget.o). Хотя нигде sys_io.o в чистом виде не наблюдается, видать, в какой-то библиотеке сидит. Прошу совета и разъяснения. Заранее благодарен. Игорь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 24 января, 2011 Опубликовано 24 января, 2011 · Жалоба Похоже, никто глубоко так не забирался в дебри. Короче, взял, не мудрствуя лукаво и без изменений, тот RETARGET.C, что лежит в FlashFS, - и все заработало: и printf в UART плюется, и файловая работает. И все бы хорошо, и тему закрыть, но обнаружил интересный эффект. Понадобилось мне в терминале периодически (точно раз в одну секунду) обновлять строку "по месту". В соответствующем printf заменил \n на \r. Работает, но... такое впечатление, что обновление происходит не каждую секунду, а через раз. Никто с таким не встречался? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 26 января, 2011 Опубликовано 26 января, 2011 (изменено) · Жалоба Похоже, никто глубоко так не забирался в дебри. Решение (но не глубинное понимание) найдено. Если кому интересно, слушайте сюда. Итак, хотим файловую систему RL-FlashFS из KEIL и вывод на терминал (в данном случае - через UART) по printf(). Вариант 1) - классический: 1.1) вносим в проект (возможно, предварительно скопировав их в каталог проекта) файлы File_Config.c и retarget.c из RL-FlashFS. 1.2) подключаем к проекту библиотеку FS_CM3.LIB (Cortex) или FS-ARM.LIB (ARM7). 1.3) имплементируем функции sendchar (и, возможно, getkey()), объявленные в retarget.c, реализуя передачу (и прием) символов через UART. 1.4) имплементируем функции доступа к носителю. Для SD карты через SPI, например, - это четыре функции, как описано здесь. 1.5) смотрим в помощь к RL-FlashFS и пользуем ее функции инициализации, ввода/вывода и другие. 1.6) пользуемся printf() для вывода через UART чего бы ни было на терминал. Все прекрасно за одним исключением: подсистема вывода на терминал странно обрабатывает строки, заканчивающиеся на '\r': в итоге строки-то выводятся, но с запозданием, словно подсистема выплевывает буфер либо только при наличии '\n', либо при переполнении. Применяем вариант 2) - модифицированный: 1.7) ко всему вышенаписанному в файл retarget.c добавляем: extern int $Super$$fputc(int c, FILE *f); // Original library function int $Sub$$fputc(int c, FILE *f) { // Patch if (f == stdout) return sendchar(c); else return $Super$$fputc(c, f); } Что такое "подкуп долларами", можно почитать здесь: Using $Super$$ and $Sub$$ to patch symbol definitions Что сделали? Переписали функцию fputc, отловили там вывод на терминал, но перенаправили все остальное в библиотечную функцию. Все работает как надо. Изменено 26 января, 2011 пользователем KnightIgor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Это все интересно, но это был сизифов труд. Ретаргетинг подробно описывается в доке и примерах к компилеру RVCT которая лежит в закромах в свободном доступе ;) У Keil-а про ретаргетинг искать бесполезно. И надо сказать ретаргетинг как процесс несколько сложнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Это все интересно, но это был сизифов труд. Сизифов - это когда несколько раз на одни грабли. Ретаргетинг подробно описывается в доке и примерах к компилеру RVCT которая лежит в закромах в свободном доступе ;) Ссылочку бы... Это в том доке, по которому ныне на сайте ARM вкось написано серыми большими буквами "Superceded"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 2 26 января, 2011 Опубликовано 26 января, 2011 · Жалоба Ссылочку бы... Это в том доке, по которому ныне на сайте ARM вкось написано серыми большими буквами "Superceded"? http://infocenter.arm.com/help/index.jsp?t...ar01s03s04.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба http://infocenter.arm.com/help/index.jsp?t...ar01s03s04.html Спасибо за ссылку, но мы о разных вещах говорим. Там речь о "перенаправлении" в смысле поддержки новых (на тот момент, 2007) Cortex-M3 процессоров. Я это все знаю. Меня же интересовало внутреннее построение аппаратно-независимой библиотеки stdio и rtl, чтобы разобраться, почему вывод через _sys_write() странно обрабатывает строки с '\r', а также понять, как взаимосвязаны различные функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Еще у Keil есть вот такая pdf-ка http://www.keil.com/download/docs/403.asp Сам думаю попробовать RL-ARM, но пока дальше мечты не продвинулся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 27 января, 2011 Опубликовано 27 января, 2011 · Жалоба Еще у Keil есть вот такая pdf-ка http://www.keil.com/download/docs/403.asp Сам думаю попробовать RL-ARM, но пока дальше мечты не продвинулся. Да, эта pdf-ка лежит у меня на диске. Ею я и руководствовался, когда разбирался с RL-FileSystem. Но там ничего нет (и быть не может) о stdio. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться