|
STM32F407 Ethernet checksum = 0 |
|
|
|
Mar 10 2016, 09:29
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 9-12-14
Пользователь №: 84 046

|
Всем добрый день!
Используется связка контроллеров STM32F407 с Ethernet, набортными свичами, lwip, аппаратной чексуммой и широковещательным udp-обменом. Время от времени происходит проблема: как показывает лог Вайршарка, один случайный контроллер из тех, которые посылают чаще, чем другие (порядка 200 пак./с.), вроде как перестает считать чексумму исходящих пакетов (ставит 0 в Header checksum и UDP checksum) или, реже, дает некорректную чек-сумму. Из-за этого другие теряют с ним связь. Этой ситуации предшествует обрезанный или склеенный с другим пакет (что странно, но не критично), после чего все пакеты следуют или без чек-суммы, или с некорректной. Ситуация может устраниться, может устраниться временно, может не устраниться - до передергивания Ethernet-кабеля, что через прерывание вызывает ETH_Stop/ETH_Start (stm32f4x7_eth.c), ETH_FlushTransmitFIFO и пр. (HAL-драйвер не используется). Вероятно, очищение fifo микросхемы каким-то образом и исправляет ситуацию.
Случайный сброс признаков аппаратной чексуммы в дескрипторах я исключил - задавал им 1 прямо перед выставлением признака OWN. (Еще при нагрузочном тестировании зафиксировал попадание в лог редких одиночных пакетов с нулевой Header checksum, но с корректной UDP checksum и без левого пакета перед этим. Непонятно, связано ли это вообще с основной проблемой.)
Скажите, есть ли вероятность, что сама микросхема перестает корректно считать чек-сумму (потому что пакеты, в остальном, она выдает корректно)? Если нет, то куда копать: lwip, еще какая-то работа с dma? Даташит, само собой, я изучал, и ситуаций, подпадающих под нулевую crc, у нас вроде как нет.
Сообщение отредактировал cyrax0 - Mar 10 2016, 09:35
|
|
|
|
|
 |
Ответов
|
Mar 14 2016, 07:13
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 9-12-14
Пользователь №: 84 046

|
Цитата(aaarrr @ Mar 11 2016, 18:05)  Проблема есть, но: - чему у Вас равен ETH_TX_BUF_SIZE? Возможна ли ситуация вообще? Большинство пакетов у нас небольшие, поэтому ETH_TX_BUF_SIZE = 256. Думаю, именно это и стало корнем проблемы. У нас циклически посылается несколько пакетов, и только один из них > 256. Лог вайршарка показывает, что началом проблемы является некорректный пакет, состоящий из начала большого пакета (256 байт) и маленького пакета вместо хвоста большого. Налицо ошибка в обработке кольца дескрипторов. После этого для следующих пакетов Ethernet считать чексумму отказывается (хотя передаются они корректно). Сложно представить, что микросхема из-за посылки некорректного пакета перестает правильно считать чексумму; получается, что некорректные исходные данные из дескрипторов переводят ее в это состояние. Буду лопатить stm-овский код на предмет этого, свой писать сейчас (с учетом необходимости обкатки) возможности нет. Цитата(aaarrr @ Mar 11 2016, 18:05)  - в известном мне порте lwip стоит еще одна проверка в low_level_output Верно, в low_level_output, которая вызывает ETH_Prepare_Transmit_Descriptors, тоже есть проверка на занятость текущего дескриптора - но опять же на один. Правильно будет именно в этой функции рассчитывать количество необходимых буферов и выходить, если оно меньше количества свободных (хотя по сути проблема иллюзорна: MAC с посылкой в while(1) способен выдавать 30000 пакетов в секунду, это гораздо больше, чем мы выдаем за цикл, так что занятых дескрипторов в принципе не должно быть).
|
|
|
|
|
Mar 14 2016, 10:23
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(cyrax0 @ Mar 14 2016, 10:13)  Верно, в low_level_output, которая вызывает ETH_Prepare_Transmit_Descriptors, тоже есть проверка на занятость текущего дескриптора Тогда, возможно, достаточно обновить порт. Вот кусок из того, который смотрел: CODE static err_t low_level_output(struct netif *netif, struct pbuf *p) { static xSemaphoreHandle xTxSemaphore = NULL; struct pbuf *q; u8 *buffer ; __IO ETH_DMADESCTypeDef *DmaTxDesc; uint16_t framelength = 0; uint32_t bufferoffset = 0; uint32_t byteslefttocopy = 0; uint32_t payloadoffset = 0;
if (xTxSemaphore == NULL) { vSemaphoreCreateBinary (xTxSemaphore); }
if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME)) { DmaTxDesc = DMATxDescToSet; buffer = (u8 *)(DmaTxDesc->Buffer1Addr); bufferoffset = 0;
for(q = p; q != NULL; q = q->next) { if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) { goto error; }
/* Get bytes in current lwIP buffer */ byteslefttocopy = q->len; payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/ while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) { /* Copy data to Tx buffer*/ memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
/* Point to next descriptor */ DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */ if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) { goto error; }
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); bufferoffset = 0; }
/* Copy the remaining bytes */ memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy ); bufferoffset = bufferoffset + byteslefttocopy; framelength = framelength + byteslefttocopy; }
/* Prepare transmit descriptors to give to DMA*/ ETH_Prepare_Transmit_Descriptors(framelength);
/* Give semaphore and exit */ error:
xSemaphoreGive(xTxSemaphore); }
return ERR_OK; }
|
|
|
|
Сообщений в этой теме
cyrax0 STM32F407 Ethernet checksum = 0 Mar 10 2016, 09:29 cyrax0 Изучая проблему, наткнулся на функцию ETH_Prepare_... Mar 11 2016, 13:38 scifi Цитата(cyrax0 @ Mar 11 2016, 16:38) Изуча... Mar 12 2016, 09:02  pitt Цитата(scifi @ Mar 12 2016, 04:02) Это ST... Mar 12 2016, 16:34   AleksBak Цитата(pitt @ Mar 12 2016, 20:34) ...
Я н... Mar 12 2016, 17:21    pitt Цитата(AleksBak @ Mar 12 2016, 12:21) Не ... Mar 13 2016, 01:33 AleksBak "спецом" - имел ввиду специально, а не ... Mar 13 2016, 04:38 cyrax0 У меня то же самое, только без семафоров (что плох... Mar 14 2016, 13:00 cyrax0 Посмотрите, пожалуйста, возможно ли в используемой... Mar 21 2016, 14:40
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|