|
|
  |
lwip с Rtos или без Rtos, Как лучше, правильнее, удобнее использовать стек с rtos или без |
|
|
|
Jan 29 2014, 11:53
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Понятно, какие еще есть открытые , на данный момент нашел два lwip и fnet и uIP. Второй кто нибудь использовал ? Еще вопрос по стеку Lwip в функции low_level_output в цикле заполняется dma и после отправляется фрейм. Если сразу отправлять, насколько это будет правильно? Код for(q = p; q != NULL; q = q->next) { заполняем dma(q->payload, q->len); запрос на передачу() }
|
|
|
|
|
Jan 29 2014, 12:45
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(sergey sva @ Jan 29 2014, 15:53)  Еще вопрос по стеку Lwip в функции low_level_output в цикле заполняется dma и после отправляется фрейм. Если сразу отправлять, насколько это будет правильно? Сразу отправлять - это zero-copy transmit что ли? Я, собственно, так и делаю. Естественно, есть ограничения: данные для отправки не могут лежать в флеше, т.к. STM32 Ethernet DMA не имеет к ней доступа. Кроме того, я жду окончания отправки пакета прямо там же, так как в противном случае есть вероятность того, что буфер будет затёрт до того, как пакет будет отправлен. Чтобы не быть голословным, вот код: CODE err_t low_level_output(struct netif *netif, struct pbuf *p) { int i; uint32_t mask;
if (!netif_is_link_up(netif)) { return ERR_OK; } while ((ETH_DMASR & 0x00700000) != 0x00600000) { /* wait until Tx DMA is suspended */ } mask = (1u << 31) /* OWN bit */ | (1 << 28); /* first segment */ i = -1; for (;;) { i++; if (i == TX_RING_SIZE) { /* not enough TX descriptors */ return ERR_MEM; } tx_desc[i].len[0] = p->len; tx_desc[i].ptr[0] = p->payload; p = p->next; if (p) { tx_desc[i].len[1] = p->len; tx_desc[i].ptr[1] = p->payload; p = p->next; if (p) { tx_desc[i].status = mask; mask = (1u << 31); /* OWN bit */ } else { break; } } else { tx_desc[i].len[1] = 0; break; } } mask |= (1 << 21) /* end of ring */ | (1 << 29); /* last segment */ tx_desc[i].status = mask; REGBIT(ETH_DMASR, 10) = 1; /* reset ETS flag in status register */ ETH_DMATPDR = 0; /* start transmission */ while (REGBIT(ETH_DMASR, 10) == 0) { /* wait for data to be copied into Tx FIFO */ } return ERR_OK; }
|
|
|
|
|
Jan 29 2014, 16:17
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(sergey sva @ Jan 29 2014, 15:53)  .. по стеку Lwip..Если сразу отправлять, насколько это будет правильно?.. можно делать следующе: 1) завести обработчик прерывания на приём и передачу. 2) выкинуть нафик все мэмкопи. подумайте - у вас DMA и ему пофигу откуда кушать ваши данные!!! То же самое приёмник. 3) Если будете юзать ось - то там (благодаря обработчику) сокращается одна нитка. вообще то стэк основан на полинге а не на прерываниях - отсюда тормоза. Короче говоря надо доработать напильником
|
|
|
|
|
Jan 29 2014, 18:07
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Golikov A. @ Jan 29 2014, 19:29)  Какой тогда смысл ДМА, если в этот момент вы не можете делать ничего другого? Видимо ДМА справляется с этой задачей быстрее, чем ядро... Цитата(Golikov A. @ Jan 29 2014, 19:29)  вы не можете делать ничего другого? Могут выполнятся прерывания, и если шина свободна - ДМА отправит данные на передечу, а ядро нет. Правда выигрыш там накакой наверное будет...
|
|
|
|
|
Jan 29 2014, 18:32
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Мне кажется что memcpy быстрее скопирует данные из памяти в память, чем дма из памяти через мак в езернет.
потому выделить память, кинуть в нее данные, и отдать их на выдачу через ДМА по времени будет не дольше, а часто и быстрее чем в функции ждать окончания посылки. Из минусов только выделение памяти, зато можно много чего другого сделать, зарядить прочие ДМА пересылать данные дальше или собирать их, например....
я в чем то не прав?
еще есть вариант сделать свой кольцевой буфер, и запускать его через ДМА, в этом случае будет серьезный выигрыш.
|
|
|
|
|
Jan 29 2014, 19:08
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Golikov A. @ Jan 29 2014, 21:29)  Простите, я может не так понял. Вы указываете ДМА где лежат данные, а потом ждете когда он их все перепихает наружу? Какой тогда смысл ДМА, если в этот момент вы не можете делать ничего другого? Смысл в том, я что я включил режим transmit store and forward, то есть DMA сразу копирует весь пакет в FIFO перед отправкой. Это происходит очень быстро (измерял), но точную цифру сейчас не помню. Альтернатива - не ждать, но тогда нужно серьёзно допиливать стек, чтобы освобождать буферы только после отправки пакета, при этом проблем возникнет больше, чем решится.
|
|
|
|
|
Jan 29 2014, 19:24
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Golikov A. @ Jan 29 2014, 20:32)  Из минусов только выделение памяти, зато можно много чего другого сделать, зарядить прочие ДМА пересылать данные дальше или собирать их, например.... я в чем то не прав? Да всё может и так, но scifi пишет: Цитата так исторически сложилось из-за дефицита ОЗУ
|
|
|
|
|
Jan 30 2014, 18:17
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Понятно видимо гдето ошибся. Добавили вывод в терминал при приеме и передачи пакетов, после подключения пакетов приходит много, а плата отправляет вначале 42байта и иногда по 64, попытался пинговать, узел не доступен. Может я не правильно указал функцию ввода ethernet_inpup? Подскажите на что обратить внимание? Код netif_add(netif_eth0, &my_ipaddr_data, &my_netmask_data, &my_gw_data, NULL, ethernetif_init, ethernet_input);
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|