关于low_level_output(input也差不多)的数据拷贝过程
以cubemx生成的freertos+lwip程序为例
在初始化描述符的函数HAL_ETH_DMATxDescListInit中有这样的代码
最后一个描述符的下一个描述符指回第一个描述符
/* For last descriptor, set next descriptor address register equal to the first descriptor base address */
/*最后一个描述符的下一个描述符指回第一个描述符*/
dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
而low_level_output的部分代码如下
for循环的中间没有break,goto也是返回错误信息。也就是说必定遍历操作完所有输入的pbuf才退出循环
/* copy frame from pbufs to driver buffers */
//中间没有break,goto也是返回错误信息。也就是说必定遍历操作完所有输入的pbuf才退出循环
for(q = p; q != NULL; q = q->next)
{
/* Is this buffer available? If not, goto error */
if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
{
errval = ERR_USE;
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( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_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) != (uint32_t)RESET)
{
errval = ERR_USE;
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*)q->payload + payloadoffset), byteslefttocopy );
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
/* Prepare transmit descriptors to give to DMA */
HAL_ETH_TransmitFrame(&heth, framelength);
/*当操作完pbuf后才会硬件DMA发送,如果pbuf所带的数据大于描述符
所指的缓冲区的总大小,那么当填充完最后一个描述符的缓冲区以后,
又会指向第一个描述符,但是此时第一个描述符的缓冲区已经被填满,
新的数据覆盖了原有数据,这样发送的时候不就会丢失掉一部分数据吗?
还是说在其他的地方对lwip内核输入了描述符缓冲区的总大小,lwip每次
分配pbuf链时都会注意分配不超过描述符缓冲区总大小的数据量再调用low_level_output?*/
//话说想设个悬赏发现100起充真的有点绷不住了,这个问题卡了我很久如果有老哥解答的比较好可以留个zfb请喝杯奶茶
当操作完pbuf后才会硬件DMA发送,如果pbuf所带的数据大于描述符
所指的缓冲区的总大小,那么当填充完最后一个描述符的缓冲区以后,
又会指向第一个描述符,但是此时第一个描述符的缓冲区已经被填满,
新的数据覆盖了原有数据,这样发送的时候不就会丢失掉一部分数据吗?
还是说在其他的地方对lwip内核输入了描述符缓冲区的总大小,lwip每次
分配pbuf链时都会注意分配不超过描述符缓冲区总大小的数据量再调用low_level_output?