|
楼主 |
发表于 2020-4-15 13:47:16
|
显示全部楼层
对应net_lib.c里的信号量,我已改成rtt的接口。
硬件没有问题,因为跑rtt自带的lwip或bsd socket都正常。驱动层我是这样封装的
void send_frame (OS_FRAME *frame)
{
HAL_StatusTypeDef state;
__IO ETH_DMADescTypeDef *DmaTxDesc;
rt_uint8_t *buffer = (rt_uint8_t *)(EthHandle.TxDesc->Buffer1Addr);
rt_uint32_t framelength = 0;
rt_uint32_t bufferoffset = 0;
rt_uint32_t byteslefttocopy = 0;
rt_uint32_t payloadoffset = 0;
DmaTxDesc = EthHandle.TxDesc;
bufferoffset = 0;
while((DmaTxDesc->Status & ETH_DMATXDESC_OWN) == 0);
LOG_D("%s\r\n",__func__);
/* copy frame from pbufs to driver buffers */
for (;;)
{
/* Get bytes in current lwIP buffer */
byteslefttocopy = frame->length;
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((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)frame->data + 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) != (uint32_t)RESET)
{
LOG_E("dma tx desc buffer is not valid");
goto error;
}
buffer = (uint8_t *)(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((uint8_t *)((uint8_t *)buffer + bufferoffset), (uint8_t *)((uint8_t *)frame->data + payloadoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
break;
}
#ifdef ETH_TX_DUMP
dump_hex(buffer, p->tot_len);
#endif
/* Prepare transmit descriptors to give to DMA */
/* TODO Optimize data send speed*/
LOG_D("transmit frame lenth :%d", framelength);
/* wait for unlocked */
while (EthHandle.Lock == HAL_LOCKED);
state = HAL_ETH_TransmitFrame(&EthHandle, framelength);
if (state != HAL_OK)
{
LOG_E("eth transmit frame faild: %d", state);
}
rt_event_send(&event, EVENT_FLAG5);
error:
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
{
/* Clear TUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_TUS;
/* Resume DMA transmission*/
EthHandle.Instance->DMATPDR = 0;
}
}
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
#ifdef RT_USING_LWIP
rt_err_t result;
result = eth_device_ready(&(stm32_eth_device.parent));
if (result != RT_EOK)
LOG_I("RxCpltCallback err = %d", result);
#endif
#ifdef RT_USING_RL_TCPnet
OS_FRAME *frame;
while(ETH_GetRxPktSize(heth->RxDesc))
{
HAL_StatusTypeDef state;
uint16_t len = 0;
uint8_t *buffer;
__IO ETH_DMADescTypeDef *dmarxdesc;
uint32_t bufferoffset = 0;
uint32_t payloadoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t i = 0;
/* Get received frame */
state = HAL_ETH_GetReceivedFrame_IT(&EthHandle);
if (state != HAL_OK)
{
LOG_D("receive frame faild");
}
/* Obtain the size of the packet and put it into the "len" variable. */
len = EthHandle.RxFrameInfos.length;
buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer;
LOG_D("receive frame len : %d", len);
if (len > 0)
{
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
frame = alloc_mem (len | 0x80000000);
}
#ifdef ETH_RX_DUMP
dump_hex(buffer, p->tot_len);
#endif
if (frame != NULL)
{
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
bufferoffset = 0;
for (;;)
{
byteslefttocopy = frame->length;
payloadoffset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while ((byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE)
{
/* Copy data to pbuf */
memcpy((uint8_t *)((uint8_t *)frame->data + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset));
/* Point to next descriptor */
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
buffer = (uint8_t *)(dmarxdesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy remaining data in pbuf */
memcpy((uint8_t *)((uint8_t *)frame->data + payloadoffset), (uint8_t *)((uint8_t *)buffer + bufferoffset), byteslefttocopy);
bufferoffset = bufferoffset + byteslefttocopy;
put_in_queue (frame);
break;
}
}
/* Release descriptors to DMA */
/* Point to first descriptor */
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i = 0; i < EthHandle.RxFrameInfos.SegCount; i++)
{
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
EthHandle.RxFrameInfos.SegCount = 0;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
EthHandle.Instance->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
EthHandle.Instance->DMARPDR = 0;
}
// free_mem(frame);
rt_event_send(&event, EVENT_FLAG5);
}
#endif
}
因为我用的是最新的hal库,所以也没办法按照V5或V6的base库去对照修改
|
|