在W55RP20-EVB-PICO上设置UDP多播!

目录

组件

硬件组件

项目描述

设置

文件


在W55RP20-EVB-PICO上设置UDP多播

组件

硬件组件

WIZnet - W55RP20-EVB-Pico


项目描述

UDP 多播是一种通信方法,它使用网络比单播或广播更高效地将单个数据包发送到多播组中的多个接收器。

  • 主要特点:

  1. 将数据高效分发到多个接收器。

  2. 没有确认或重新传输(尽力而为)。

  • 常见用例:

  1. 流媒体:实时视频或音频广播(例如 IPTV)。

  2. 游戏:实时多人游戏更新。

  3. 金融系统:市场数据分布。

  4. 物联网系统:设备同步或固件更新。

  5. 灾难警报系统:向多个设备发送紧急通知。

  • IPv4 组播地址范围 : 224.0.0.0 ~ 239.255.255.255 此范围是为多播通信保留的,可以划分如下:

  1. 224.0.0.0 ~ 224.0.0.255: 本地网络多播 仅限于同一子网,不遍历路由器。

  2. 239.0.0.0 ~ 239.255.255.255:组织特定的多播 在专用网络中使用,可以像单播地址一样进行配置。

设置

在这个 WCC 中,W55RP20-EVB-Pico 将充当 UDP 多播发送方,因此将进行多个Socket配置。

使用的接收器包括 W5500-EVB-PicoW5100S-EVB-PicoW5500-EVB-Pico2智能手机

此外,由于多播将在本地网络中执行,因此 TTL 设置为 1,

setSn_TTL(SOCKET_ID, 1);                // set TTL (1 : local)

地址配置为 224.0.0.1 范围。

static uint8_t multicast_ip[4] = {224, 0, 0, 6}; // multicast ip address
static uint16_t multicast_port = 29999;          // multicast port

将配置的多播 IP 和端口设置为目标,如下所示。

setSn_DIPR(SOCKET_ID, multicast_ip);          // destination IP setting
setSn_DPORT(SOCKET_ID, multicast_port);  // destination port setting

组播与标准 ARP(地址解析协议)用法的不同之处在于,特定 IP 地址由多个接收方共享。由于组播 IP 地址直接转换为 MAC 地址,因此不需要 ARP。

因此,MAC 地址的转换方式如下:

uint8_t multicast_mac[6] = {
        0x01, 0x00, 0x5e,         // First 3 bytes of the multicast MAC address
        multicast_ip[2] & 0x7f,   // Last 23 bits of the IP address(first 7 bits of 224~239 : 1)
        multicast_ip[3],          // Last 2 bytes of the IP address
        0x00                      // Remaining byte is set to 0
    };

并相应地进行配置。

// Set the MAC address (DHAR: Socket n Destination Hardware Address Register)
setSn_DHAR(SOCKET_ID, multicast_mac);
​
// Skip ARP (Address Resolution Protocol) and directly set the MAC address
setSn_CR(SOCKET_ID, Sn_CR_SEND_MAC);

发送方的执行界面如下。当在特定 GPIO 上检测到上升沿时,将发送消息。

UDP 多播接收器是参考下面的代码实现的,智能手机连接到同一个 Wi-Fi 网络,使用测试器应用程序进行测试。

WIZnet-PICO-C/examples/udp_multicast/udp_multicast_receiver at main · WIZnet-ioNIC/WIZnet-PICO-C · GitHub

以下屏幕显示了接收器的显示。

同时显示发送方和接收方的视频如下所示。

// UDP multicast sender
​
#include <stdio.h>
#include "port_common.h"
​
#include "wizchip_conf.h"
#include "w5x00_spi.h"
#include "w5x00_gpio_irq.h"
#include "socket.h"
#include "loopback.h"
#include "multicast.h"
#include "timer.h"
​
/* Clock */
#define PLL_SYS_KHZ (133 * 1000)
​
/* Buffer */
#define SOCKET_ID 1                      // Socket number
#define ETHERNET_BUF_MAX_SIZE (1024 * 2) // Send and receive cache size
​
/* GPIO  */
static void gpio_callback(void);
​
/* Timer  */
static void repeating_timer_callback(void);
static time_t millis(void);
wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e}, // Define MAC variables
    .ip = {192, 168, 11, 21},                    // Define IP variables
    .sn = {255, 255, 255, 0},                    // Define subnet variables
    .gw = {192, 168, 11, 1},                     // Define gateway variables
    .dns = {168, 126, 63, 1},                    // Define DNS  variables
    .dhcp = NETINFO_STATIC};                     // Define the DNCP mode
​
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};
uint8_t data[] = "Warning! GPIO14 state is HIGH!";
static uint8_t multicast_ip[4] = {224, 0, 0, 6}; // multicast ip address
static uint16_t multicast_port = 29999;          // multicast port
int flag = 0;
volatile uint32_t prev_state = 0;  
volatile uint32_t current_state = 0;
uint32_t start_ms = 0;
static volatile uint32_t g_msec_cnt = 0;
​
static void set_clock_khz(void);
​
int main()
{
    uint16_t local_port = 5000;
​
    uint8_t multicast_mac[6] = {
        0x01, 0x00, 0x5e,         // First 3 bytes of the multicast MAC address
        multicast_ip[2] & 0x7f,   // Last 23 bits of the IP address(first 7 bits of 224~239 : 1)
        multicast_ip[3],          // Last 2 bytes of the IP address
        0x00                      // Remaining byte is set to 0
    };
    gpio_init(14);
    gpio_init(15);
    gpio_set_dir(14, false);
    gpio_set_dir(15, true);
    gpio_put(15, 1);
​
    set_clock_khz();
​
    /*mcu init*/
    stdio_init_all(); // Initialize the main control peripheral.
    wizchip_spi_initialize();
    wizchip_cris_initialize();
    wizchip_reset();
    wizchip_initialize(); // spi initialization
    wizchip_check();
​
    wizchip_1ms_timer_initialize(repeating_timer_callback);
    wizchip_gpio_interrupt_initialize(SOCKET_ID, gpio_callback);
​
    network_initialize(net_info);
​
    print_network_information(net_info); // Read back the configuration information and print it
​
    setSn_DIPR(SOCKET_ID, multicast_ip);    // Set destination IP
    setSn_DPORT(SOCKET_ID, multicast_port); // Set destination port
    setSn_DHAR(SOCKET_ID, multicast_mac); // Set the MAC address (DHAR: Socket n Destination Hardware Address Register)
    setSn_CR(SOCKET_ID, Sn_CR_SEND_MAC); // Skip ARP (Address Resolution Protocol) and directly set the MAC address
    setSn_TTL(SOCKET_ID, 1);                // Set TTL (1 : local)
​
    // Socket初始化
    if (socket(SOCKET_ID, Sn_MR_UDP, local_port, SF_MULTI_ENABLE) != SOCKET_ID)
    {
        printf("Failed to open socket\n");
    }
    printf("Sends a message when GPIO14 detects a rising edge!\n");
​
    while (1)
    { }
    }
}
​
static void set_clock_khz(void)
{
    // set a system clock frequency in khz
    set_sys_clock_khz(PLL_SYS_KHZ, true);
​
    // configure the specified clock
    clock_configure(
        clk_peri,
        0,                                                // No glitchless mux
        CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, // System PLL on AUX mux
        PLL_SYS_KHZ * 1000,                               // Input frequency
        PLL_SYS_KHZ * 1000                                // Output (must be same as no divider)
    );
}
​
/* GPIO */
static void gpio_callback(void)
{
    current_state = millis();
    if((current_state - prev_state) > 500) {
        sendto(SOCKET_ID, data, sizeof(data), multicast_ip, multicast_port);
        printf("send!\n");
        prev_state = current_state;
    }
}
/* Timer */
static void repeating_timer_callback(void)
{
    g_msec_cnt++;
}
​
static time_t millis(void)
{
    return g_msec_cnt;
}

文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值