您的位置:首页 > 其它

LWIP network interface 即 LWIP 的 硬件 数据 接口 移植 首先 详解 STM32 以太网数据 到达 的第一站: ETH DMA 中断函数

2017-08-11 15:12 3195 查看
要 运行 LWIP 不光 要实现 OS 的 一些 接口 ,还要 有 硬件 数据 接口 移植 ,即 网线上 来的 数据 怎么个形式 传递给 LWIP ,去解析 做出相应的 应答 ,2017年8月11日14:45:16

LWIP 官网 介绍 这个硬件数据 接口 即 要 填满 网卡 这个 结构体 : http://www.nongnu.org/lwip/2_0_x/structnetif.html 关于 这个 结构体 详解 :大神 博客 :http://blog.csdn.net/zhzht19861011/article/details/6690534

以及 网卡 操作 相关 API http://www.nongnu.org/lwip/2_0_x/group__netif.html

我 的 环境 是 STM32F407 + DP83848 软件 环境 是 FreeRTOS9.0 + lwip2.0.2

我 使用 的 代码 是 ST 官方 提供 的 演示例程 , 可以在 这里下载到 STM32F407 + DP83848

工程 打开路径 : C:\Users\admin\Desktop\STM32F4x7_ETH_LwIP_V1.1.0\Project\FreeRTOS\udptcp_echo_server_netconn\MDK-ARM

以太网 数据 来了 为啥 会 进入 中断 以及 怎么 配置 STM32 的 寄存器 可以 使 以太网 工作 这个 后面 说 ,现在 就是 情况 就是 配置好 以太网寄存器后 ,有以太网数据包了 就会进入 中断函数 即 第一站 。。

首先 分析 一下 以太网 数据 到达 的 第一站 : 即 以太网 DMA 中断函数 void ETH_IRQHandler(void)

/**
* @brief  This function handles ethernet DMA interrupt request.
* @param  None
* @retval None
*/
void ETH_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* Frame received */
if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
{
/* Give the semaphore to wakeup LwIP task */
xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
}

/* Clear the interrupt flags. */
/* Clear the Eth DMA Rx IT pending bits */
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

/* Switch tasks if necessary. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}


个人 解析 后 的 结果 :

/**
* @brief  This function handles ethernet DMA interrupt request.
* @param  None
* @retval None
*/
void ETH_IRQHandler(void)
{

//使用 过 FreeRTOS 的 人 应该 知道 ,在中断 中 调用 FreeRTOS的 API

//一般 会 先 定义 这个变量  用于 判定 调用 API  后 是否有更高级的 任务 就绪

// 看其 名字  含义  : 高优先级任务 唤醒  2017年8月11日15:22:10

// 如果有更高级 的 任务  就系  ,就 使能 任务切换 中断 即 portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

//2017年8月11日15:19:37,suozhang

//具体 解释 到 大神 博客 :http://blog.csdn.net/zhzht19861011/article/details/50578159

/* xHigherPriorityTaskWoken必须被初始化为pdFALSE。如果调用vTaskNotifyGiveFromISR()会解除vHandlingTask任务的阻塞状态,
并且vHandlingTask任务的优先级高于当前处于运行状态的任务,则xHigherPriorityTaskWoken将会自动被设置为pdTRUE。
*/

portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* Frame received */

// 首先判断 是不是   以太网 收到数据 的 中断
if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
{
/* Give the semaphore to wakeup LwIP task */

//发送 一个 信号  告诉   其他任务  接收到 了  以太网 数据 ,至于 其他任务怎么处理 这个数据
//得需要 看  什么 任务  使用了 这个信号量 ,并一直 等待 的  ,可以使用  ctrl+F 全局搜索 这个变量
//  ethernetif_input 发 先 这个 函数 一直 在等待 这个信号 ,这个函数 后面 在分析
//  2017年8月11日15:27:39 suozhang
xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
}

/* Clear the interrupt flags. */
/* Clear the Eth DMA Rx IT pending bits */
// 手动 清除   接收 中断标志位  和  不知道 什么 中断标志位  ,这就尴尬了
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

/* Switch tasks if necessary. */

//这个 就是 如果 有 更高级 的任务 唤醒了  ,  就使能  任务切换中断  即 实际 是 使能 PendSV中断
// 2017年8月11日15:30:11  suozhang
if( xHigherPriorityTaskWoken != pdFALSE )
{
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐