硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1063|回复: 4
收起左侧

[以太网] STM32H7+LWIP+FREERTOS,以太网工作异常

[复制链接]

9

主题

32

回帖

59

积分

初级会员

积分
59
发表于 2022-12-3 14:27:57 | 显示全部楼层 |阅读模式
各位大佬,基于STM32H7+LWIP+FREERTOS进行UDP通信,系统通过UDP以120Hz的频率在定时中断中向外发数,同时在1s一次的任务中对外发数,在接收到串口数据后(1秒8次的不定时数据)也会向外发数,同时UDP每秒还会接收32次每次近1000字节的数据,测试中发现系统在一段时间后HAL_ETH_Transmit函数会返回错误值,由于对UDP了解不多,不知道原因是什么,感觉存在有正在RTOS周期性任务发以太网数的过程中突然定时中断或串口通信中断发以太网数据导致发送函数返回错误值,不知道这种机理准不准确,在未验证的情况下我把中断发送以太网数据的函数进行了改写,新增了一个8ms周期的任务,在任务中根据各需要UDP发送的数的标志来决定本任务周期要不要发送相应数据,改写完后,能正常发送1s的周期数据,但此时一接收以太网数据,整个系统就奔溃了,表现在freertos 1秒周期的闪灯维持在常量或常灭,由于本人对FREERTOS也不太熟悉(freertos包括4个任务,ethernetif_input任务优先级为osPriorityRealtime,1秒周期任务优先级为osPriorityNormal,主要闪灯和给1s周期性发数使能置位,100ms周期任务用于AD采样,优先级为osPriorityLow6,8ms任务用于发送以太网数据,根据各数据使能情况进行发数,每8ms最多发送两帧以太网数据,优先级为osPriorityLow7),想问下大佬,针对这两个问题能不能帮指点下
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107462
QQ
发表于 2022-12-4 12:03:01 | 显示全部楼层
使用UDP最好做应答处理。UDP本身只管发送,他不管成功不成功,如果不做应答会有阻塞,丢包等问题。
回复

使用道具 举报

4

主题

47

回帖

59

积分

初级会员

积分
59
发表于 2022-12-5 00:14:54 | 显示全部楼层
HAL_ETH_Transmit返回错误值你把error_callback打开看看错误是什么,另外可以在报错的时候刷一下phy 寄存器的错误讯息,查看是不是底层出现故障,以下这段代码供参考
[C] 纯文本查看 复制代码
//写入网卡发送数据
ERROR_SUB MCU_ETH_WriteMultiPack(ETH_MULTI_PACK* multiPackPtr)
{
    uint16_t indexUtil = 0;
    uint32_t sendLength = 0;
    uint32_t txResult = TX_SUCCESS;
    HAL_StatusTypeDef halState = HAL_OK;
    if(multiPackPtr->packCount == 0)
    {
        return ERROR_SUB_OK;
    }
    //申请信号量
    txResult = tx_semaphore_get(&semaphoreMCU_ETH,TIME_OUT_MS_ETH_SEND);
    if(TX_SUCCESS != txResult)
    {
        //信号量申请失败,返回错误
        LowLevelPrintf("%s,semaphoreMCU_ETH GetTimeOut\r\n",__func__);
        //停止ETH
        halState = HAL_ETH_Stop_IT(&ETH_Handler);
        if(halState != HAL_OK)
        {
            LowLevelShowHalError(halState);
            while(1);
        }
        //启动ETH
        halState = HAL_ETH_Start_IT(&ETH_Handler);
        if(halState != HAL_OK)
        {
            LowLevelShowHalError(halState);
            while(1);
        }
        //发送信号量
        tx_semaphore_ceiling_put(&semaphoreMCU_ETH,1);
        return ERROR_SUB_MCU_ETH_SEND_TIME_OUT;
    }
    //清除发送结构
    UserMemSet((uint8_t*)ethSendPackBuffer,0,(ETH_TX_DESC_CNT*(sizeof(ETH_BufferTypeDef)/sizeof(uint8_t))));
    //清除发送缓存
    UserMemSet((uint8_t*)ethSendBufferArray,0,(ETH_TX_DESC_CNT*ETH_MAX_PACKET_SIZE));
    //配置发送结构
    for(indexUtil = 0;indexUtil < multiPackPtr->packCount;indexUtil++)
    {
        //数据拷贝到发送缓存
        UserMemCopy((uint8_t*)ethSendBufferArray[indexUtil],(void*)multiPackPtr->dataBufferPtrArray[indexUtil],
                        multiPackPtr->dataLengthArray[indexUtil]);
        //发送环境创建
        ethSendPackBuffer[indexUtil].buffer = ethSendBufferArray[indexUtil];
        ethSendPackBuffer[indexUtil].len = multiPackPtr->dataLengthArray[indexUtil];
        if(indexUtil != multiPackPtr->packCount -1)
        {
            //多包链接
            ethSendPackBuffer[indexUtil].next = &ethSendPackBuffer[indexUtil+1];
        }
        //总长度计算
        sendLength += multiPackPtr->dataLengthArray[indexUtil];
    }
    #if(MCU_ETH_ENABLE_CACHE_INVALID_STRATEGY == 1)
    //更新缓存
    SCB_CleanDCache_by_Addr((uint32_t*)(ethSendBufferArray),(ETH_RX_DESC_CNT*ETH_MAX_PACKET_SIZE)/4);
    SCB_CleanDCache_by_Addr((uint32_t*)ethSendPackBuffer,(ETH_TX_DESC_CNT*(sizeof(ETH_BufferTypeDef)/sizeof(uint8_t)))/4);
    #endif
    ethTxConfig.Length = sendLength;
    ethTxConfig.TxBuffer = ethSendPackBuffer;
    //中断发送
    halState = HAL_ETH_Transmit_IT(&ETH_Handler,&ethTxConfig);
    if(halState != HAL_OK)
    {
        LowLevelShowHalError(halState);
        while(1);
    }
    return ERROR_SUB_OK;
}

[C] 纯文本查看 复制代码
//发送完成回调
void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
{
    if(heth->Instance == ETH)
    {
        //发送信号量
        tx_semaphore_ceiling_put(&semaphoreMCU_ETH,1);
    }
}

[C] 纯文本查看 复制代码
//多包发送结构体
typedef struct ETH_MULTI_PACK
{
    uint8_t* dataBufferPtrArray[ETH_TX_DESC_CNT];
    uint16_t dataLengthArray[ETH_TX_DESC_CNT];
    uint16_t packCount;
}ETH_MULTI_PACK;
回复

使用道具 举报

9

主题

32

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2022-12-5 09:29:04 | 显示全部楼层
eric2013 发表于 2022-12-4 12:03
使用UDP最好做应答处理。UDP本身只管发送,他不管成功不成功,如果不做应答会有阻塞,丢包等问题。

收到,谢谢大佬
回复

使用道具 举报

9

主题

32

回帖

59

积分

初级会员

积分
59
 楼主| 发表于 2022-12-5 09:29:58 | 显示全部楼层
dengxiaojundink 发表于 2022-12-5 00:14
HAL_ETH_Transmit返回错误值你把error_callback打开看看错误是什么,另外可以在报错的时候刷一下phy 寄存器 ...

感谢感谢,我去试着用一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-2 14:37 , Processed in 0.244644 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表