jcxz 172 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба А кто заставляет посылать широковещательные? Можно MAC адрес приёмника забить прямо в пакет. Для сдачи задания вполне достаточно. Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 59 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован? Мне кажется можно статично вбить ip-адреса железки (задать самому любой свободный), и адрес приёмника. Нужно будет считать контрольные суммы. Но я не уверен за результат, т.к. никогда так не делал, и не стал бы советовать кому-либо делать. Хотя для диплома - пойдёт. Но ещё раз повторюсь: диплом довольно сложен. Преподаватель обязан консультировать студента. Но я думаю, что преподаватель не очень компетентен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба Преподаватель обязан консультировать студента. Но я думаю, что преподаватель не очень компетентен. Да судя по формулировке задачи я бы сказал, что преподаватель вообще не копенгаген :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex11 3 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба Мне кажется можно статично вбить ip-адреса железки (задать самому любой свободный), и адрес приёмника. Работать будет, если в одной подсети. Проверено. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 59 15 мая, 2018 Опубликовано 15 мая, 2018 · Жалоба Работать будет, если в одной подсети. Проверено. Ну в общем для диплома действительно пойдёт. Но для реального проекта - только с большим количеством ограничений))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 16 мая, 2018 Опубликовано 16 мая, 2018 · Жалоба Вы предлагали UDP. А там кроме MAC вообще-то есть и IP-адреса если что. Какие туда адреса забивать прикажете если ARP не реализован? Так же, как и MAC - руками (статически). И даже работать будет. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 16 мая, 2018 Опубликовано 16 мая, 2018 (изменено) · Жалоба В указанном примере как раз таки 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 */ } Где-то что-то упустил или вообще все кардинально неправильно?)) Изменено 16 мая, 2018 пользователем remixx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 59 16 мая, 2018 Опубликовано 16 мая, 2018 · Жалоба Я бы рекомендовал не использовать ось. Я не знаю ваши строки, но вы можете закопаться и не успеть. ОС - это не просто многозадачность, это ещё и особый подход к проектированию ПО. Например, передача данных между процессами, обработка прерываний и т.п. Если у вас, конечно, есть опыт работы с операционными системами, тогда другой вопрос) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 17 мая, 2018 Опубликовано 17 мая, 2018 · Жалоба Я бы рекомендовал не использовать ось. Я не знаю ваши строки, но вы можете закопаться и не успеть. ОС - это не просто многозадачность, это ещё и особый подход к проектированию ПО. Например, передача данных между процессами, обработка прерываний и т.п. Если у вас, конечно, есть опыт работы с операционными системами, тогда другой вопрос) на крайняк сделаю с "тупыми" задержками :biggrin: посмотрю еще сегодня ISR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 17 мая, 2018 Опубликовано 17 мая, 2018 · Жалоба По советам jcxz решил, что надо добавлять в проект и RTOS. ... osDelay(1); ... osDelay(1); ... Где-то что-то упустил или вообще все кардинально неправильно?)) А что кардинально изменилось? Точно так же всё на задержках сделали. :laughing: "Использовать ОС" - это не просто рассовать функции по задачам. Это в первую очередь означает, что работа должна производиться event-driven. Т.е. - Ваши задачи должны не всё время долбить что-то (и зачем тогда вообще многозадачность?), а должны обрабатывать события. Т.е. - в задаче АЦП дали старт преобразования и после этого задача должна ждать завершения преобразования, после чего считать данные, обработать их, и запустить следующее преобразование. Ждать она должна, ожидая готовности какого-либо элемента синхронизации ОС (мэйлбокса, семафора и т.п.). Этот мэйлбокс переводиться в сигнальное состояние может например из ISR завершения преобразования АЦП (а лучше конечно из ISR завершения DMA-пересылки блока данных АЦП->ОЗУ). То же самое и с задачей отправки данных в ETHERNET. Если у Вас задачи всё время что-то долбят, то тут никакой многозадачности нет, одна фикция, пыль в глаза. Наберите в гугле "event-driven programming". В упрощённом виде работа с АЦП должна выглядеть так: void AdcReadyIsr() { AdcConfirm(); OSMboxPost(mboxAdcReady); } void AdcTask() { AdcInit(); ClearAndEnableIrqAdcReady(); while (1) { AdcStart(); OSMboxPend(mboxAdcReady); DataQueueWrite(AdcRead()); PingEthernetSendTask(); } } Это если время преобразования АЦП == необходимому периоду измерений (или можно так сконфигурить АЦП). Если нет, то чуть сложнее (с использованием таймера): 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(); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
remixx 0 22 мая, 2018 Опубликовано 22 мая, 2018 (изменено) · Жалоба В рбщем поговорил с преподавателем, решили т.к. времени мало организовать всю работу на таймерах/счетчиках. Дальше уже буду сам разбираться :laughing: Но вот на деле уже 2 дня так и не могу пропинговать плату) В настройках LWIP пробую забивать как статический ip так и выставлять DHCP. Реакции 0. Варианта 2: либо я что-то неправильно подключил (схему приложил) либо подозрение упало на PHYADR, в дш написано что по дефолту он 1, собственно 1 в настройках LWIP я и выставляю, но у меня вывод PHYAD0 вообще не подключен, а 1-4 включены т.к. это RXD. Получается у меня PHY адрес 30 или все таки дефолтный 1? Изменено 22 мая, 2018 пользователем remixx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 59 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба Но вот на деле уже 2 дня так и не могу пропинговать плату) ИМХО, не тем путём вы идёте :rolleyes: У вас может не работать канальный уровень, а вы ждёте пинга. Для начала - увас фиттер (ksz8721) ответила? Т.е. вы можете прочитать из её регистров её ID-номер? Если нет, или он не совпадает с даташитовским, то дальше вообще нет смысла ничего со стеком делать, кроме как решать проблему драйвера фиттера. Если id читатете. То следующий вопрос. У вас wireshark видит исходящие пакеты с платы? Любые. А плата принимает пакеты на канальном уровне? Когда заработает канальный уровень. вам нужно подключить стек. Как это делается, читатйте в документации. В том же lwip, я уже плохо помню, но надо поправить шаблон файла ethernetif.c под свои драйвера. После этого оно у меня сразу заработало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться