打印
[其它应用]

基于LWIP实现MCU ping其他设备的功能

[复制链接]
1669|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-2-6 10:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、前提:在MCU上已实现LWIP功能,外部设备可以ping通MCU
二、需求:MCU可以主动去ping外部设备
三、实现:
创建ICMP控制块,在主循环前执行一次即可,需要引入 "raw.h" 头文件
static struct raw_pcb *ping_pcb;
static struct pbuf *ping_buf;

int ping_init(void)
{
    ping_pcb = raw_new(IP_PROTO_ICMP);        //创建ICMP控制块
    if (!ping_pcb)
    {
        return -1;
    }

    IP4_ADDR(&ping_pcb->local_ip, 192.168.0.100);        //MCU IP地址
    IP4_ADDR(&ping_pcb->remote_ip, 192.168.0.200);//MCU 要ping的设备IP

    ping_buf = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr), PBUF_RAM);
    if (!ping_buf)
    {
        return -2;
    }
    return 0;
}

创建ping函数用于ping其他设备
void ping_test(void)
{
    if (ping_pcb && ping_buf)
    {
        // ping_buf = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr), PBUF_RAM);
        struct icmp_echo_hdr *iecho;
        err_t err;

        iecho = (struct icmp_echo_hdr *)ping_buf->payload;
        iecho->type = 8;
        iecho->code = 0;
        iecho->id = htons(0x0200);
        iecho->seqno = htons(0x5800);
        iecho->chksum = 0;
        // iecho->chksum = inet_chksum(p->payload, sizeof(struct icmp_echo_hdr));//这里需要注释掉,否则会ping失败

        err = raw_sendto(ping_pcb, ping_buf, &ping_pcb->remote_ip); // 发送ping包
        if (err != ERR_OK)
        {

        }
        // pbuf_free(ping_buf);
    }
}

发送ping包后会接收到应答包,需要在 icmp.c 文件中进行相关逻辑设置
在 void icmp_input(struct pbuf *p, struct netif *inp) 函数前面创建一个全局变量,用于标记接收到了ping的应答包。

uint8_t pingEchoReply = 0 ;
在 void icmp_input(struct pbuf *p, struct netif *inp) 函数的switch语句中,手动添加一个“case ICMP_ER”(ICMP Echo Reply)的判断条件,让设备能够接受处理icmp的回复消息。下面代码实现:每当收到一个应答包时将 pingEchoReply  置为 1

switch (type) {
  case ICMP_ER:
          pingEchoReply  = 1;
      break;
  .......
实现功能:每50ms检测一次,若收不到应答包则1S后将 Connection_status  置为 0
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/arch.h"
#include "lwip/ip_addr.h"

extern uint8_t udp_status;
extern uint8_t pingEchoReply;

int main(void)
{
        //所有需要的初始化实现
      ping_init();
}

void Task50ms(void *pvParameters){
        while(1)
        {
            if(pingEchoReply)
            {
                    pingEchoReply = 0;
                    Connection_status = 1;        //normal
                    cnt = 0;
            }
            else
            {
                    if(cnt++>20)
                    {
                cnt = 0;
                            Connection_status = 0;        //abnormal
                       }
            }
        ping_test();
        vTaskDelay(50);
        }
}

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/floenrce/article/details/134515166

使用特权

评论回复
沙发
chenjun89| | 2024-2-6 14:12 | 只看该作者
这个只是实现了LWip的第一步

使用特权

评论回复
板凳
中国龙芯CDX| | 2024-2-26 21:45 | 只看该作者
在MCU上已实现LWIP功能,外部设备可以ping通MCU

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1923

主题

15596

帖子

11

粉丝