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

Пытаюсь запустить эзернет на МК. В качестве внешнего PHY использую KSZ8721. Задача следующая: сформировать пакет определенной структуры (т.е. условно 20-28 байт параметр1, 29-36 байт параметр2, 37-50 параметр3 и т.д.), записать в эти параметры значения с АЦП и передать определенное количество пакетов в секунду.

Подключение MII, режим full duplex.

Собственно в связи с вышеизложенным следующие вопросы:

1. Каким образом можно сформировать произвольную структуру пакета?

2. Будет ли достаточно для данных целей обычной инициализации эзернета в кубе и передачи пакетов функцией HAL_ETH_TransmitFrame()? Код функции представлен ниже.

/**
  * @brief  Sends an Ethernet frame. 
  * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
  *         the configuration information for ETHERNET module
  * @param  FrameLength: Amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
{
  uint32_t bufcount = 0U, size = 0U, i = 0U;
  
  /* Process Locked */
  __HAL_LOCK(heth);
  
  /* Set the ETH peripheral state to BUSY */
  heth->State = HAL_ETH_STATE_BUSY;
  
  if (FrameLength == 0U) 
  {
    /* Set ETH HAL state to READY */
    heth->State = HAL_ETH_STATE_READY;
    
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
    
    return  HAL_ERROR;                                    
  }  
  
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  if(((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
  {  
    /* OWN bit set */
    heth->State = HAL_ETH_STATE_BUSY_TX;
    
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
    
    return HAL_ERROR;
  }
  
  /* Get the number of needed Tx buffers for the current frame */
  if (FrameLength > ETH_TX_BUF_SIZE)
  {
    bufcount = FrameLength/ETH_TX_BUF_SIZE;
    if (FrameLength % ETH_TX_BUF_SIZE) 
    {
      bufcount++;
    }
  }
  else 
  {  
    bufcount = 1U;
  }
  if (bufcount == 1U)
  {
    /* Set LAST and FIRST segment */
    heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS;
    /* Set frame size */
    heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1);
    /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
    heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
    /* Point to next descriptor */
    heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
  }
  else
  {
    for (i=0U; i< bufcount; i++)
    {
      /* Clear FIRST and LAST segment bits */
      heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
      
      if (i == 0U) 
      {
        /* Setting the first segment bit */
        heth->TxDesc->Status |= ETH_DMATXDESC_FS;  
      }
      
      /* Program size */
      heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
      
      if (i == (bufcount-1U))
      {
        /* Setting the last segment bit */
        heth->TxDesc->Status |= ETH_DMATXDESC_LS;
        size = FrameLength - (bufcount-1U)*ETH_TX_BUF_SIZE;
        heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
      }
      
      /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
      heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
      /* point to next descriptor */
      heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);
    }
  }
  
  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
  if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
  {
    /* Clear TBUS ETHERNET DMA flag */
    (heth->Instance)->DMASR = ETH_DMASR_TBUS;
    /* Resume DMA transmission*/
    (heth->Instance)->DMATPDR = 0U;
  }
  
  /* Set ETH HAL State to Ready */
  heth->State = HAL_ETH_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(heth);
  
  /* Return function status */
  return HAL_OK;
}

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


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

Я не знаю куб, но вопрос: вы хотите данные гнать на канальном уровне? Т.е. TCP/IP или UDP вам не нужен?

 

2. Будет ли достаточно для данных целей обычной инициализации эзернета в кубе и передачи пакетов функцией HAL_ETH_TransmitFrame()? Код функции представлен ниже.

Это низкоуровневая функция передачи ETHERNET-фрейма через среду (витую пару в вашем случае). Конечно, можно гнать данные на этом уровне, но как вы будете доставлять их адресату? Или как кто-то будет запрашивать их у вашей железки? Ведь адресация в таком случае будет возможно только по mac-адресу. А в локальных сетях принято использовать что-то повыше уровнем, например IPv4. Значит вам нужен TCP/IP стек, пусть и не полный. Всё зависит от ваших требований? Чего вы хотите? Что за прибор, куда будет подключаться, кто будет обмениваться с ним данными?

 

Рекомендую познакомиться хотя бы бегло с 7-уровневой моделью OSI. Затем почитать про TCP/IP стеки. Я использовал lwip. Прикручиватеся не совсем просто, если нет опыта. У меня ушло недели полторы на адаптацию драйвера MAC+PHY, и портирование стека на свою платформу (LPC4337 + внешний фиттер).

 

P.S. Судя по вашим постам на форуме, вы методично и последовательно ваяете что-то измерительное с выходом в сеть)))

 

P.S.S. Логический анализатор вам и здесь может понадобиться. У вас kszшка-то хоть ответила по MDC?

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


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

Я не знаю куб, но вопрос: вы хотите данные гнать на канальном уровне? Т.е. TCP/IP или UDP вам не нужен?

 

 

Это низкоуровневая функция передачи ETHERNET-фрейма через среду (витую пару в вашем случае). Конечно, можно гнать данные на этом уровне, но как вы будете доставлять их адресату? Или как кто-то будет запрашивать их у вашей железки? Ведь адресация в таком случае будет возможно только по mac-адресу. А в локальных сетях принято использовать что-то повыше уровнем, например IPv4. Значит вам нужен TCP/IP стек, пусть и не полный. Всё зависит от ваших требований? Чего вы хотите? Что за прибор, куда будет подключаться, кто будет обмениваться с ним данными?

 

Рекомендую познакомиться хотя бы бегло с 7-уровневой моделью OSI. Затем почитать про TCP/IP стеки. Я использовал lwip. Прикручиватеся не совсем просто, если нет опыта. У меня ушло недели полторы на адаптацию драйвера MAC+PHY, и портирование стека на свою платформу (LPC4337 + внешний фиттер).

 

P.S. Судя по вашим постам на форуме, вы методично и последовательно ваяете что-то измерительное с выходом в сеть)))

 

P.S.S. Логический анализатор вам и здесь может понадобиться. У вас kszшка-то хоть ответила по MDC?

Функционал устроства верный :biggrin:. Это мой дипломный проект, по сути представляет из себя некий измерительный блок, который оцифровывает показания датчика температуры и передает их по ethernet.

Вообще задача сформулирована следующим образом: необходимо передать 1000 ethernet пакетов с определенной структурой в секунду. В каждом пакете должны содержаться: значение измеренной температуры, время, дата и еще несколько параметров. Сам блок подключается к компьютеру, к нему никаких обращений не требуется, т.е. она просто гонит данные и все.

 

Читаю про TCP/IP стек, но теория без практики воспринимается сложно. Пытаюсь найти примеры с реализацией lwip.

Пробовал пинговать плату при обычной инициализации ethernet (без lwip), результата нет.

Изменено пользователем remixx

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


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

еобходимо передать 1000 ethernet пакетов

Здесь неоднозначность терминов: ethernet-пакте, это фрейм канального уровня. На этом уровне нет ip-адреса. Только mac-адрес, служебные данные, контрольная сумма и пакет полезных данных. Чтобы это всё на компьютере получить и использовать, нужна специальная самописаня софтина.

Читаю про TCP/IP стек, но теория без практики воспринимается сложно. Пытаюсь найти примеры с реализацией lwip.

Их много в сети. Вопрос, какой вам подойдёт.

Пробовал пинговать плату при обычной инициализации ethernet (без lwip), результата нет.

И никогда не будет. На пинг отвечает кусочек стека, а у вас его нет. "Чистый" ethernet ни на что отвечать не умеет. по-сути это uart (ооочень грубо, но по смыслу верно). Только этот uart передаёт данные не по-байтно, а минимум пакетом (сколько точно не помню). И длина этого пакета варьируется от минимума до максимума. Вот внутрь уже можно положить нечто похожее на протокол, например tcp/ip.

 

 

Это мой дипломный проект

Вообще задача для дипломного проекта вполне решаема, но времени нужно этак полгода. И это при том, что вам читали (а вы не пропускали) соответствующие дисциплины. Ну, а так... до года может уйти, в зависимости от подготовки и желания.

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


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

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

 

Но пинговаться ваш прибор при этом не будет :(

 

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


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

Вообще задача сформулирована следующим образом: необходимо передать 1000 ethernet пакетов с определенной структурой в секунду.

Ну если препод хотел сказать именно то, что написал, то Вам остаётся только посочувствовать. :laughing:

Уже знаете как будете из под винды добираться до уровня ETHERNET-фреймов? :biggrin: Это будет посложнее, чем полное изучение TCP-стека.

Совет: срочно бежать к преподу и переформулировать задачу на "передачу через UDP" или через TCP-сокет. А ещё лучше: "через любой сетевой протокол работающий поверх ETHERNET".

Даже если препод не понимает разницы между ETHERNET-кадрами и TCP/UDP-кадрами, то достаточно в приёмной комиссии оказаться одному человеку, кто понимает и можете смело ставить крест на защите. Если бы я был в комиссии, а Вы с таким ТЗ притащили проект сделанный на TCP/UDP, то я бы завалил. :biggrin:

 

2. Будет ли достаточно для данных целей обычной инициализации эзернета в кубе и передачи пакетов функцией HAL_ETH_TransmitFrame()? Код функции представлен ниже.

Думаю что не будет. Ибо как докажете, что что-то вообще передаётся?

А значит: на стороне приёмной стороны нужно писать что-то, что будет принимать эти пакеты и отображать инфу из них.

 

Сам блок подключается к компьютеру, к нему никаких обращений не требуется, т.е. она просто гонит данные и все.

И как доказать, что компьютер эти данные принимает?

 

никакого стека (даже lwip) для этого не понадобится.

Да ладно!? А какой МК умеет передавать UDP-кадры самостоятельно, без TCP/IP-стека?

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


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

Функционал устроства верный :biggrin:. Это мой дипломный проект, по сути представляет из себя некий измерительный блок, который оцифровывает показания датчика температуры и передает их по ethernet.

Вообще задача сформулирована следующим образом: необходимо передать 1000 ethernet пакетов с определенной структурой в секунду. В каждом пакете должны содержаться: значение измеренной температуры, время, дата и еще несколько параметров. Сам блок подключается к компьютеру, к нему никаких обращений не требуется, т.е. она просто гонит данные и все.

Для справки. Термина "Функционал" в русском техническом языке нет вообще...

И вот, чисто по жизни, есть вопрос. "Температура" - она что так быстро меняется? Это что температура плазмы или газовой струи в ракетном сопле? Какова масса объекта, у которого измеряют температуру?

А сам датчик, какая у него постоянная времени по температуре? Ну пусть десятая доля секунды... Тогда у Вас что, имеются тысячи датчиков, если в задании "1000 ethernet пакетов в секунду"... Или же это сказано так, для балды? Но ведь сказано, что "блок" находится "рядом", т.е не далее 300 метров, потому как не факт, что такие кадры пройдут по сетевому оборудованию...

Вот...

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


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

Ну если препод хотел сказать именно то, что написал, то Вам остаётся только посочувствовать. :laughing:

Да и так уже понятно, что задание выдано от балды :rolleyes:

Интересно, а автору топика это действительно интересно и нужно, или это всего лишь желание только защитить диплом?

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


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

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

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

Пары не прогуливал :biggrin: , большинство курсов в основном были связаны с элементной базой, принципом работы ИМС, их проектированием и т.п.

На единственном курсе, связанным с программированием, мы по-этапно выводили символ нажатой кнопки на ЖКИ в течение 3-х лаб, писалось все на ассемблере. Поэтому "уровень" соответствующий.

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

Собственно вот с таким "багажом" я и подошел к работе над вышеупомянутой задачей), поэтому возникает куча вопросов на каждом шагу.

 

Ну ладно, это небольшое лирическое отступление :biggrin:

 

По теме:

под пакетом преподаватель имел ввиду фрейм (IEEE 802.3), структуру представил ниже.

 

post-93818-1526362414_thumb.jpg

 

То есть насколько я понял, преамбула, header mac, длина и LLC формируются автоматически при отправке, с указанными значениями при инициализации, а в блок данных (data unit), необходимо завести требуемые значения измерений. Думаю это удобно сделать через struct, пример:

 

struct Data {
int32_t temperature;
uint8_t time;
uint8_t date;
}

Перед каждой отправкой приравниваю переменные к полученным значениям измерений и отправляю их.

После чего некая задержка, ну из первого что пришло в голову 1 сек / 1000 = 1 мс, соответственно её и беру.

И снова измерение, формирование фрейма, отправка. И так 1000 раз.

 

По вашим советам стал искать информацию, как осуществить передачу, используя lwip.

Наткнулся вот на такой пример. С помощью куба он инициализирует ethernet и подключает lwip. В коде добавляет функции для udp и отправляет тестовый фрейм.

Вроде бы это то что нужно)

 

Кстати для анализа полученных пакетов использую wireshark.

Изменено пользователем remixx

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


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

Перед каждой отправкой приравниваю переменные к полученным значениям измерений и отправляю их.

После чего некая задержка, ну из первого что пришло в голову 1 сек / 1000 = 1 мс, соответственно её и беру.

Тупых "задержек" быть не должно. Не знаю как там работает куб или lwip (не пользовал никогда), но в любом случае формировать следующий кадр для отправки нужно только после получения уведомления о завершении отправки предыдущего кадра.

Например простейший алгоритм: завести цикл (прерывание) работающий с частотой 1 кГц, при каждом проходе цикла проверять стоит ли флаг завершения отправки предыдущего ETHERNET-кадра и только если стоит - формировать следующий кадр.

Ещё лучше добавить FIFO кадров на несколько позиций и писать в него если в FIFO есть место (и стартовать передачу, если предыдущее завершение отправки произошло при пустом FIFO). В обработчике события "завершения отправки кадра" ETHERNET-драйвера отправлять следующий кадр из FIFO ели там есть хотя-бы один кадр.

 

И снова измерение, формирование фрейма, отправка. И так 1000 раз.

Измерение должно идти независимо от отправки. В своей задаче RTOS или ISR. Измерение и передача в сеть должны быть связаны через механизм FIFO. Иначе не получите ожидаемой частоты (вообще никакой стабильной частоты преобразования не получите - она будет плавать).

 

По вашим советам стал искать информацию, как осуществить передачу, используя lwip.

С помощью куба он подключает lwip. В коде добавляет функции для udp и отправляет тестовый фрейм.

Определитесь уже что Вам всё-таки нужно - описанные выше Вами ETHERNET-кадры или всё-же UDP?

 

Кстати для анализа полученных пакетов использую wireshark.

Если на защите достаточно будет показать приём в шарке, то наверное можно и так.

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


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

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

ОК, это радует! :rolleyes:

По теме:

под пакетом преподаватель имел ввиду фрейм (IEEE 802.3), структуру представил ниже.

Стандартная картинка из документа :rolleyes: Опять таки здесь можно двусмысленно толковать. В data payload можно положить как произвольные данные, тогда прнимающая сторона должна будет уметь их принять и расшифровать. На этом уровне у вас не будет ip-адреса, следовательно пакеты будут находить адресата только по mac-адресу. Следовательно, что с ними сделает более-менее умный маршрутизатор - я не знаю, тут у меня опыта нет. Также в data payload можно положить данные, которые сгенерирует любой tcp/ip-стек. А вот уже в данные udp или tcp можно положить снова ваши произвольные данные. Но при этом пакеты будут "настоящие". Смогут ходить к адресату по ip-адресу. Более того, вы можете обращаться к железке более-менее стандартными способами (web, ftp, tftp, telnet) и получать свои данные, например, браузером.

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

Ну тогда ваш диплом не по теме. Даже мне с некоторым опытом в данной области понадобилось бы около месяца на выполнения этой работы (я имею в виду ацп, сеть, отладка, тестирование образца). Хотя тут всё индивидуально, уверен, кто-то и за день сделает :rolleyes:

И снова измерение, формирование фрейма, отправка. И так 1000 раз.

Тут надо смотреть как работает MAC-модуь микроконтроллера. Это всё-таки не uart в прямом смысле. И по завершению отправки пакета он должен генерировать прерывание, либо выставлять флаг в аппаратном регистре. К сожалению, STM для работы с сетью не использовал, ничего не подскажу. Но поищите в сети проекты связки stm + lwip. Наверно можно как-то вытащить исходники драйверов mac, и подкорректировать их под себя.

Кстати для анализа полученных пакетов использую wireshark.

Крайне полезная программа! Без неё никак. У вас что-нить приходит? Опять же вайршарк - хорошо, но чем будете данные в готовой железке смотреть?

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


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

Да ладно!? А какой МК умеет передавать UDP-кадры самостоятельно, без TCP/IP-стека?
Любой, у которого есть MAC. Минимальный UDP протокол простой как бревно - формируем образ Eth фрейма с UDP Payload в памяти (в виде структуры) и отправляем это в качестве Eth пакета наружу. Это всё. lwip для этого не нужен.

 

Если нужна полная поддержка IP стека (включая ICMP и ARP, а так же что угодно на приём), то тут уже как минимум lwip потребуется.

 

 

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


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

Посмотрите здесь https://github.com/ntruchsess/arduino_uip и в гугле есть описание фреймов. Ключевые слова Arduino & ENC28J60

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


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

Любой, у которого есть MAC. Минимальный UDP протокол простой как бревно - формируем образ Eth фрейма с UDP Payload в памяти (в виде структуры) и отправляем это в качестве Eth пакета наружу. Это всё. lwip для этого не нужен.

Чтобы засрать широковещательными UDP всю сеть?

 

Если нужна полная поддержка IP стека (включая ICMP и ARP, а так же что угодно на приём), то тут уже как минимум lwip потребуется.

Как минимум lwip избыточен. Есть гораздо более лёгкие стеки. Даже в примерах IAR-а имелись.

 

Но поищите в сети проекты связки stm + lwip. Наверно можно как-то вытащить исходники драйверов mac, и подкорректировать их под себя.

Лучше взять примеры из IAR для работы с Ethernet.

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


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

Чтобы засрать широковещательными UDP всю сеть?
А кто заставляет посылать широковещательные? Можно MAC адрес приёмника забить прямо в пакет. Для сдачи задания вполне достаточно.

 

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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