当前位置: 首页 > java >正文

第二十七章 W55MH32 Interrupt示例

目录

1 TOE中断简介

2 中断特点

3 TOE中断应用场景

4 TOE中断源

5 使用中断接收数据的流程

6 实现过程

7 运行结果

8 总结


本篇文章,我们将详细介绍如何在W55MH32芯片上面使用TOE中断功能,并通过实战例程,为大家讲解如何通过中断进行回环数据测试。

该例程用到的其他网络协议,请参考相关章节。有关 W55MH32 的初始化过程,请参考 Network Install 章节,这里将不再赘述。

1 TOE中断简介

在TOE中断模式下,可以设置多种中断事件,例如网络建立连接、数据接收、数据发送完成等。当某个事件发生时,通过PD9通知给处理器,处理可以立即响应中断,并进行相应的处理。这种方式可以提高系统的响应速度和效率,减少处理器在轮询状态下的资源浪费。

2 中断特点

  1. 实时性:在中断事件发生后,处理器会暂停当前正在执行的任务,立刻响应中断,当存在多个中断处理时,处理器会基于优先级进行对应处理。
  2. 提高系统效率:如果没有中断机制,处理器需要不断轮询寄存器状态,以检查是否需要进行处理,这会占用大量的处理器资源,而中断方式可以让处理器专注运行主程序,需要处理时再去处理相应的任务,提高了系统资源的利用率。
  3. 事件驱动:中断是由事件驱动的,这些事件可以是外部的(如外部设备的操作、信号变化等),也可以是内部的(如定时器溢出、计算结果异常等)
  4. 中断服务程序:每个中断源通常都有对应的中断服务程序,它们是专门为处理该中断事件而编写的一段独立的程序代码。

3 TOE中断应用场景

  1. 网络唤醒: 启用魔术包中断后,当W55MH32接收到魔术包时会触发中断,进而通知设备执行唤醒操作。
  2. 网络配置: 启用Socket接收中断后,W55MH32在接收到数据时触发中断,系统在中断触发后才进行消息读取配置,无需持续轮询,从而节省系统资源。
  3. 错误处理:当遇到错误时(例如IP地址冲突,网络不可达),W55MH32可以立即进行处理,提高系统的稳定性。

4 TOE中断源

  1. IP冲突:在收到ARP请求时,发现发送方IP与本地IP重复时触发中断。
  2. 目标不可抵达:在接收到ICMP(目的端口不可达)包后触发中断。
  3. PPPoE连接关闭:在PPPoE模式下,PPPoE连接断开时触发中断。
  4. Magic Packet:当网络唤醒模式启用并通过UDP接收到Magic Packet网络唤醒包时触发中断。

以下为Socket 中断:

  1. 发送完成:成功发送数据给对方时触发中断。
  2. 超时:当ARP超时或者TCP超时时触发中断。
  3. 接收到数据:接收到对方数据时触发中断。
  4. 关闭连接:接收到对方的FIN 或 FIN/ACK包时触发中断。
  5. 建立连接:成功与对方建立连接时触发中断。

5 使用中断接收数据的流程

  1. 初始化中断引脚;
  2. 开启对应Socket的中断功能,相关寄存器及描述如下:

  1. 开启Socket RECV中断功能,相关寄存器及描述如下:

  1. 编写中断处理函数,在接收到数据时进行处理。

6 实现过程

接下来,我们看看如何在W55MH32上实现中断回环数据测试。

注意:测试实例需要PC端和W55MH32处于同一网段。

步骤1:初始化中断引脚

void wizchip_int_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource8);NVIC_InitStructure.NVIC_IRQChannel                   = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 3;NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;NVIC_Init(&NVIC_InitStructure);EXTI_InitStructure.EXTI_Line    = EXTI_Line8;EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
}

步骤2:中断处理

void EXTI9_5_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line8) == SET){if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8) == RESET){wizchip_ISR();}}EXTI_ClearITPendingBit(EXTI_Line8);
}/*** @brief   Determine the interrupt type and store the value in I_STATUS* @param   none* @return  none*/
void wizchip_ISR(void)
{uint8_t SIR_val = 0;uint8_t tmp, sn;SIR_val = getSIR();if (SIR_val != 0xff){setSIMR(0x00);for (sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++){tmp = 0;if (SIR_val & IR_SOCK(sn)){tmp           = getSn_IR(sn);I_STATUS[sn] |= tmp;tmp          &= 0x0f;setSn_IR(sn, tmp);}}setSIMR(0xff);}
}

在TOE成功触发中断后,会调用wizchip_ISR()函数,在这里会记录中断标志位并清空中断标志。

步骤3:开启中断功能

    setSIMR(0x01); // enable socket0 interruptsetSn_IMR(SOCKET_ID, 0x0f); // enable all interrupt functions of socket 0.

步骤4:主循环中运行TCP回环服务器

void loopback_tcps_interrupt(uint8_t sn, uint8_t *buf, uint16_t port)
{uint16_t len = 0;uint8_t  destip[4];uint16_t destport;if (I_STATUS[sn] == SOCK_CLOSED){if (!ch_status[sn]){
#ifdef INTERRUPT_DEBUGprintf("%d:TCP server start\r\n", sn);
#endifch_status[sn] = ready_status;if (socket(sn, Sn_MR_TCP, port, 0x00) != sn){ch_status[sn] = closed_status;}else{
#ifdef INTERRUPT_DEBUGprintf("%d:Socket opened\r\n", sn);
#endiflisten(sn);
#ifdef INTERRUPT_DEBUGprintf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port);
#endif}}}if (I_STATUS[sn] & Sn_IR_CON){getSn_DIPR(sn, destip);destport = getSn_DPORT(sn);
#ifdef INTERRUPT_DEBUGprintf("%d:Connected - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);#endifch_status[sn]  = connected_status;I_STATUS[sn]  &= ~(Sn_IR_CON);}if (I_STATUS[sn] & Sn_IR_DISCON){printf("%d:Socket disconnected\r\n", sn);if ((getSn_RX_RSR(sn)) > 0){if (len > ETHERNET_BUF_MAX_SIZE){len = ETHERNET_BUF_MAX_SIZE;}recv(sn, buf, len);buf[len] = 0x00;printf("%d:recv data:%s\r\n", sn, buf);I_STATUS[sn] &= ~(Sn_IR_RECV);send(sn, buf, len);}disconnect(sn);ch_status[sn]  = closed_status;I_STATUS[sn]  &= ~(Sn_IR_DISCON);}if (I_STATUS[sn] & Sn_IR_RECV){setIMR(0x00);I_STATUS[sn] &= ~(Sn_IR_RECV);setIMR(0xff);if ((len = getSn_RX_RSR(sn)) > 0){if (len > ETHERNET_BUF_MAX_SIZE){len = ETHERNET_BUF_MAX_SIZE;}len      = recv(sn, buf, len);buf[len] = 0x00;printf("%d:recv data:%s\r\n", sn, buf);send(sn, buf, len);}}if (I_STATUS[sn] & Sn_IR_SENDOK){I_STATUS[sn] &= ~(Sn_IR_SENDOK);}
}

进入函数后,首先检查Socket状态。如果Socket处于关闭状态,则启动一个TCP服务器。接着,根据记录的中断标志位判断是否触发了中断,并根据中断类型进行相应的处理。

7 运行结果

烧录例程运行后,首先可以看到进行了PHY链路检测,然后打印了设置的网络地址信息,接着是TCP中断回环测试,W55MH32接收到Socket数据后触发中断并进行回传。如下图所示:

8 总结

本文讲解了如何在 W55MH32 芯片上使用 TOE 中断功能并进行回环数据测试,通过实战例程展示了从初始化中断引脚、处理中断、开启中断功能到在主循环中运行 TCP 回环服务器的完整过程。文章详细介绍了 TOE 中断的概念、特点、应用场景、中断源以及使用中断接收数据的流程,帮助读者理解其在提升系统响应速度和资源利用率方面的实际应用价值。

下一篇文章将讲解在 W55MH32 芯片上实现以太网测速功能,解析其核心原理及在网络性能评估中的应用,同时通过实战例程讲解如何借助 Jperf 工具进行测速,敬请期待!

http://www.xdnf.cn/news/16160.html

相关文章:

  • go语言基础教程:【1】基础语法:变量
  • 爬虫基础概念
  • 数学基础弱能学好大数据技术吗?
  • Kubernetes 集群架构和Pod创建流程
  • tcp基础协议
  • 字节的机器人模型 GR-3
  • 高可用架构模式——如何应对接口级的故障
  • uni-app支付宝小程序样式穿透失效
  • C51:用DS18B20传感器读取温度
  • 如何将拥有的域名自定义链接到我的世界服务器(Minecraft服务器)
  • 【Rust线程】Rust高并发编程之线程原理解析与应用实战
  • 【unity游戏开发入门到精通——组件篇】unity的粒子系统力场 (Particle System Force Field)实现如旋风、吸引力、风吹效果等
  • 数据库垂直拆分和水平拆分
  • 【​I2S:芯片设计中的“音频桥梁”​】
  • Android Service 全解析:从基础原理到实战优化
  • Windows11 本地安装docker Desktop 部署dify 拉取镜像报错
  • 【DataWhale】快乐学习大模型 | 202507,Task06笔记
  • 游戏装备被盗,运营商赔不赔
  • Petalinux的常用指令
  • 【Linux | 网络】应用层(HTTPS)
  • Python 程序设计讲义(7):Python 的基本数据类型——整数类型
  • Linux 或者 Ubuntu 离线安装 ollama
  • Paimon的部分更新以及DeleteVector实现
  • 使用阿里云 ESA 边缘函数转发代理 docker registry
  • Vue TodoList案例
  • day060-zabbix监控各种客户端
  • Android网络请求,Retrofit,OKHttp学习
  • 在AI深度嵌入企业业务的当下——AI时代的融合数据库
  • 【Vue3】ECharts图表案例
  • 跟著Qcadoo MES系统学习产品设计001