你的中断怎么写的,这个是我们的
[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
}
|