реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> STM32F107RCT6 + KSZ8721 (ethernet)
jcxz
сообщение May 15 2018, 12:56
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(XVR @ May 15 2018, 14:46) *
А кто заставляет посылать широковещательные? Можно MAC адрес приёмника забить прямо в пакет. Для сдачи задания вполне достаточно.

Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован?
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 15 2018, 14:23
Сообщение #17


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (jcxz @ May 15 2018, 20:56) *
Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован?

Мне кажется можно статично вбить ip-адреса железки (задать самому любой свободный), и адрес приёмника. Нужно будет считать контрольные суммы. Но я не уверен за результат, т.к. никогда так не делал, и не стал бы советовать кому-либо делать. Хотя для диплома - пойдёт. Но ещё раз повторюсь: диплом довольно сложен. Преподаватель обязан консультировать студента. Но я думаю, что преподаватель не очень компетентен.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 15 2018, 15:49
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(haker_fox @ May 15 2018, 17:23) *
Преподаватель обязан консультировать студента. Но я думаю, что преподаватель не очень компетентен.

Да судя по формулировке задачи я бы сказал, что преподаватель вообще не копенгаген laughing.gif
Go to the top of the page
 
+Quote Post
Alex11
сообщение May 15 2018, 16:26
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Цитата
Мне кажется можно статично вбить ip-адреса железки (задать самому любой свободный), и адрес приёмника.

Работать будет, если в одной подсети. Проверено.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 15 2018, 23:41
Сообщение #20


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (Alex11 @ May 16 2018, 00:26) *
Работать будет, если в одной подсети. Проверено.

Ну в общем для диплома действительно пойдёт. Но для реального проекта - только с большим количеством ограничений)))


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
XVR
сообщение May 16 2018, 04:07
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(jcxz @ May 15 2018, 15:56) *
Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован?

Так же, как и MAC - руками (статически). И даже работать будет. rolleyes.gif
Go to the top of the page
 
+Quote Post
remixx
сообщение May 16 2018, 06:59
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



В указанном примере как раз таки MAC и ip адреса вбиваются вручную, все хидеры lwip проставляет автоматически, все что остается это засунуть данные в payload.
По советам jcxz решил, что надо добавлять в проект и RTOS.
Из той информации, которую изучил на данный момент, имею следующее представление:
1. Создаю 2 задачи. В первой провожу инициализацию АЦП и в бесконечном цикле отправляю запрос на единичное преобразование, записывая результат в соответствующий элемент структуры и ставя её в очередь.
Примерный код:
Код
// Добавляю глобальную переменную для очереди //
osMailQId strout_Queue

// Указываю размер очереди //
#define MAIL_SIZE (uint32_t) 1 // Насколько я понимаю, чтобы гарантированно передать по ethernet значение преобразования, в очереди должен быть всего 1 элемент, соответственно если она заполнена, то первая задача находится в блокированном состоянии

// Задаю структуру с данными //
typedef data_t {
   int32_t temperature;
   uint8_t time;
   uint8_t date;
} data;

// Создаю задачу RTOS //
osThreadDef(ADC, StartTaskADC, osPriorityNormal, 0, 128);
ADCHandle = osThreadCreate(osThread(ADC), NULL);

// Создаю очередь //
osMailQDef(stroutqueue, MAIL_SIZE, data;
strout_Queue = osMailCreate(osMailQ(stroutqueue), NULL);

// Создаю функцию первой задачи //
void StartTaskADC(void const * argument)
{
  /* USER CODE BEGIN StartTaskADC */
  struct_out *qstruct; // добавляю переменную типа передаваемой в очереди структуры
  ADC_Init; // выполняю инициализацию АЦП (отправляю набор команд по SPI, использую функцию HAL_SPI_Transmit, можно ли взять её или для таких применений нужно с DMA каким-нибудь?)
  /* Infinite loop */
  for(;;)
  {
    qstruct = osMailAlloc(strout_Queue, osWaitForever); // выделяю память под очередь
    qstruct->temperature = ADC_ReadValue; // записываю в элемент структуры temperature полученное значение из АЦП (посылаю команду единичного преобразования через HAL_SPI_Transmit, аналогичный вопрос)
    qstruct->time = 1 // записываю в элемент структуры time рандомное значение (пока не важно)
    qstruct->date = 2 // записываю в элемент структуры date рандомное значение (пока не важно)
    osMailPut(strout_Queue, qstruct); // отправляю структуру в очередь
    osDelay(1);
  }
  /* USER CODE END StartTaskADC */
}


2. Создаю вторую задачу, которая будет инициализировать UDP, получать измеренное значение температуры из очереди и отправлять его.
Код
// Создаю глобальные переменные структур, требующихся для передачи по ethernet //
extern struct netif gnetif;
static struct udp_pcb *udp_Pcb1_p;

// Создаю задачу RTOS //
osThreadDef(ETH, StartTaskETH, osPriorityNormal, 0, 128);
ETHHandle = osThreadCreate(osThread(ETH), NULL);

// Создаю функцию второй задачи //
void StartTaskETH(void const * argument)
{
  /* USER CODE BEGIN StartTaskETH */
  osEvent event; // добавляю переменную типа структуры состояния очереди
  struct_out *qstruct; // добавляю переменную типа передаваемой в очереди структуры
  UDP_Init; // выполняю инициализацию UDP (в ней создается новое подключение UDP (udp_new), вручную записывается mac и ip адрес компа, биндится соединение (udp_bind) и проверяется на наличие ошибок)
  /* Infinite loop */
  for(;;)
  {
    static const char packet[]; // создаю переменную для данных, которые буду класть в payload
    event = osMailGet(strout_Queue, osWaitForever); // забираю данные из очереди
    if (event.status == osEventMail) // проверяю состояние очереди
    qstruct = event.value.p; // присваиваю переменной типа структуры очереди указатель на элемент очереди
    packet[] = qstruct->temperature, qstruct->time, qstruct->date; // записываю полученные данные в переменную для payload
    SendPacket; // вызываю функцию отправки udp (здесь указывается ip адрес клиента, создается буффер для передачи по eth, в который заносим вышеуказанный packet[], заносим все это в payload и отправляем (udp_sendto)
    ethernetif_input(&gnetif); // вписываю стандартный код для обеспечения постоянной работы стека
    sys_check_timeouts; // продолжение... (говорят, что эти 2 строки можно заменить MX_LWIP_Process() тогда и extern struct netif gnetif не нужно, но пока попробую запуститься так)
    osDelay(1);
  }
  /* USER CODE END StartTaskETH */
}


Где-то что-то упустил или вообще все кардинально неправильно?))

Сообщение отредактировал remixx - May 16 2018, 07:03
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 16 2018, 07:52
Сообщение #23


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



Я бы рекомендовал не использовать ось. Я не знаю ваши строки, но вы можете закопаться и не успеть. ОС - это не просто многозадачность, это ещё и особый подход к проектированию ПО. Например, передача данных между процессами, обработка прерываний и т.п. Если у вас, конечно, есть опыт работы с операционными системами, тогда другой вопрос)


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
remixx
сообщение May 17 2018, 02:35
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



Цитата(haker_fox @ May 16 2018, 07:52) *
Я бы рекомендовал не использовать ось. Я не знаю ваши строки, но вы можете закопаться и не успеть. ОС - это не просто многозадачность, это ещё и особый подход к проектированию ПО. Например, передача данных между процессами, обработка прерываний и т.п. Если у вас, конечно, есть опыт работы с операционными системами, тогда другой вопрос)

на крайняк сделаю с "тупыми" задержками biggrin.gif
посмотрю еще сегодня ISR.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 17 2018, 06:35
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(remixx @ May 16 2018, 09:59) *
По советам jcxz решил, что надо добавлять в проект и RTOS.
...
osDelay(1);
...
osDelay(1);
...
Где-то что-то упустил или вообще все кардинально неправильно?))

А что кардинально изменилось? Точно так же всё на задержках сделали. laughing.gif
"Использовать ОС" - это не просто рассовать функции по задачам. Это в первую очередь означает, что работа должна производиться event-driven.
Т.е. - Ваши задачи должны не всё время долбить что-то (и зачем тогда вообще многозадачность?), а должны обрабатывать события.
Т.е. - в задаче АЦП дали старт преобразования и после этого задача должна ждать завершения преобразования, после чего считать данные, обработать их, и запустить следующее преобразование. Ждать она должна, ожидая готовности какого-либо элемента синхронизации ОС (мэйлбокса, семафора и т.п.). Этот мэйлбокс переводиться в сигнальное состояние может например из ISR завершения преобразования АЦП (а лучше конечно из ISR завершения DMA-пересылки блока данных АЦП->ОЗУ).
То же самое и с задачей отправки данных в ETHERNET.

Если у Вас задачи всё время что-то долбят, то тут никакой многозадачности нет, одна фикция, пыль в глаза.
Наберите в гугле "event-driven programming".
В упрощённом виде работа с АЦП должна выглядеть так:
CODE
void AdcReadyIsr()
{
AdcConfirm();
OSMboxPost(mboxAdcReady);
}
void AdcTask()
{
AdcInit();
ClearAndEnableIrqAdcReady();
while (1) {
AdcStart();
OSMboxPend(mboxAdcReady);
DataQueueWrite(AdcRead());
PingEthernetSendTask();
}
}

Это если время преобразования АЦП == необходимому периоду измерений (или можно так сконфигурить АЦП).
Если нет, то чуть сложнее (с использованием таймера):
CODE
void AdcReadyIsr()
{
AdcConfirm();
OSMboxPost(mboxAdcReady);
}
void TimerPeriodicIsr()
{
TimerConfirm();
OSMboxPost(mboxTimerPeriodic);
}
void AdcTask()
{
AdcInit();
TimerInit(DESIRED_FREQUENCY);
ClearAndEnableIrqAdcReady();
ClearAndEnableIrqTimerPeriodic();
while (1) {
OSMboxPend(mboxTimerPeriodic);
AdcStart();
OSMboxPend(mboxAdcReady);
DataQueueWrite(AdcRead());
PingEthernetSendTask();
}
}
Go to the top of the page
 
+Quote Post
remixx
сообщение May 22 2018, 16:42
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 19-10-16
Пользователь №: 93 818



В рбщем поговорил с преподавателем, решили т.к. времени мало организовать всю работу на таймерах/счетчиках. Дальше уже буду сам разбираться laughing.gif
Но вот на деле уже 2 дня так и не могу пропинговать плату)
В настройках LWIP пробую забивать как статический ip так и выставлять DHCP. Реакции 0.
Варианта 2: либо я что-то неправильно подключил (схему приложил)
Прикрепленное изображение

либо подозрение упало на PHYADR, в дш написано что по дефолту он 1, собственно 1 в настройках LWIP я и выставляю, но у меня вывод PHYAD0 вообще не подключен, а 1-4 включены т.к. это RXD. Получается у меня PHY адрес 30 или все таки дефолтный 1?
Прикрепленное изображение


Сообщение отредактировал remixx - May 22 2018, 16:43
Go to the top of the page
 
+Quote Post
haker_fox
сообщение May 23 2018, 00:28
Сообщение #27


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (remixx @ May 23 2018, 00:42) *
Но вот на деле уже 2 дня так и не могу пропинговать плату)

ИМХО, не тем путём вы идёте rolleyes.gif У вас может не работать канальный уровень, а вы ждёте пинга. Для начала - увас фиттер (ksz8721) ответила? Т.е. вы можете прочитать из её регистров её ID-номер? Если нет, или он не совпадает с даташитовским, то дальше вообще нет смысла ничего со стеком делать, кроме как решать проблему драйвера фиттера. Если id читатете. То следующий вопрос. У вас wireshark видит исходящие пакеты с платы? Любые. А плата принимает пакеты на канальном уровне? Когда заработает канальный уровень. вам нужно подключить стек. Как это делается, читатйте в документации. В том же lwip, я уже плохо помню, но надо поправить шаблон файла ethernetif.c под свои драйвера. После этого оно у меня сразу заработало.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th April 2024 - 13:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01509 секунд с 7
ELECTRONIX ©2004-2016