硬汉嵌入式论坛

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

[有问必答] 请教关于STM32F407不断进入ETH中断函数ETH_IRQHandler

[复制链接]

4

主题

24

回帖

36

积分

新手上路

积分
36
发表于 2023-3-13 10:12:57 | 显示全部楼层 |阅读模式
有个产品有使用以太网外设,配置的是中断接收方式,运行8天左右就会卡在ETH_IRQHandler中断函数内,现象是一直进该中断函数,但是进中断后发现DMASR寄存器NIS位没有置1。现在不知如何定位问题,请教下是否有小伙伴遇到过类似的问题。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2023-3-13 10:16:50 | 显示全部楼层
你的中断怎么写的,这个是我们的


[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: ETH_IRQHandler
*	功能说明: 以太网中断,主要处理从MAC DMA接收描述符接收到的数据帧以及错误标志的处理。
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void ETH_IRQHandler (void) 
{
	OS_FRAME *frame;
	U32 i, RxLen;
	U32 *sp,*dp;
	
#if USE_FreeRTOS == 1
	BaseType_t xResult;
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#endif

	i = RxBufIndex;
	
	/* 循环所有接受描述符列表,遇到未接收到数据的退出循环 */
	do 
	{
		/*
			#define DMA_RX_ERROR_MASK   (DMA_RX_ES | DMA_RX_LE | DMA_RX_RWT | \
								         DMA_RX_RE | DMA_RX_CE)
			
			有错误,放弃此帧数据,错误类型包含如下:
			位15 DMA_RX_ES:错误汇总(Error summary),即CRC错误,接收错误,看门狗超时,延迟冲突等。
		    位12 DMA_RX_LE:长度错误(Length error)
		                    该位置1时,指示接收帧的实际长度与长度/类型字段的值不符。该字段仅在帧类
		                    型位(RDES0[5])复位后有效。
			位4 DMA_RX_RWT:接收看门狗超时 (Receive watchdog timeout)
		                    该位置1时,表示接收看门狗计时器在接收当前帧时超时,且当前帧在看门狗超
		                    时后被截断了
			位3 DMA_RX_RE: 接收错误 (Receive error)
                            该位置1时,表示在帧接收期间,当发出RX_DV信号时,会发出RX_ERR信号。
			位1 DMA_RX_CE: CRC 错误(CRC error)
                            该位置1时,表示接收的帧发生循环冗余校验(CRC)错误。只有最后一个描述符
		                    (RDES0[8])置1时,该字段才有效
		*/
		if (Rx_Desc[i].Stat & DMA_RX_ERROR_MASK)
		{
			goto rel;
		}
		
		/*
			#define DMA_RX_SEG_MASK   (DMA_RX_FS | DMA_RX_LS)
		    位9 FS:第一个描述符 (First descriptor)
                    该位置1时,指示此描述符包含帧的第一个缓冲区。如果第一个缓冲区的大小为0,则第二
                    个缓冲区将包含帧的帧头。如果第二个缓冲区的大小为0,则下一个描述符将包含帧的帧头。
		
		    位8 LS:最后一个描述符 (Last descriptor)
                    该位置1时,指示此描述符指向的缓冲区为帧的最后一个缓冲区。
		
		    下面的函数用于判断此帧数据是否只有一个缓冲,初始化接收描述符列表的时候,每个描述符仅设置了
		    一个缓冲。
		*/
		if ((Rx_Desc[i].Stat & DMA_RX_SEG_MASK) != DMA_RX_SEG_MASK) 
		{
			goto rel;
		}
		
		RxLen = ((Rx_Desc[i].Stat >> 16) & 0x3FFF) - 4;
		if (RxLen > ETH_MTU) 
		{
			/* 数据包太大,直接放弃 */
			goto rel;
		}
		
		/* 申请动态内存,RxLen或上0x80000000表示动态内存不足了不会调用函数sys_error() */
		frame = alloc_mem (RxLen | 0x80000000);
		
		/* 如果动态内存申请失败了,放弃此帧数据;成功了,通过函数put_in_queue存入队列中 */
		if (frame != NULL) 
		{
			sp = (U32 *)(Rx_Desc[i].Addr & ~3);
			dp = (U32 *)&frame->data[0];
			for (RxLen = (RxLen + 3) >> 2; RxLen; RxLen--) 
			{
				*dp++ = *sp++;
			}
			put_in_queue (frame);
		}
		
		/* 设置此接收描述符继续接收新的数据 */
		rel: Rx_Desc[i].Stat = DMA_RX_OWN;

		if (++i == NUM_RX_BUF) i = 0;
	}
	while (!(Rx_Desc[i].Stat & DMA_RX_OWN));
	
	RxBufIndex = i;

	/*
	   DMASR DMA的状态寄存器(DMA status register)
	   位7 RBUS:接收缓冲区不可用状态 (Receive buffer unavailable status)
                 此位指示接收列表中的下一个描述符由CPU所拥有,DMA无法获取。接收过程进入挂起状态。
	             要恢复处理接收描述符,CPU应更改描述符的拥有关系,然后发出接收轮询请求命令。如果
	             未发出接收轮询请求命令,则当接收到下一个识别的传入帧时,接收过程会恢复。仅当上一
	             接收描述符由DMA所拥有时,才能将ETH_DMASR[7]置1。
	
	   DMAIER的接收缓冲区不可用中断RBUIE是bit7,对于的接收缓冲区不可用状态在DMA状态寄存器中也是bit7。
	*/
	if (ETH->DMASR & INT_RBUIE) 
	{
		/* 接收缓冲区不可用,重新恢复DMA传输 */
		ETH->DMASR = ETH_DMASR_RBUS;
		ETH->DMARPDR = 0;
	}
	
	/* 
	   DMASR DMA的状态寄存器(DMA status register)
	   这里实现清除中断挂起标志 
	   位16 ETH_DMASR_NIS:所有正常中断 (Normal interrupt summary)
	   位15 ETH_DMASR_AIS:所有异常中断 (Abnormal interrupt summary)
	   位6  ETH_DMASR_RS :接收状态 (Receive status)
	                       此位指示帧接收已完成,具体的帧状态信息已经包含在描述符中,接收仍保持运行状态。
	*/
	ETH->DMASR = ETH_DMASR_NIS | ETH_DMASR_AIS | ETH_DMASR_RS;
	
#if USE_FreeRTOS == 1
	xResult = xEventGroupSetBitsFromISR(xCreatedTCPnetGroup, /* 事件标志组句柄 */
									    0x0001,              /* 设置bit0 */
									    &xHigherPriorityTaskWoken );
	
	/* 消息被成功发出 */
	if( xResult != pdFAIL )
	{
		/* 如果xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	}
#endif
}

回复

使用道具 举报

4

主题

24

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2023-3-13 10:30:47 | 显示全部楼层
eric2013 发表于 2023-3-13 10:16
你的中断怎么写的,这个是我们的

中断函数是用的HAL库提供的
[C] 纯文本查看 复制代码
void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
{
  /* Frame received */
  if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R)) 
  {
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)

[mw_shl_code=c,true]void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
    
    HAL_ETH_GetReceivedFrame_IT(heth); //判断是否接收到数据
}

    /*Call registered Receive complete callback*/
    heth->RxCpltCallback(heth);
#else
    /* Receive complete callback */
    HAL_ETH_RxCpltCallback(heth);
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */

     /* Clear the Eth DMA Rx IT pending bits */
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R);

    /* Set HAL State to Ready */
    heth->State = HAL_ETH_STATE_READY;
   
    /* Process Unlocked */
    __HAL_UNLOCK(heth);

  }
  /* Frame transmitted */
  else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T))
  {
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
    /*  Call resgistered Transfer complete callback*/
    heth->TxCpltCallback(heth);
#else
    /* Transfer complete callback */
    HAL_ETH_TxCpltCallback(heth);
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */

    /* Clear the Eth DMA Tx IT pending bits */
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T);

    /* Set HAL State to Ready */
    heth->State = HAL_ETH_STATE_READY;
   
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
  }
  
  /* Clear the interrupt flags */
  __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS);
  
  /* ETH DMA Error */
  if(__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS))
  {
#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)
    heth->DMAErrorCallback(heth);
#else
    /* Ethernet Error callback */
    HAL_ETH_ErrorCallback(heth);
#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */

    /* Clear the interrupt flags */
    __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS);
  
    /* Set HAL State to Ready */
    heth->State = HAL_ETH_STATE_READY;
   
    /* Process Unlocked */
    __HAL_UNLOCK(heth);
  }
}[/mw_shl_code]
回复

使用道具 举报

7

主题

7

回帖

28

积分

新手上路

积分
28
发表于 2023-12-15 22:31:26 来自手机 | 显示全部楼层
楼主解决了吗,我现在也是一直进中断。
回复

使用道具 举报

4

主题

24

回帖

36

积分

新手上路

积分
36
 楼主| 发表于 2024-1-14 20:50:48 | 显示全部楼层
shuaniaun 发表于 2023-12-15 22:31
楼主解决了吗,我现在也是一直进中断。

参考了这里面的处理,http://news.eeworld.com.cn/mp/STM32/a125367.jspx
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-7 12:45 , Processed in 0.161447 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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