Продолжим работу с LWIP NETCONN, а также с протоколом HTTP.
И сегодня мы попытаемся не просто отправить страничку браузеру с нашего контроллера, но отправить данные в определённое место страницы, причём без перезагрузки всей страницы.
Раньше нам этого делать не удавалось, так как мы применяли технологии CGI и SSI, которые такого себе позволить не могли.
И поэтому нам на помощь пришла технология AJAX, которая делать это позволяет.
AJAX означает Asynchronous Javascript and XML. Из данной расшифровки следует, что AJAX использует именно язык JavaScript. Надеюсь, все мы знаем, что данный язык поддерживается всеми браузерами. Это язык не для сервера, тем более уж не для нашего контроллера. Поэтому писать мы код для AJAX будем именно в странице либо в отдельном файле со скриптом, а не в коде для контроллера. Но тем не менее у нас будет задача и для контроллера — предоставить данные, которые у нас запросит браузер, воспользовавшись технологией AJAX, а также принять данные, которые нам передаст браузер, что также возможно. Также из расшифровки аббревиатуры мы видим, что AJAX — это возможность обмена информацией между браузером и сервером именно в асинхронном режиме, то есть, мы запросили из браузера данные у сервера, а сервер нам пока их не передал, он их ещё готовит, но браузер их не ждёт, а продолжает выполнять дальнейший код, а когда данные придут, то браузер уже это обработает. Тем самым обеспечивается то, что вывод страницы не будет тормозить вследствие ожидания данных от сервера. Поэтому технология AJAX нам позволяет не просто осуществить обмен данными браузера с сервером без перезагрузки всей страницы, а также, если этих данных будет очень много, то также не вызвать замедление загрузки содержимого страницы.
Я, конечно же, не буду здесь выкладывать все тонкости языка JavaScript и стилизации CSS. Мы просто ими воспользуемся для преследования наших целей. Кому интересно научиться полноценно оперировать данными языками, то на этот счёт есть масса уроков и информации, правда не у меня. Я мог бы конечно дать неплохие уроки по данным языкам и не только, но, увы, всё невозможно успеть.
Поэтому давайте пока перейдём к проекту.
Проект был сделан из проекта прошлого занятия LAN8742_HTTP_SERVER_NETCONN и получил имя LAN8742_HTTP_SERVER_AJAX_NETCONN за счёт использования технологии AJAX.
Откроем наш проект в Cube MX и включим генератор случайных величин RNG
Затем идём в Clock Configuration и немного изменим регуляторы
Сгенерируем проект для System Workbench и откроем его там. Установим уровень оптимизации в 1, уберём при наличии отладочные настройки и закомментируем неизвестные компилятору строки в файле main.c.
Пока проект мы собирать не будем, так как мы знаем. что он все равно не соберётся.
А начнём пока готовить файл страницы.
Создадим нашу страницу с именем index.html, сохраним её в папке fs каталога, в котором мы собираем файл fsdata.c, и откроем её в любом редакторе. Удобнее, конечно это делать, например в SublimeText, но если его нет под рукой то подойдёт и блокнот Notepad++.
Первоначальный текст нашей страницы будет следующий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="page"> <div id="header"> </div> <div id="content"> <div id="article"> </div> <div id="sidebar"> </div> </div> <div id="footer"> </div> </div> </body> </html> |
Это обычный WEB-документ с заголовком и разбивкой на блоки. У нас будет блок с заголовком, блок с контентом и блок с подвалом. Блок с контентом будет разбит на 2 части — основной контент с идентификатором «article», а также сайдбар (правая боковая панель) с идентификатором «sidebar». Если мы попытаемся открыть такую страницу в браузере, то мы ничего не увидим. Наши блоки будут следовать друг за другом, будут они шириной во всю страницу и с высотой 0, так как в них нет никакого контента (содержимого). Но это мы исправим за счёт стилизации, недаром же мы каждому блоку присвоили идентификаторы. Для этого нам нужно создать скрипт со стилями наших блоков, можно это сделать и в тексте самой страницы, но чтобы не нагружать её в целях лучшей читабельности лишней информацией, то мы поместим наши стили блоков и затем не только блоков в отдельный файл, назовём его style.css и поместим в папку с самой страницей.
Первоначальное содержание данного файла будет следующее
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
body { background-color: #333333; background-image: url(IMG/bg01.png); } #page { width: 960px; margin: 0 auto; } #header { background-image: url(IMG/bg02.jpg); background-blend-mode: ; height: 100px; } #content::before, #content::after { content: ""; display: table; } #content::after { clear: both; } #content { background-image: url(IMG/bg03.png); zoom: 1; } #article { background-color: rgba(255,255,255,.7); width: 720px; padding: 20px; float: left; } #sidebar { width: 200px; float: left; } #sidebar ul li { color: #8f8; } #footer { background-color: #330033; height: 100px; padding: 20px; } #footer p { color: #0ff; } |
Мы задали определённый тип расположения наших блоков, также применили к ним фон, в некоторых местах даже в виде картинок, придали им определённую прозрачность. Кто знает css, тот поймёт.
Также не забываем в папку со страницами положить наш файл с прошлого урока 404.html для выдачи его пользователю при запросе несуществующего документа.
Также поместим папку IMG с файлами картинок для фонов в папку с нашей страницей.
Помимо данных картинок мы туда положим ещё четыре картинки с прошлого урока img01.jpg — img04.jpg.
Также не забываем подключить файл со скриптами в нашей странице index.html в тегах head
1 2 3 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="style.css"> </head> |
И, даже если мы сейчас откроем нашу страницу в браузере, то мы также ничего там не увидим, так как блоки у нас пустые.
Поэтому начнём их потихоньку набивать содержимым. Содержимое мы будем брать из страницы прошлого урока.
Блок header:
1 2 3 4 5 6 |
<div id="header"> <h1 style="text-align: center; color: #fff;">STM32F746G-DISCO</h1> <p></p> <p></p> <h2 style="text-align: center; color: #fff;">User Manual</h2> </div> |
Блок article:
1 2 3 4 5 6 7 8 9 10 11 12 |
<div id="article"> <h1 style="text-align: center;"> <strong>Introduction</strong> </h1> <p style="text-align: justify; margin-left: 11.35pt;"> The STM32F746G-DISCO discovery board (32F746GDISCOVERY) is a complete demonstration and development platform for STMicroelectronics ARM<sup>®</sup> Cortex<sup>®</sup>-M7 corebased STM32F746NGH6 microcontroller. This microcontroller features four I<sup>2</sup>Cs, six SPIs with three multiplexed simplex I<sup>2</sup>S, SDMMC, four USARTs, four UARTs, two CANs, three 12-bit ADCs, two 12-bit DACs, two SAIs, 8- to 14-bit digital camera module interface, internal 320+16+4-Kbyte SRAM and 1-Mbyte Flash memory, USB HS OTG, USB FS OTG, Ethernet MAC, FMC interface, Quad-SPI interface, SWD debugging support. This discovery board offers everything required for users to get started quickly and develop applications easily. </p> ....... <p> <strong> </strong> </p> </div> |
Весь блок я сюда постить не стал, так как очень много текста. Я скорее всего прикреплю потом всю заархивованную папку со всеми файлами вместе с проектом внизу страницы. Да и вообще вы можете в данный блок размещать любую информацию, как говорится, на ваш вкус и цвет.
Блок sidebar:
1 2 3 4 5 6 7 8 9 |
<div id="sidebar"> <ul> <li>Пункт 1</li> <li>Пункт 2</li> <li>Пункт 3</li> <li>Пункт 4</li> </ul> <p> </p> </div> |
Здесь просто список.
Ну и блок footer:
1 2 3 4 5 |
<div id="footer"> <p> <strong>Авторские права</strong> </p> </div> |
Сохраним изменения в странице и откроем её в браузере
Наша страница приобрела нормальный вид.
Осталось только придать функционал.
Давайте пока проверим работу нашего сервера.
Сгенерируем файл fsdata.c, обновим дерево проекта, отключим компиляцию данного файла и попробуем собрать проект.
Проект теперь должен будет собраться.
В функции задачи обработки запросов добавим запрос файла css-скриптов
1 2 3 4 5 6 7 |
else if (strncmp((char const *)buf,"GET /style.css",14)==0) { fs_open(&file, "/style.css"); netconn_write(newconn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY); fs_close(&file); } else if (strncmp((char const *)buf,"GET /IMG/img01.jpg",18)==0) |
Также добавим запросы картинок фоновых изображений
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
else if (strncmp((char const *)buf,"GET /IMG/bg01.png",17)==0) { fs_open(&file, "/IMG/bg01.png"); netconn_write(newconn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY); fs_close(&file); } else if (strncmp((char const *)buf,"GET /IMG/bg02.jpg",17)==0) { fs_open(&file, "/IMG/bg02.jpg"); netconn_write(newconn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY); fs_close(&file); } else if (strncmp((char const *)buf,"GET /IMG/bg03.png",17)==0) { fs_open(&file, "/IMG/bg03.png"); netconn_write(newconn, (const unsigned char*)(file.data), (size_t)file.len, NETCONN_NOCOPY); fs_close(&file); } else |
Соберём ещё раз код, прошьём контроллер и попробуем нашу страницу увидеть в браузере, набрав в адресной строке IP-адрес нашего сервера.
Мы должны получить ту же картину, как и при локальном открытии нашей страницы.
Это всё были только подготовительные мероприятия.
А функционал для отправки и приёма данных между клиентом и сервером мы продолжим писать в следующей части нашего занятия.
Предыдущий урок Программирование МК STM32 Следующая часть
Отладочную плату можно приобрести здесь STM32F746G-DISCOVERY
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Hi,
I am working on websocket. Your project seems great. I miss some inputs at cubeMX. Could you please share your ioc file and basic source code for websocket because I am stuck in code. I need your help.
Yours sincerely.
Добрый день. Не пытались ли запустить сеть на STM32H7? я что-то неделю не могу пинг получить.
Пока не пробовал. Пока больше занимаюсь с MP1.
Всего одну неделю?! Я три недели вечеров потратил с STM32H743VI+LAM8720, чтобы урок №96 пинговался, жесть — новые версии куба требуют только java 64 бит, без FReeRTOS IP и маску не не генерит, приходится ищё НАL_Delай перед и после инициализации LAN. При инициалализации SystemClock_Config не ставится __HAL_RCC_D2SRAM3_CLK_ENABLE(), приходится потом…. Мне помог коментарий из 96 урока второй части про MPU. Очень долго проект в куьбе лепил, чтобы всё делалось и генерилось не затирая нужного. Ещё подключил TFT_ILI9341_SPI — намучился, резюками 360 Ом надо зашунтировать на Gnd — MOSI и SCK