第二十七章 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 工具进行测速,敬请期待!

相关推荐
绿蕉2 小时前
中国5G RedCap基站开通情况及2025年全年计划
物联网·5g redcap·蜂窝通讯
熬夜的猪仔14 小时前
第五章 Freertos物联网实战 微信小程序篇
物联网·freertos·微信小程序开发
熬夜的猪仔1 天前
第四章 Freertos物联网实战DHT11温湿度模块
物联网·freertos·dht11温湿度模块
时序数据说1 天前
时序数据库主流产品概览
大数据·数据库·物联网·时序数据库·iotdb
时序数据说1 天前
时序数据库在工业物联网领域的核心优势与应用价值
大数据·数据库·物联网·时序数据库·iotdb
断竿散人1 天前
深入探索浏览器中的 Navigator 对象:功能解析与最佳实践
前端·javascript·物联网
时序数据说1 天前
时序数据库IoTDB的核心功能特性
大数据·数据库·物联网·时序数据库·iotdb
ws2019072 天前
AUTO TECH 2025广州先进汽车材料展:华南聚能,能否点燃产业升级新引擎?
大数据·人工智能·物联网
TDengine (老段)2 天前
TDengine 计算百分位函数使用手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据