Перейти к содержанию
    

1. Ваш Phy чип определяется?

 

что в регистрах id1 и id2, т.е. идентификатор для RTL8201 определяется корректно? Пробегитись с отладчиком, после указанных строк в if попадаете?

 

2. Где 'Net_lib.c'?

Определяется. Пробежался.

Net_lib.c - что такое?

 

init_ethernet(); закоментил, dhcp_disable (); добавил. Пингуетя!!! Ура!!!

 

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

 

int main (void) 
{
    
    USART1_Init();    
//    init_ethernet();
  init_TcpNet ();
    dhcp_disable (); 

  /* Setup and enable the SysTick timer for 100ms. */
  SysTick->LOAD = (72000000 / 10) - 1;
  SysTick->CTRL = 0x05;
    
  while (1)
    {    

    timer_poll ();
        main_TcpNet();
            
    } /* Loop forever */
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

дальше уже дело техники,

все очень просто!

 

//выделяете сокет 
SocketNumber = tcp_get_socket (TCP_TYPE_SERVER | TCP_TYPE_DELAY_ACK | TCP_TYPE_FLOW_CTRL | TCP_TYPE_KEEP_ALIVE, 0, 65535, tcp_callback); 

//если получилось, ставите его на прослушку - это сокет который принимает конект
if (SocketNumber != 0)
  {
    /* Start listening on TCP port DevEthInfo.CtrlPort */
    tcp_listen (SocketNumber, PortNumber);
  }

 

 

tcp_callback - это функция обработки событий

 

 

 uint16_t tcp_callback (uint8_t soc, uint8_t evt, uint8_t *buf, uint16_t len) {
  /* This function is called by the TCP module on TCP event */
  /* Check the Net_Config.h for possible events.            */
  switch (evt)
  {
        case TCP_EVT_DATA: //ïðèøëè äàííûå
            /* TCP data frame has arrived, data is located at *buf, */
            /* data length is len. Allocate buffer to send reply.   */
            break;    

    case TCP_EVT_CONREQ:
      /* Remote host is trying to connect to our TCP socket. */
      return (1);
      
    case TCP_EVT_ABORT:
      break;
      
    case TCP_EVT_CONNECT:
      /* Socket is connected to remote peer. */
            return (1);
    
    case TCP_EVT_CLOSE:
      break;
                    
      
    case TCP_EVT_ACK: 
      /* Our sent data has been acknowledged by remote peer */
      break;
  }
  return (0);

 

в эту функцию надо написать прием данных по событию TCP_EVT_DATA, buf - данные, len - длинна

учтите если вы никуда не сохранили данные они просто пропадут

 

чтобы послать данные

tcp_send (SocketNumber, sendbuf, SendDataSize);

 

 

для сброса окна

tcp_reset_window(SocketNumber)

это функция нужна если сокет делали с флагом TCP_TYPE_FLOW_CTRL

она сбрасывает окно, в кейловском стеке окно сбрасывается разом, по кусочкам из него не вычитывается.

 

 

 

самое простое - это сервер

в функцию приема воткнуть посылку данных обратно и сброс окна.

 

 

 

 

А да забыл.

после того как вы это сделали и запустили, надо конектиться из винды(юникса, макоса и бла бла бла) к этому сокету, по заданному порту, и слать данные.

 

со стороны винды(юникса) самое простое взять netcat

это программка консольная которая позволяет устанавливать ТСР соединение по заданному порту, слать и принимать данные

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такое сообщение об ошибке получилось:

main_eth.c(48): error:  #20: identifier "TCP_TYPE_KEEP_ALIVE" is undefined

и ведь действительно в rtl.h не определено. Как поступить?

 

Попутно хотелось бы понимать ситуацию когда обращается скажем 2 и более клиента, при этом каждому нужны свои данные. Как их различать и отслеживать? Количество одновременных коннектов, я так понимаю лимитируется только размером памяти?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у меня такое написано

 

#define TCP_TYPE_SERVER    0x01   /* Socket Type Server (open for listening) */
#define TCP_TYPE_CLIENT    0x02   /* Socket Type Client (initiate connect)   */
#define TCP_TYPE_DELAY_ACK 0x04   /* Socket Type Delayed Acknowledge         */
#define TCP_TYPE_FLOW_CTRL 0x08   /* Socket Type Flow Control                */
#define TCP_TYPE_KEEP_ALIVE 0x10  /* Socket Type Keep Alive                  */
#define TCP_TYPE_CLIENT_SERVER (TCP_TYPE_SERVER | TCP_TYPE_CLIENT)

 

может старая версия стэка... она к 4.3 изменилась, FLOW_CTRL добавился вроде бы

 

надо про ТСР читать.

Соединение ТСР сокет - сокет, сокеты различаются по IP и номеру порта.

по конекту вызывается калбэк, с параметрами того кто конектится,

В установленное соединение сокет - сокет никто влезть не может.

 

у меня 3 сокета в проекте, на каждом свой тип данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, что уделяетемне время!

 

Версия кейла у меня 4.54, может там и нет такого. Его добавить или наоборот убрать? Может файлы просто заменить в кейле на те, что от более нового?

 

Теперь про сокеты не соображу. Вот выполнилось условие if (SocketNumber != 0). Будет вызван tcp_listen. Я так понимаю оттуда будет вызван tcp_callback. У каждого клиента будет свой номер или как мне различить их?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:)

нет такого флага в вашем кейле и вашей библиотеке, значит его использовать нельзя.

это от 4.72, когда прошла смена стэка мне не ведомо, в 3.7 flow контроля не было по моим данным

 

Вам надо концептуально понять

Сокет - это розетка. Воткнули вилку - розетку заняли

 

SocketNumber - это идентификатор этой розетки.

если в него кто-то подсоединится он собой этот сокет займет. И все что сокет пошлет, будет для него, а все что он пошлет придет в этот сокет

если номер 0 - то значит сокет не сделался, для этого проверка, а если он сделался, то к нему подключается прослушка и калбэк функция

 

обратите внимание что в

uint16_t tcp_callback (uint8_t soc, uint8_t evt, uint8_t *buf, uint16_t len)

 

есть параметр soc - это как раз этот номер, то есть если вы сделаете много сокетов, то они будут вызывать калбэк функцию каждый со своим номером.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:)

нет такого флага в вашем кейле и вашей библиотеке, значит его использовать нельзя.

это от 4.72, когда прошла смена стэка мне не ведомо, в 3.7 flow контроля не было по моим данным

 

Вам надо концептуально понять

Сокет - это розетка. Воткнули вилку - розетку заняли

 

SocketNumber - это идентификатор этой розетки.

если в него кто-то подсоединится он собой этот сокет займет. И все что сокет пошлет, будет для него, а все что он пошлет придет в этот сокет

если номер 0 - то значит сокет не сделался, для этого проверка, а если он сделался, то к нему подключается прослушка и калбэк функция

 

обратите внимание что в

uint16_t tcp_callback (uint8_t soc, uint8_t evt, uint8_t *buf, uint16_t len)

 

есть параметр soc - это как раз этот номер, то есть если вы сделаете много сокетов, то они будут вызывать калбэк функцию каждый со своим номером.

 

Появилось время продолжить.

 

Про сокет я понял. Только не соображу как все устроено. Если сокетов несколько, то как все изменится программно? SocketNumber я так понимаю переменная которую надо объявить? "есть параметр soc - это как раз этот номер" т.е. всякий раз когда вызвана tcp_callback используя soc можно узнать для какого сокета произошел вызов и соответственно обработать, так? Только вот не ясно. Скажем есть сокеты с номерами 1,2,3,4. Если сокет №2 освободился, то остальные так и останутся со своими номерами? "ставим на прослушку" имеется в виду, что нужно постоянно проверять значение SocketNumber?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С помощью терминальной программы: http://www.hw-group.com/products/hercules/index_en.html пробовал отсылать пару байт. В режиме TCP-Client соединение происходит и Wireshark показывает, что плата отвечает. Однако я никак не могу попасть в tcp_callback. Как правильно проверить связь? Порт задал 80.

 

 

На всякий случай выкладываю архив с проектом в последней эволюционной стадии, может делаю чего не так. Компилируется, пингуется.

ETH_keil.zip

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть ли какая=то терминальная программа для ethernet? искал в сети, но что-то безрезультатно...

 

Netcat

PuTTY

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

надо знать про сокеты вот что.

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

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

 

потом просто пишите текст в командную строку, и данные пошли.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

post-3446-1387726852_thumb.jpg

 

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

 

Теперь интересует такая штука. Вот я получил указатель и число байт. Я так понимаю, что из tcp_callback нужно выйти как можно быстрее? т.е. живенько все скопировать в свой буфер и выйти из tcp_callback?

А как услать свой пакет в ответ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

чтобы послать данные надо их как бы послать:)

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

tcp_send - отправляем данные

 

перед отправкой имеет смысл проверить

tcp_get_state - чтобы был в конекте

tcp_check_send - что может оправлять

tcp_max_dsize - сколько макс данных можно заслать, мало ли вдруг на другом конце окно забилось.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

tcp_get_buf

не спроста так называется, не спроста с тср начинается%)..

это штука буфер для отправки, но не просто буфер, это буфер в очереди ТСР сообщений, за которым следит ТСР.

 

естественно если у вас кончиться память то будет ошибка, там даже есть обработчик критических ошибок с while (1) в конце, чтоб у новичков проекты висли, наверное%)...

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

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...