Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm32f207+ethernet+xml
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Kalyan
Добрый вечер. Начал работать с ethernet протоколом на микроконтроллере stm32f207. Запустил пример вебсервера с использованием Freertos с сайта STM. Глубохих знанй работы TCP/IP и HTTP нету. И вот мне надо по ethernet отправлять XML запросы. Я вообще не понимаю с какой стороны подойти к решению этой задачи. Подскажите пожалуйста где про это можно прочитать (не про сам протокол XML, а как генерировать их микроконтроллером и отправлять по ethernet). буду очень благодарен за информацию.
alx2
Цитата(Kalyan @ Jun 22 2012, 02:21) *
Подскажите пожалуйста где про это можно прочитать (не про сам протокол XML, а как генерировать их микроконтроллером и отправлять по ethernet)

Боюсь, что Вам следует-таки начать со знакомства с XML. Потому что это не протокол вовсе, а язык. Из упомянутого Вами протоколами являются IP, TCP и HTTP.
Чтобы ликвидировать кашу в голове, надо разобраться с основными понятиями. Затем выбрать протокол, посредством которого будет осуществляться обмен документами на языке XML (если к этому моменту не передумаете использовать XML). И вот когда протокол будет выбран, дойдет очередь и до вопроса, как по этому протоколу передавать и принимать данные...
А пока, без конкретной постановки задачи, вряд ли что-то конкретное можно порекомендовать.
Начните вот с этого:
http://ru.wikipedia.org/wiki/XML
http://ru.wikipedia.org/wiki/Ethernet
http://ru.wikipedia.org/wiki/IP
http://ru.wikipedia.org/wiki/TCP
http://ru.wikipedia.org/wiki/HTTP
Kalyan
alx2, спасибо за советы. Я их учел.
протокол выбран это будет HTTP.
Но вот как XML запросы отправлять для меня не понятно.
scifi
Цитата(Kalyan @ Jun 22 2012, 10:18) *
Но вот как XML запросы отправлять для меня не понятно.

Что есть "XML запрос"?
Единственное, что мне приходит в голову - это AJAX. Скрипт в браузере использует объект XMLHttpRequest, который запрашивает с веб-сервера динамические данные в формате XML. Веб-сервер, сидящий в вашем МК, должен сгенерировать эти данные и предоставить их браузеру в виде XML-файла (с соответствующим HTTP-заголовком). Вот, собственно, и всё.
Я правильно понял вашу задачу?
AlexandrY
Цитата(scifi @ Jun 22 2012, 09:47) *
Что есть "XML запрос"?
Единственное, что мне приходит в голову - это AJAX. Скрипт в браузере использует объект XMLHttpRequest, который запрашивает с веб-сервера динамические данные в формате XML. Веб-сервер, сидящий в вашем МК, должен сгенерировать эти данные и предоставить их браузеру в виде XML-файла (с соответствующим HTTP-заголовком). Вот, собственно, и всё.
Я правильно понял вашу задачу?


Видимо проблема и есть в правильном формировании HTTP заголовка, ибо сам текст XML запроса можно подсмотреть в браузере через инструменты разработчика.
А вот как передать куки, какое кодирование, какая таблица символов, аутентификация и т.д. с учетом ограниченности embedded web сервера.
Вот это надо будет отлаживать конкретно. biggrin.gif
Kalyan
Ситуация немного прояснилась. На МК мне надо реализовать HTTP клиент.
В примерах с сайта STM есть толь реализация HTTP сервера.
Может кто-то знает где взять реализацию HTTP клиента для МК и желательно с использованием LwIp стека?
scifi
Цитата(Kalyan @ Jun 22 2012, 12:12) *
Может кто-то знает где взять реализацию HTTP клиента для МК и желательно с использованием LwIp стека?

Гугл в помощь.
А вообще если всё, что нужно, - это запрашивать XML-файлы с сервера и интерпретировать их содержимое, то клиент может быть очень простым.
AlexandrY
Цитата(scifi @ Jun 22 2012, 11:22) *
Гугл в помощь.
А вообще если всё, что нужно, - это запрашивать XML-файлы с сервера и интерпретировать их содержимое, то клиент может быть очень простым.


Хотел бы я найти простой портируемый парсер XML wink.gif
scifi
Цитата(AlexandrY @ Jun 22 2012, 12:53) *
Хотел бы я найти простой портируемый парсер XML wink.gif

Легко! При том условии, что файлы на входе парсера имеют заранее известный сильно упрощённый вид :-) Я думаю, у вопрошающего как раз этот случай.
Kalyan
Для создания клиента буду пользоваться Netconn API functions со стека LwIp.
Допустим что на одной плате я запусти HTTP сервер тот что с примера с сайта CTM.
А на второй плате я запущу свой HTTP клиент. Вот как послать своим клиентом самый простой запрос к серверу.
Возникает ряд вопросов:
как работать с ip адресами?
Пусть у сервера будет 192.168.0.10 а у клиента 192.168.0.9.
Нашел функцию для его определения:
netconn_getaddr(conn, &local_ip_address, &port, 1);
Правильно ли я понял: эта функция должна найти адрес другого локального устройства (если флаг 1)? То есть адрес моего сервера ( 192.168.0.10). А если устройств в сети будет больше чем одно, тогда как? Но при использовании netconn_getaddr(conn, &local_ip_address, &port, 1) local_ip_address равняется нулю, но ошибка не возвращается.
Теперь на счет запроса. На стороне сервера есть вот такая проверка запросов:
Код
/* Is this an HTTP GET command? (only check the first 5 chars, since
      there are other formats for GET, and we're keeping it very simple )*/
      if ((buflen >=5) && (strncmp(buf, "GET /", 5) == 0))
      {
        /* Check if request to get ST.gif */
        if (strncmp((char const *)buf,"GET /STM32F2x7_files/ST.gif",27)==0)
        {...}  
        /* Check if request to get stm32.jpeg */
        else if (strncmp((char const *)buf,"GET /STM32F2x7_files/stm32.jpeg",31)==0)
        {...}
        else if (strncmp((char const *)buf,"GET /STM32F2x7_files/logo.jpg", 29) == 0)                                          
        {...}
        else if(strncmp(buf, "GET /STM32F2x7TASKS.html", 24) == 0)
        {...}


Корректно ли будет отправка такого запроса:
Код
char request[]="GET /STM32F2x7TASKS.html";

Мне вот хотя бы увидеть что клиент передает а сервер это воспринимает и отвечает.

В итоге пробовал это сделать вот так:

Код
struct netconn *conn, *newconn;
err_t err;
  
struct ip_addr local_ip_address = {0xc0a8000a}; //подствил адрес сервера так как его адрес не читался функцией netconn_getaddr

char request[]="GET /STM32F2x7TASKS.html";
    
  
  /* Create a new TCP connection handle */
  conn = netconn_new(NETCONN_TCP);
  
  if (conn!= NULL)
  {    
   // err = netconn_getaddr(conn, &local_ip_address, &port, 1);
    
    /* Bind to port 80 (HTTP) with default IP address */
    err = netconn_bind(conn, &local_ip_address, HTTP_PORT);
    
    if (err == ERR_OK)
    {
      err=netconn_write(conn, &request, 24, NETCONN_NOCOPY);
      
      /* Close the connection (server closes in HTTP) */
      netconn_close(conn);
    }
  }



netconn_bind проходит успешно. никакой ошибки не возвращается. А вот netconn_write возвращает ошибку (-8 - нет соединения).
В чем я ошибаюсь?
brag
тоже чесслово не понял, что за XML-запросы...
А для работы с http вам понадобится работать с текстом, а для этого надо парсер лопатить. на МК (да и не только) эффективно это делается в виде стейт-машины, забудьте про всякие bison. раньше я лопатил вручную, потом была своя приблуда для облегчения набивки типовых машин, а теперь юзаю Ragel State Machine Compiler - он умеет еще эти машины оптимизировать wink.gif
AlexandrY
Цитата(Kalyan @ Jun 22 2012, 18:42) *
netconn_bind проходит успешно. никакой ошибки не возвращается. А вот netconn_write возвращает ошибку (-8 - нет соединения).
В чем я ошибаюсь?


Ну вы даете, похоже действительно вам трудно wink.gif

netconn_bind - это еще не создание подключения.
Дальше для сервера должно следовать netconn_listen (т.е. начинаем слушать свой порт), а в случае клиента netconn_connect (т.е. подключаемся к порту другого сервера)
http://lwip.wikia.com/wiki/Netconn_bind

Адрес сервера вы не узнаете никакими командами в стеке TCP/IP.
Его надо забивать либо в ручную, либо использовать клиент протокола DHCP, а сервер должен иметь серверную часть DHCP.
Есть еще конечно такие протоколы как DNS,RIP, SNMP.. для таких дел, но...

Да, и по lwIP меня не спрашивайте, в нем не спец, просто посмотрел первый попавшийся хелп.
Aleksandr Baranov
Может, имеет смысл сначала потренироваться на создании клиента на PC? Там это будет удобнее, а разница - только в наменованиях методов установления соединения и передачи.
А сервер у Вас где - на PC или тоже на микроконтроллере?
scifi
Цитата(Aleksandr Baranov @ Jun 23 2012, 00:52) *
Может, имеет смысл сначала потренироваться на создании клиента на PC? Там это будет удобнее, а разница - только в наменованиях методов установления соединения и передачи.

+1. Я так и начинал. Запустил порт lwip для win32. AJAX тоже щупал под виндой. Когда всё заработало, перенёс на МК.
Kalyan
Цитата
Ну вы даете, похоже действительно вам трудно wink.gif

Да трудно, иначе б и не спрашивал :-)

Помогите понять правильную последовательностть устанеовления связей, подклюсения портов, отправления запросов и тд.

На сколько я понял должно быть так (для киента):

1. conn = netconn_new(NETCONN_TCP); /* Create a new TCP connection handle */
2. err = netconn_bind(conn, &local_ip_address, HTTP_PORT); /* Bind to port 80 (HTTP) with default IP address */
3. netconn_connect(.....) /
4. netconn_write(conn, &request, 24, NETCONN_NOCOPY); // и отправили HTTP запрос

После этого закрываем netconn_close(conn); /* Close the connection (server closes in HTTP) */

Правильно или нет?

А как тогда еще принимать ответы от сервера?

После отправления запроса netconn_write() перейти на прослушивание порта netconn_listen ()?
scifi
Цитата(Kalyan @ Jun 24 2012, 17:18) *
На сколько я понял должно быть так (для киента):
...
После этого закрываем netconn_close(conn); /* Close the connection (server closes in HTTP) */

Насколько я знаю, lwip поддерживает 3 разных API: raw API, netconn API и sockets, причём самый простой API - это sockets. Так что при недостатке опыта логично использовать sockets. Утверждается, что там есть хорошая совместимость с BSD sockets, то есть примеров использования должно быть много.
Kalyan
Цитата
Так что при недостатке опыта логично использовать sockets. Утверждается, что там есть хорошая совместимость с BSD sockets, то есть примеров использования должно быть много.

ок. Спасибо, попробую.
Но все же правильно ли я понял написал последовательность функций с netconn API?:

1. conn = netconn_new(NETCONN_TCP); /* Create a new TCP connection handle */
2. err = netconn_bind(conn, &local_ip_address, HTTP_PORT); /* Bind to port 80 (HTTP) with default IP address */
3. netconn_connect(.....) /
4. netconn_write(conn, &request, 24, NETCONN_NOCOPY); // и отправили HTTP запрос
scifi
Цитата(Kalyan @ Jun 24 2012, 22:04) *
ок. Спасибо, попробую.
Но все же правильно ли я понял написал последовательность функций с netconn API?:
1. conn = netconn_new(NETCONN_TCP); /* Create a new TCP connection handle */
2. err = netconn_bind(conn, &local_ip_address, HTTP_PORT); /* Bind to port 80 (HTTP) with default IP address */
3. netconn_connect(.....) /
4. netconn_write(conn, &request, 24, NETCONN_NOCOPY); // и отправили HTTP запрос

Сам я netconn не пробовал. Но общеизвестно, что bind нужен для того, чтобы принимать входящие соединения, то есть для серверов. У вас клиент, он сам инициирует соединения, так что bind исключить.
Кстати, для отладки советую задействовать Wireshark. Правда, для отладки требуется понимание происходящего (оно пока на нуле, очевидно). Придётся подтянуться.
Kalyan
Цитата
Кстати, для отладки советую задействовать Wireshark

Спасибо. До этого момента меня мучал вопрос об отладке сего ужаса :-).
Тоесть я могу подключить шнурок к своей плате и к компу, запустить Wireshark, и он сможет показывать структуру HTTP пакетов?

А дополнительно на ПК не надо ставить HTTP сервер чтобы firmware отправляя netconn_connect(.....) подключалось к нему?
scifi
Цитата(Kalyan @ Jun 24 2012, 23:07) *
Тоесть я могу подключить шнурок к своей плате и к компу, запустить Wireshark, и он сможет показывать структуру HTTP пакетов?

Именно так. Он захватывает пакеты и представляет их в удобоваримом виде. Отличная вещь.

Цитата(Kalyan @ Jun 24 2012, 23:07) *
А дополнительно на ПК не надо ставить HTTP сервер чтобы firmware отправляя netconn_connect(.....) подключалось к нему?

Я именно так и делал. Рекомендую вот этот.
Kalyan
Цитата
Я именно так и делал. Рекомендую вот этот.


Огромное спасибо! Вот только ссылка не работает. (
Aleksandr Baranov
Нужно:
Создать соединение с IP адресом сервера через порт 80;
Передать туда HTTP header;
Начать принимать от сервера ответные строки и парсать их;
В нужный момент - послать то, что хочется послать;
Принять от сервера ответ;
Закрыть соединение.
Kalyan
Цитата
Нужно:
Создать соединение с IP адресом сервера через порт 80;
Передать туда HTTP header;
Начать принимать от сервера ответные строки и парсать их;
В нужный момент - послать то, что хочется послать;
Принять от сервера ответ;
Закрыть соединение.


Огромное вам спасибо! То что я искал!
И еще немного наводящих вопросов:
Цитата
Создать соединение с IP адресом сервера через порт 80;

Делаю это вот так:
Код
netconn_connect(conn, &local_ip_address, HTTP_PORT)

Цитата
Передать туда HTTP header;

Это делаю вот так:
Код
netconn_write(conn, &http_client_request, 24, NETCONN_NOCOPY); //send request

Цитата
Начать принимать от сервера ответные строки и парсать их;

И вот после отправки запроса серверу HTTP клиент надо перевести в прослушивание что бы уловить ответы. Наверное функцией:
netconn_listen()
А после этого наверное обратно надо перевести соединение на отправку и сделать это функцией
Код
netconn_connect(conn, &local_ip_address, HTTP_PORT)


Поправьте если я ошибаюсь....
Aleksandr Baranov
Цитата(Kalyan @ Jun 26 2012, 05:59) *
...

Я не настолько силен в lwIP, чтобы советовать, но, по-моему, вместо listen надо применять rcv. И вообще, лучше сокетами оперировать.
andrewlekar
Да, Kalyan, плаваешь ты в теме знатно... Сделай лучше на компе серверный сокет и клиентский и погоняй между ними данные, а то пока у тебя полная чушь получается.
По теме, для клиентского соединения не нужно использовать ни bind, ни listen - это методы для сервера.
coredumped
На сайте ST есть все примеры применения LWIP на камешках STM32. Вот, например, для Cortex-M4: http://www.st.com/internet/com/SOFTWARE_RE...x7_eth_lwip.zip
Посмотрите примеры tcp_echo_client и tcp_echo_server - все вопросы сразу отпадут. Если у Вас другой МК, то искать надо страничку этого МК, закладочка "Design support", и по словам "LWIP TCP/IP stack demonstration". Есть исходники и аппнот (pdf) с описанием. Возьмите готовый проект и переделайте, не изобретайте колесо!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.