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

 
 
> STM32F407 Ethernet checksum = 0
cyrax0
сообщение Mar 10 2016, 09:29
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
cyrax0
сообщение Mar 21 2016, 14:40
Сообщение #2


Участник
*

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



Посмотрите, пожалуйста, возможно ли в используемой мной реализации LwIP/драйвера использование low_level_output в разных прерываниях? Или нужен "мьютекс" с выходом из функции и, соответственно, потерей пакета?

CODE

static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
err_t errval;
struct pbuf *q;
u8 *buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
__IO ETH_DMADESCTypeDef *DmaTxDesc;
uint16_t framelength = 0;
uint32_t bufferoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t payloadoffset = 0;

DmaTxDesc = DMATxDescToSet;
bufferoffset = 0;

/* copy frame from pbufs to driver buffers */
for(q = p; q != NULL; q = q->next)
{
/* Is this buffer available? If not, goto error */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET)
{
errval = ERR_BUF;
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)
{
errval = ERR_USE;
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;
}

/* Note: padding and CRC for transmitted frame
are automatically inserted by DMA */

/* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(framelength);

errval = ERR_OK;

error:

/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
{
/* Clear TUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TUS;

/* Resume DMA transmission*/
ETH->DMATPDR = 0;
}
return errval;
}


Тот же вопрос у меня к функциям lwip (типа udp_send). Разрешено ли их вызывать из разных прерываний, если поставить мьютекс в low_level_output?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 14:08
Рейтинг@Mail.ru


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