![]() |
![]() |
|||||||||||||||
STM32F4-DISCOVERY Пример подключения к Ethernet Продолжение
Автор: Борис Горшков, 4bg@mail.ru Часть вторая. Обе части представляют собой попытку обобщить знания из примеров, статей и скромного личного опыта в освоении микроконтроллера STM32F4 в среде программирования CooCox CoIDE. Для полноценной работы, как и в первой части, нам понадобится микроконтроллер линейки “DISCOVERY” на ядре Cortex-M4 и плата приемопередатчика DP83848. Несмотря на то, что в каждой части рассматриваются обособленные примеры, начинать ознакомление с темой сразу с этой части будет не совсем правильно, потому как она является продолжением предыдущей статьи и ранее изложенные вопросы здесь не рассматривается. Эта часть посвящена загрузке файлов с сервера http. Также рассмотрен пример использования двух тегов технологии SSI.
Веб-страницы сервера Начнем с html документов сервера (как вы помните, они находятся в папке fs проекта). Обращаю внимание на то, что все html документы созданы в сокращенном варианте, предполагающем, что значение некоторых параметров заданы по умолчанию, что может в свою очередь привести к искажению информации в отдельных конфигурациях браузера. В таком случае нужно поменять настройки браузера или дописать текст страницы должным образом. И так займемся проектом. Главная страница сервера подверглась некоторым корректировкам – добавлены прямые ссылки на загрузку файлов (“Загрузка рисунка”, “Загрузка txt файла”, “Загрузка видеофайла”) и ссылка на страницу загрузки через запрос CGI рис.1. Страница “Загрузка файлов” написана заново. Как видно из рис.7 здесь расположены переключатель (radiobutton) для выбора файла и кнопка “Send” – передать запрос на сервер. Рис.1. Главная страница сервера
На странице рис.2 “Прием данных” в html тексте добавлен второй тег <!--#u-->, убрана строка автоматического обновления и соответствующим образом изменена страница на рис.3 “Передача данных” под два запроса cgi и сокращено количество элементов интерфейса для упрощения. Обратите внимание, что второй тег никоим образом не связан с передачей файлов сервером, а введен для демонстрации мультитегового примера технологии SSI.
Рис. 2 Страница html “Прием данных”
Рис.3 Страница html “Передача данных”
И наконец, в папку fs помещены следующие файлы для загрузки: - dfile.txt (текс с сайта https://mkpochtoi.ru) - image01.jpg (архитектура сети и настройки) - Gol_Havera.3gp
И последнее замечание перед тестированием. В файле STM32F4x7Rx.shtml (“Прием данных”) убран тег автоматического обновления, поскольку в примере первой части он не всегда стабильно работал с минимальным временем перезагрузки, но там он был оправдан наличием графических данных. Другое дело, что в той конфигурации нужно было увеличить его время с пропорциональным увеличением объема данных или передавать информацию динамическим файлом. К вопросу передачи данных в файле мы еще вернемся, а пока тег обновления исключен из текста html. Теперь пришло время испытания нового творения в автономном режиме. Для этого будем использовать браузер Mozilla Firefox, который открывает все файлы в надлежащем виде - рисунки 4,5,6,8. Замечу, что речь идет, прежде всего, о видеофайле 3gp так как именно его некоторые браузеры открывают в текстовом виде прямо в своем окне без окна диалога. Рис.4 Страница html с диалогом загрузки файла
Рис.5 Страница html с загруженным видеофайлом Сравнивая видео на мониторе со скриншотом, нетрудно заметить, что качество картинки на рис. 5 несколько лучше, а дело все в том, что, во-первых, утилита makefsdata.exe с оригинального пятисекундного ролика mp4 создает файл fsdata.c неприемлемой величины для ресурсов контроллера. А потому файл mp4 был конвертирован в формат 3gp размером ~90КБ (формат предназначен для видео на мобильных телефонах – с соответствующим качеством) и получен результирующий файл fsdata.с размером около 650КБ. Во-вторых, используемая программа создания скриншотов напрочь отказалась захватить стоп-кадр, поэтому пришлось поработать в графическом редакторе – и раз уж так вышло, то с оригиналом – mp4. Проект откомпилировался без ошибок. Проблема с величиной файла mp4 не должна огорчать, поскольку для хранения больших файлов на сервере можно использовать, например, SDкарту памяти. И чтобы окончательно завершить тему видеофайла, следует указать, что для его воспроизведения использовался проигрыватель KMPlayer, поддерживающий все популярные аудио и видеоформаты. Теперь можно перейти к тексту самого проекта.
Описание примера. Микроконтроллер
Для демонстрации приема файлов с сервера не будем создавать новый проект, а откорректируем пример первой части. Тем более, что изменений не так уж много и все они касаются, в основном, исходного файла httpd_cgi_ssi.c. В этом файле, прежде всего, подключаем ранее неиспользованный тег “u”.
char const* TAGCHAR="t"; char const* TAGCHAR2="u"; char const** TAGS= { &TAGCHAR, &TAGCHAR2 }; tCGI CGI_TAB[2]; //1
И дополнительно пишем обработчик CGI.
const tCGI FILE_CGI={"/dfile.cgi", FILE_CGI_Handler};
const char * FILE_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]);
Далее сокращаем уже знакомую нам по первой части функцию LEDS_CGI_Handler до четырех каналов управления (светодиоды LED3-LED6) и одной переменной (Var1). //------------------------------------------------------------------- const char * LEDS_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { /* We have only one SSI handler iIndex = 0 */ if (iIndex = 0) { uint32_t i=0;
/* All leds off */ LEDOff(LED3); LEDOff(LED4); LEDOff(LED5); LEDOff(LED6);
statusLED[0] = 0; statusLED[1] = 0; statusLED[2] = 0; statusLED[3] = 0;
/* Check cgi parameter : example GET /leds.cgi?led=2&led=4 */ for (i=0; i<iNumParams; i++) { /* check parameter "led" */ if (strcmp(pcParam[i] , "led")==0) { /* switch led1 ON if 1 */ if(strcmp(pcValue[i], "1") = =0) { GPIOD->BSRRL = GPIO_Pin_12; statusLED[3]=1; } /* switch led2 ON if 2 */ else if(strcmp(pcValue[i], "2") = =0) { GPIOD->BSRRL = GPIO_Pin_13; statusLED[2]=1; } /* switch led3 ON if 3 */ else if(strcmp(pcValue[i], "3") = =0) { GPIOD->BSRRL = GPIO_Pin_14; statusLED[1]=1; } /* switch led4 ON if 4 */ else if(strcmp(pcValue[i], "4") = =0) { GPIOD->BSRRL = GPIO_Pin_15; statusLED[0]=1; } } if (strcmp(pcParam[i] , "Var1")= =0) { Var1[0] = atoi(pcValue[i]); } } /* uri to send after cgi call*/ // return "/STM32F4x7Tx.html"; return "/STM32F4x7Rx.shtml"; } } //--------------------------------------------------------------------------------------------------------------
Пишем новую функцию FILE_CGI_Handler для обработки запросов файлов (iIndex=1) . //--------------------------------------------------------------------------------------------------------------- const char * FILE_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { uint32_t i=0; if (iIndex==1) { if (strcmp(pcParam[i] , "image")= =0) { if(strcmp(pcValue[i], "1") = =0) { return "/image01.jpg"; } else if(strcmp(pcValue[i], "2") = =0) { return "/dfile.txt"; } else if(strcmp(pcValue[i], "3") = =0) { return "/Gol_Havera.3gp"; }
} } } //--------------------------------------------------------------------------------------------------------
Обработчик Data_Handler SSI сокращен и написан для iIndex 0 и 1, которые соответствуют тегам "t" и "u". //-------------------------------------------------------------------------------------------------------- u16_t Data_Handler(int iIndex, char *pcInsert, int iInsertLen) { uint32_t Da; char DigitA1=0, DigitA2=0, DigitA3=0, DigitA4=0; char DigitB1=0, DigitB2=0, DigitB3=0, DigitB4=0;
if (iIndex = =0) { int i=0; while (i<4) { if(statusLED[i] = = 1) { *(pcInsert+i)='1'; }else {*(pcInsert+i)='0';} i++; } return strlen(pcInsert); } if (iIndex = =1){ Da=Var1[0];
//-- prepare data to be inserted in html DigitA1= Da/1000; DigitA2= (Da-( DigitA1*1000))/100 ; DigitA3= (Da-(( DigitA1*1000)+(DigitA2*100)))/10; DigitA4= Da -(( DigitA1*1000)+(DigitA2*100)+ (DigitA3*10));
*pcInsert = (char)(DigitA1+0x30); *(pcInsert + 1) = (char)(DigitA2+0x30); *(pcInsert + 2) = (char)(DigitA3+0x30); *(pcInsert + 3) = (char)(DigitA4+0x30);
/* need to be inserted in html*/ return strlen(pcInsert); } return 0; } В заключение корректировки указываем количество индексов в функциях инициализации CGI и SSI, и можно компилировать проект, предварительно подключив файл с html страницами - fsdata.c. Настройки файла main.h не меняем. Имя папки проекта - Server_Eth_2.
Работа
Загружаем откомпилированный код проекта в память микроконтроллера STM32F4. Схема подключения и настройки сети (Рис.1 и Рис.2. первой части) остаются без изменений. В браузере указываем адрес сервера 192.168.1.110 и загружаем главную страницу рис.1. Далее проверяем загрузку файлов по ссылкам на главной странице сервера и по запросу со страницы “Загрузка файла” рис. 7. Результат тестирования программы приведен на рисунках 5,6,8. Рис.6 Страница html с загруженным текстовым файлом
Рис.7 Загрузка с сервера видеофайла. Диалог
Рис.8 Загрузка с сервера графического файла
Вывод информации с использованием двух тегов "t" и "u" технологии SSI приведен на рисунках 9 и 10. Рис. 9 Страница html “Передача данных”. Задание состояний выходов и переменной
Рис.10 Страница html “Прием данных”.
На загруженной странице STM32F4x7Rx.shtml “Прием данных” рис. 10 строки текста <!--#t--> и <!--#u--> заменены на стороне сервера информацией о состоянии светодиодов LED1…LED4 и значением переменной Var1 соответственно. Эта информация была предварительно отправлена клиентом со страницы STM32F4x7Tx.html “Передача данных” рис.9.
Внешний вид сервера в составе плат STM32F4-DISCOVERY и приемопередатчика DP83848, приведен на рис.11. Рис.11 Внешний вид плат сервера и их подключение
Заключение
На этом завершим рассмотрения вопроса загрузки файлов с сервера http. Ещё раз обращаю внимание, на то, что все файлы примера предварительно созданы утилитой makefsdata.exe и размещены в памяти микроконтроллера STM32F4-DISCOVERY на этапе компиляции. Замечу, что пример второй части статьи может представлять интерес, прежде всего для дальнейшего развития темы - передачи динамически изменяющихся данных в файле. Очевидно, что именно эта задача актуальна при удаленном управлении - будь то система умный дом или промышленный объект. Это может быть информация с различных датчиков, видеокамеры, или журналы отчетов и другие виды данных. Пример возможной реализации передачи данных файлом рассмотрим в третьей части статьи. Исходный текст проекта второй части можно скачать по ссылке ниже.
Файлы: Все вопросы в Форум.
|
|
|||||||||||||||
![]() |
![]() |


![]() |
||||
|
|
||||





