第二十七章 W55MH32 Interrupt示例

目录

[1 TOE中断简介](#1 TOE中断简介)

[2 中断特点](#2 中断特点)

[3 TOE中断应用场景](#3 TOE中断应用场景)

[4 TOE中断源](#4 TOE中断源)

[5 使用中断接收数据的流程](#5 使用中断接收数据的流程)

[6 实现过程](#6 实现过程)

[7 运行结果](#7 运行结果)

[8 总结](#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 :初始化中断引脚

cpp 复制代码
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 :中断处理

cpp 复制代码
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 :开启中断功能

cpp 复制代码
    setSIMR(0x01); // enable socket0 interrupt
    setSn_IMR(SOCKET_ID, 0x0f); // enable all interrupt functions of socket 0.

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

cpp 复制代码
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_DEBUG
            printf("%d:TCP server start\r\n", sn);
#endif
            ch_status[sn] = ready_status;

            if (socket(sn, Sn_MR_TCP, port, 0x00) != sn)
            {
                ch_status[sn] = closed_status;
            }
            else
            {
#ifdef INTERRUPT_DEBUG
                printf("%d:Socket opened\r\n", sn);
#endif
                listen(sn);
#ifdef INTERRUPT_DEBUG
                printf("%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_DEBUG
        printf("%d:Connected - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);

#endif
        ch_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 工具进行测速,敬请期待!

相关推荐
胡楚昊6 小时前
借Polar IOTS一道困难挑战题简单入门蓝牙流量分析
物联网·蓝牙
神一样的老师19 小时前
【兆易创新GD32VW553开发板试用】天气时钟设计与调试实战
单片机·嵌入式硬件·物联网
怎么就重名了1 天前
mosquitto在windows上的安装和测试
物联网
WIZnet1 天前
MQTTS连接adafruit平台示例
网络·以太网·wiznet
搜佛说1 天前
sfsEdgeStore用极致轻量化打破工业物联网网关的硬件瓶颈 重新定义边缘存储新标准
物联网
HiWooiot20181 天前
工厂局域网远程监测:制造企业轻量化数字化转型解决方案
物联网
电子科技圈2 天前
芯科科技在蓝牙亚洲大会展示汽车与边缘AI前沿蓝牙创新技术, 解锁车用、家居、健康及工商业等应用场景
人工智能·科技·嵌入式硬件·mcu·物联网·网络安全·汽车
三佛科技-134163842122 天前
PD65W快充电源方案LP8841SD+LP35118N(高频QR反激、BOM简洁,小体积,过认证)
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
珠海西格电力2 天前
零碳园区产业园管理系统的全场景源网荷储氢协同调度功能是如何实现的
大数据·运维·人工智能·物联网·能源
sailing-data2 天前
【SE BT】BR/DER协议
物联网·架构