Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F107 + RTL8201 + lwip-1.4.0
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4
Golikov A.
надо знать про сокеты вот что.
1. сокет - это тройка параметров IP адрес, Порт, Протокол (TCP/UDP), ни при каких условиях не может быть 2 сокетов с одинаковой тройкой параметров, хоть 1 параметр да должен отличаться...

2. сокет может быть со стороны сервера, а может быть со стороны клиента. Клиент подключается к серверу, сервер ждет соединения клиента.
Как раз включение сервера на ожидание соединение и есть прослушка, listen mode. То есть он получает все обращения к этому сокету, и ищет среди них запрос на соединение (для ТСР), на который отвечает, устанавливает связь, и сокет переходит в conected mode.

если вы закроете законекченый сокет, он разорвет соединение и вернется в режим прослушки. Если вы закроете сокет на прослушке, он удалиться совсем.

тот номер что вы получаете при создании сокета - это всего лишь номер для отличия одного вашего сокета внутри вашей системы от другого. Внутри стэка стоит соответствие между этим номером и той тройкой параметров что были в начале. Потому если вы сделали сокеты
1 2 3 4 5, а потом 2 закрыли то он просто пропадет. При следующем создании сокета может так оказаться что он опять получит номер 2, а может номе 6, этого никто не знает, да это и не надо, главное запомнить какой номер дали при создании и все.

3. Сокет в conected mode это уже не 3, а 5 параметров
IP местный и клиента, Порт местный и клиента, Протокол. То есть вы можете создать сокет с портом 5, поставить его на прослушку, и когда к вам присоединится клиент с портом 7, вы можете спокойно создать новый сокет с портом 5, который сможет принять новое соединение, но либо по другому порту либо с другого IP.

для netcat - если по умолчанию она конектится на порт 7.
netcat 192.168.0.1 80
причем обратите внимание ваша сетевая карта и устройство должны быть в одной подсети

потом просто пишите текст в командную строку, и данные пошли.
smk
SocketNumber равен 4. При этом в tcp_callback не ходит, хотя прием идет и АСК отвечает тоже. При передаче более 4 байт имею следующую картину:
Нажмите для просмотра прикрепленного файла

Поставил порт 3000 и в tcp_callback стало заходить.

Теперь интересует такая штука. Вот я получил указатель и число байт. Я так понимаю, что из tcp_callback нужно выйти как можно быстрее? т.е. живенько все скопировать в свой буфер и выйти из tcp_callback?
А как услать свой пакет в ответ?
Golikov A.
ну скорость выхода из функций должна соответствовать режиму работы программы... Все данные что вы получили в этой функции для ТСР считаются принятыми, и если вы их никуда не положите и не обработаете, то они просто потеряются. Дальше ТСР за ними уже не следит.

Если у вас задействована функция окна, то надо не забывать его очищать tcp_reset_window(Soc). Иначе данные застопорятся.

чтобы послать данные надо их как бы послатьsm.gif
sendbuf = tcp_get_buf(data) - создаем буфер отправляемых данных, буфер с которым работает ТСР
tcp_send - отправляем данные

перед отправкой имеет смысл проверить
tcp_get_state - чтобы был в конекте
tcp_check_send - что может оправлять
tcp_max_dsize - сколько макс данных можно заслать, мало ли вдруг на другом конце окно забилось.
smk
Цитата
sendbuf = tcp_get_buf(data) - создаем буфер отправляемых данных, буфер с которым работает ТСР

Т.е. по сути происходит выделение буфера указанного размера для отправки?

Вообще говоря меня настораживает этот способ т.к. наверняка ведется работа с указателями. Как бы чего не вышло. Есть ли какие-то рекомендации по опыту работы чтоб гарантировано не случился сбой? Вот например, мне нужно передать массив 2 кБ, как в этой ситуации поступить? Объявить буфер 2 кБ и более? Получается нужно вручную следить за выделением памяти и страховаться на все случаи жизни или как это будет? Максимальный оазмер, как я понял 1460 байт. Т.е. отправлять длинную посылку нужно с разбивкой самостоятельно?
Golikov A.
tcp_get_buf
не спроста так называется, не спроста с тср начинается%)..
это штука буфер для отправки, но не просто буфер, это буфер в очереди ТСР сообщений, за которым следит ТСР.

естественно если у вас кончиться память то будет ошибка, там даже есть обработчик критических ошибок с while (1) в конце, чтоб у новичков проекты висли, наверное%)...
После того как данные помещены на отправку, их обработают, поделят на пакеты и отправят, после чего самостоятельно уничтожат этот буфер. Это к вопросу почему нельзя передать указатель на свой буфер.

Про максимальный размер вы не правильно понялиsm.gif есть так называемый жумбофрейм он до 8К может быть, не знаю правда поддерживает его кеил или нет. Более того я рекомендовал еще глядеть на функции tcp_max_dsize, совершенно спокойно при забитом окне может так оказаться что и 1460 не сможет послать, и даже 54.

smk
Всеравно пока не ясно как отослать много байт. Вот есть у кейла такой пример:

Код
#include <rtl.h>
#include <string.h>

BOOL send_datalog () {
  U8 *sendbuf;
  U16 maxlen;

  if (tcp_check_send (tcp_soc)) {
    /* The socket is ready to send the data. */
    maxlen = tcp_max_dsize (tcp_soc);
    sendbuf = tcp_get_buf (maxlen);
    memcpy (sendbuf, data_buf, maxlen);
    tcp_send (tcp_soc, sendbuf, maxlen);
    return (__TRUE);
  }
  return (__FALSE);
}


Исходя из
Код
memcpy (sendbuf, data_buf, maxlen);
я не могу услать больше чем maxlen. Что-то совсем не пойму как разбивка будет происходить. Ну вот ушла часть размером maxlen и еще три таких осталось. Помогите понять идею. Спасибо.
Golikov A.
вот так и будет
у меня буфер в который я кладу данные на отправку.
время от времени вызывается функция отправки. Если можно отправить весь буфер отправляю весь, если нет, то отправляю сколько можно, остальное остается в буфере до следующего раза. Отправка происходит как в примере, создается буфер с оптравляемыми данными (или частью если все отправить нельзя) и передается в сэнд. Если в этот раз сокет вообще не может отправлять, то весь буфер остается до след раза.

Вы про окно ТСР знаете? Во время работы то комму отправляете данные информирует вас о том количестве байт что он готов принять, и вы по какой угодно технологии, с буфером или без, с указателями или ДМА, вы не имеете права посылать больше чем он может принять. Так что следить за допустимым для отправки числом байт вы обязаны.
smk
Да, вот кстати уже давно хотел спросить про окна, ранее упоминавшиеся. Что это и как и для чего...
Golikov A.
да в целом все просто, это способ контроля потока.

Окно - это размер памяти для приема новых данных, каждые поступающие данные уменьшают этот размер, каждые обработанные данные освобождают окно. При каждом ответе на прием данных сообщается также сколько еще данных осталось в окне, если окно забилось, то время от времени посылаются данные 0 длинны чтобы как только окно освободилось можно было дослать очередной кусок. Так же есть дополнительное автономное сообщение которое сообщает что окно освободилось.

принимаются данные в окно, как только вы обработали данные, вы их из окна извлекаете. Есть разные реализации освобождения окна, в кейле она единовременная на все окно.
то есть допустим у вас окно 10, приняли 6 байт, окно стало 4,
обработали 6 байт, сбрасываете окно и оно становится опять 10. Если вы обработали 2 байта, то у вас нет возможности извлечь только их сделав окно 6, пока все 6 не обработаете окно не освобождаете.

как только вы приняли 6 байт, больше 4 вам прислать не могут, как освободили окно может придти все 10 сразу. Чем больше окно - тем больше надо памяти, но тем быстрее работает стэк.






smk
Огромная благодарность Golikov A! Разобрался, все пока понятно и отлично работает. Далее самое интересное. Как показать веб-страничку и с нее настраивать прибор? В часности нужно со странички сообщать прибору числовые значения для рассчетов. Есть нужда задавать коэффициенты полинома и т.п., отображать на страничке некоторые служебные значения а-ля телеметрия. Ну и просто отсылать команды для принудительного переключения в интересующие режимы. Собственно как показать страничку и устроить диалог с прибором? Спасибо.
Golikov A.
собственно поднять HTTP серверsm.gif как еще тоsm.gif?
HTTP сервер это дополнительная надстройка над ТСР, собственное следующий уровень протоколов. Но тут я уже не силен, я такое не практикую, у меня подключение по сокетам по своим каналам, так как мои клиенты - это наши же программы, и протоколы у нас закрытые.
smk
А как можно программно менять адрес и порт? Как потом программно актуализировать изменения?
kolobok0
Цитата(smk @ Dec 24 2013, 13:29) *
А как можно программно менять адрес и порт? Как потом программно актуализировать изменения?


А порт нафик менять? Если у вас хост является Вашей железкой? Типа можете забыть и заюзать под другие дела порт?
Или я не понял вопроса?

Для задания адреса - либо инициализация его через дисплей, флэшку или ышо какой удобный способ(хоть джамперами набирай sm.gif ).
Либо ышо просче - поднять DHCP.

По поводу передачи запросов посредством HTML-я: копайте запросы GET и POST.
smk
Цитата(kolobok0 @ Dec 24 2013, 12:45) *
А порт нафик менять? Если у вас хост является Вашей железкой? Типа можете забыть и заюзать под другие дела порт?
Или я не понял вопроса?


Изделие изготавливается с установками по умолчанию, а у заказчика настраивается сообразно ихней конфигурации сети. Порт менять не очень-то нужно, но бывали случаи когда настроенное ПО у заказчика использовало другой порт.
Golikov A.
IP адрес можно менять на лету.
заполняете структуру localm и все, вы работаете сразу на новом IP.

смена порта требует пересоздание сокетов.

у нас реализовано 2 варианта.
1. Бутлоадер.
Грузиться с дефолтными настройками, с закрытыми сокетами. Запрашивает по DHCP новый адрес, если не получает грузиться с дефолтным адресом. Пользователь по UDP имеет возможность заменить IP адрес, и задать порт, так же по UDP подает команду на создание ТСР сокетов с указанным портом.

2. Штатная программа, все настройки сохраняет во флэш, там хранятся номера портов, IP адрес по умолчанию, режим работы с DHCP или без. Эти настройки можно менять через UDP и сохранять. После загрузки все ТСР сокеты сразу создаются, если надо сменить порт, меняем, сохраняем, и перезагружаем устройство.

для UDP порт не меняемый, и всегда один.
smk
С рестартом наверно самое правильное решение. Если заработает на столе, то и на производстве не подведет.
smk
Сделал как написано в:
http://we.easyelectronics.ru/LPC/lpc1768rt...eb-updated.html

Все вроде как собралось, но при обращении получаю не свою страничку, а такое:

Код
HTTP 1.0 404 Error. File Not Found
The requested URL was not found on this server.


Что я делаю не так?
kolobok0
Цитата(Golikov A. @ Dec 24 2013, 15:10) *
...по UDP имеет возможность заменить IP адрес...


кхм. в таком случае пару вопросов:
это в одном сегменте или грамотный перебор мостов-шлюзов?
критерий тогда удалённости каков, и как долгий процесс(если не один сегмент) сканирования?


Цитата(smk @ Dec 24 2013, 22:02) *
..при обращении получаю не свою страничку, а такое:

Код
HTTP 1.0 404 Error. File Not Found..

..


это значит, что по данному адресу страничка не найдена. ответ отдал сервак.
т.е. алгоритм следующий...
выясняете работоспособность вашего девайса, уровень ICMP эхо запрос-ответ. => юзаете команду ping
юзаете с разными хитрыми параметрами - читайте справку к ней. особенно уделите внимание сборке на IP уровне.

если всё ништяк(полезно так же смотреть на нижнем уровне что получаете на уровне пакетов), дальше запрашиваете страничку по 80 порту.

смотрите на нижнем уровне такие вещи как
1) приход нефргаментированных IP пакетов (теоретически потом могут появится, если запросы на сервак будут не слабыми).
2) коректность сессии TCP
3) отдача HTML кода.

если где затык - разбираетесь с данным уровнем.
по идее в железке надо открыть порт на котором вы будете ждать запросы на вэб сервак(по умолчанию 80 порт - не SSL), и при запросе
вида GET HTML отдать "файл" размеченный вэю страницей.
всё дело контролируете на нижнем уровне снифером, и ышо смотрите что получает броузер (правая кнопка, просмотреть содержимое HTML).
сравниваете что отослали и что получили.

где то так
smk
Обратил внимание на такую штуку. Я меняю содержимое файла index.htm добавляя текстовые строки. По идее размер кода должен расти, но он не меняется вообще. Что бы это значило?
Golikov A.
UDP тем и хорош что имеет широковещательный режим, именно потому он и выбран для поиска. Посылается запрос специализированный на спец порт широковещательно, наши устройства обрабатывают и отвечают. Далее уже по обстоятельствам.

В целом мы можем потребовать достаточно специфичную конфигурацию сети, так что world wide мы не реализуем, не далее чем пройдет широковещательный запрос - ответ.
smk
Пингуется, принимает и предает все как задумано. Только свою страничку не могу показать. При этом страничка с ошибкой 404 нормально показывается. Мгновенно практически. Исходя из того, что сообщает об отсутствии файла index.htm и модификация файла не приводит к изменению размера кода делаю вывод, что страничка действительно не прикручена, хотя компилятор ее видит и обрабатывает. В web.c не наблюдаю ничего похожего на html-код. Как правильно прикрутить свою страничку?
aoreh
smk, уже давно смотрел примеры, могу что-то путать, но, по-моему, там какой-то утилитой исходное переколбашивалось в С - char[] - массив
посмотрите, нет ли в каком-нить из файлов исходников большого массива
smk
Цитата(aoreh @ Dec 25 2013, 15:02) *
smk, уже давно смотрел примеры, могу что-то путать, но, по-моему, там какой-то утилитой исходное переколбашивалось в С - char[] - массив
посмотрите, нет ли в каком-нить из файлов исходников большого массива

Переколбашивает, но размер прошивки не меняется. Вот что озадачивает. И ладно бы, но и страничку тоже не показывает. Может выложить архив с проектом?
smk
Путем сопоставления с демо-проектом кое-что подправил (ну да раньше с того и начиналось). Теперь размер файла (массива) меняется в зависимости от наполнения странички. В целом уже подвижка. Однако всеравно не показывает ее. Что можно еще смотреть? Буду рад любой подсказке.

Можно меня поздравить. Заработало. Причина была в том, что в свойствах файла в пути к нему стояли большие буквы, а на самом деле в названии директории только первая была большая, а остальные маленькие. Как так вышло я не знаю, возможно что-то прохлопал.

Теперь нужно сделать кнопку на сайте и окошко и меняющейся цифиркой из контроллера.
smk
Подключил файл HTTP_CGI.c и при попытке компиляции получил ошибку:
Код
HTTP_CGI.c(251): error:  #70: incomplete type is not allowed


Как с ней бороться, подскажите пожалуйста. Спасибо.
aoreh
Цитата(smk @ Dec 25 2013, 21:29) *
Можно меня поздравить. Заработало. Причина была в том, что в свойствах файла в пути к нему стояли большие буквы, а на самом деле в названии директории только первая была большая, а остальные маленькие. Как так вышло я не знаю, возможно что-то прохлопал.

поздравляю sm.gif
я когда только перешел на линукс часто так "прохлопывал", жертва майкрософта sad.gif
kolobok0
Цитата(smk @ Dec 25 2013, 21:29) *
..Можно меня поздравить. Заработало....Теперь нужно сделать кнопку на сайте и окошко и меняющейся цифиркой из контроллера.


проздравляю! ик!
Кнопка - то понятно как. Либо замаскированный якорь, либо форма ввода, либо всякие скрипты у клиента.
апдэйт - то либо встроенный фрэйм с прописыванием времени апдэйта, либо скрипт на апдэйт этой переменной и показом.

надеюсь не обшибся, в этой текстовой разметке sm.gif а лучше - сбегайте на форумы всякие посвящённые этим делам.
к примеру:

php.ru форум
ышо один не плохой форум

Там смотрите соответствующий раздел про HTML и иже.
smk
Код
HTTP_CGI.c(251): error:  #70: incomplete type is not allowed


Так может кто-то подскажет как с такой ошибкой бороться? Прикрутил файл HTTP_CGI.c и при компиляции получил с десяток таких сообщений.
Golikov A.
как прикрутили то?
поищите по тексту, может он у вас где дефайном объявлен, вернее есть дефайн который из этого имени что-то делает.
в кейле ctrl + shift + f
и туда HTTP_CGI.c
если вы его инклюднули, то это пипец, он же СИ а не хедер.

ну и не плохо поглядеть что там на 251 строке написано, может там чего не хватает легкого...
или может он Сишный, а у вас СРР проект, тогда надо писать
external "C"
{
}

или наоборот...
smk
Цитата(Golikov A. @ Dec 26 2013, 19:26) *
как прикрутили то?


Просто добавил в проект. При этом в демо-проекте он точно также добавлен для обработки CGI запросов в HTML. однако там компилирется без проблем, а у меня есть вон те ошибки и много. Почему?
aoreh
Цитата(smk @ Dec 26 2013, 21:55) *
Просто добавил в проект. При этом в демо-проекте он точно также добавлен для обработки CGI запросов в HTML. однако там компилирется без проблем, а у меня есть вон те ошибки и много. Почему?

так а что там, в той строке, на которую ругается?
Golikov A.
ставлю на то что CPP проект и сишный файл, или наоборот...
andrewlekar
Ставлю на то, что макрос неправильно развернулся, так как от другой версии компилятора.
aoreh
я бы поставил на то, что есть форвардная декларация, но нет полного определения (на момент использования)
или определен массив без указания размера, но пытаются использовать его sizeof.
smk
Если я попрошу посмотреть проект чтоб определиться, может не откажите в помощи? Сам я врядли что-либо смогу определить. Буду очень признателен. Спасибо.

Нажмите для просмотра прикрепленного файла
aoreh
О! похоже, я таки угадал!
там в 251 строке используется
http_EnAuth
в свою очередь это дефайн
#define http_EnAuth http_config.EnAuth

а вот объявление переменной:
extern struct http_cfg http_config;

но я нигде не нашел ни http_cfg ни самой http_config
возможно, они где-то в либах, которых не приаттачено к проекту, точнее http_config в либах, а struct http_cfg в невключенном хидере
но каких-то внешних нестандартных include не видно

а кроме самой ошибки еще что-то есть? какие-нибудь ворнинги?
сам проект скомпилить не могу, кейла у меня нет
smk
Нет, другого ничего нет. Только с десяток таких ошибок по разным строчкам.

Цитата
но я нигде не нашел ни http_cfg ни самой http_config


Я тоже не нашел. Есть только net_config.c
aoreh
Цитата(smk @ Dec 27 2013, 12:42) *
Нет, другого ничего нет. Только с десяток таких ошибок по разным строчкам.
Я тоже не нашел. Есть только net_config.c


тааак... нашел инсталляцию кейла
нашел в хидерах эти определения в файлах
rl_net_lib.h net_config.h
полный путь
c:\Keil\ARM\Pack\Keil\MDK-Middleware\5.1.3\Network\Include
поскольку сам не пользовал, как это пользовать не знаю, но, скорее всего у вас просто где-то не подключен вот этот net_config.h

ПС. да, похоже он перетащен прямо в проект, но сам по себе старый, т.е. как кто-то предполагал разные версии либ, хидеров и примеров
Golikov A.
в проекте
#include "net_config.h" "RTL.h" и подобное
меняйте на
#include <net_config.h> <RTL.h> и подобное
из проекта выкидывайте все хедеры что связаны со стэком, оставляйте только
net_config.c и прочие сишники.
библиотеку к проекту подключайте, и все соберется...
smk
Сделал как советовали. Повыкидывал, скобки поменял. Файл библиотеки подключил из кейловской директории, в свою не копировал. Из своей удалил. Пробогвал собирать - тоже самое. Теже сообщения. А что у Вас собралось?
Golikov A.
ну у меня возникли какие то траблы с web.inp
и у меня небыло LEDrun
LEDOut
я это все покоментил,

заменил файл библиотеки на свой, потому что у меня версия не 454, и все собралось...
smk
LEDrun LEDOut у меня тоже нет. Может мне 4.72 тоже поставить? Фирменный программатор купил, уже можно.
в HTTP_CGI.c есть такие строки:
Код
/* Net_Config.c */
extern struct tcp_cfg   tcp_config;
extern struct http_cfg  http_config;

так вот где оно все не ясно. так и не нашел. А у Вас оно есть?

Посмотрел демо-проект. Там такого нет вообще.
Golikov A.
есть в net_lib.c
CODE
TCP_CFG tcp_config = {
tcp_scb,
TCP_NUMSOCKS,
TCP_MAXRETRY,
TCP_RETRYTOUT * TICK_RATE,
(200 + TICK_INTERVAL - 1) / TICK_INTERVAL,
TCP_SYN_RETRY_TOUT * TICK_RATE,
TCP_INIT_RETRY_TOUT * TICK_RATE,
TCP_DEFTOUT,
TCP_MAXSEGSZ,
TCP_RECWINSZ,
TCP_CONRETRY
};

HTTP_CFG http_config = {
http_scb,
HTTP_NUMSESS,
HTTP_ENAUTH,
HTTP_PORTNUM,
HTTP_SRVID,
#if (HTTP_ENAUTH)
HTTP_AUTHREALM,
HTTP_AUTHUSER,
http_passw
#else
"","",""
#endif
};

это объявления
в нет конфиге у меня только дефайны и обработчик ошибок.


в моем проекте HTTP_CGI.c нету, а в вашем, если они были в архиве, то есть, я в этом файле ничего не менял.
Только вот с вашей бибилиотекой у меня не нашлась куча фукнций и определений, когда заменил на свой файл библиотеки сразу полегчало и все нашлось...

мне кажется у вас несовпадение файла библиотеки и заголовков, возьмите файл из кейла тот что соответствует заголовкам. И второй момент, ваш проект что вы нашли мог быть под новый стэк, и тогда тоже может не работать на библиотеке от более старого стэка.
smk
Да вроде бы с нуля все делал. На машине действительно есть 4.21 версия. Наверно снесу обе и поставлю 4,72. У Вас 4,72 или 4,72а?
Golikov A.
4.72.10.0

кстати в ней в стэке появился какой то промежуточный буфер, теперь частота вызовов call_back функции 5 мСек, а раньше была 1 мСек... вот такие вот дела. Общая скорость передачи данных не изменилась, а вот скорость реакции упала маленько... хоть на LwIP переходи обратно....
smk
Не думаю чтоб в моих приложениях это было критично. На сегодня если я за секунду успею раз 100 отдать буфер в 1кБ, то устроит. Интересно, но получается более 200 пакетов за 1 сек не отправить. Так? даже наверно меньше.
Golikov A.
получается так... То есть если пакеты маленькие то и скорость здорово падает...
smk
Поставлю 4.72 без а. Все едино как сделаю на кейловском стеке, по плану все повторить, но с Lwip.
Golikov A.
мы тоже решили что-то на LwIP перелазить. Хорошо работать с поддерживаемой библиотекой, в lwIP косяки все на тебя ложатся, но зато там гораздо больше контроль. Можно и 0 копировальный буфер сделать, и прочие радости...
smk
С наступившим! И так 4,72 я поставил. Прешние проекты компилируются без проблем. Хотелось бы продолжить.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.