ucos下lwip的ping功能实现

    xiaoxiao2022-06-23  46

    做嵌入式网络开发的,想必都用过电脑ping开发板测试网路是否连通,本人参考一些网上代码,完善了这个过程。

    原文参考:http://blog.csdn.net/jtttl/article/details/50583462

    http://bbs.21ic.com/icview-406625-1-1.html

    读懂本文,需要掌握的基本知识

    1.以太网ICMP数据包相关常识

    2.ucos任务创建,消息邮箱的传递

    3.lwip的基本知识

    本文可能需要完善的地方:

    1.对接收到的ping回复没有做判断,仅仅发了一个邮箱,这样网络中的其它ping回复命令它也会认为是自己的。(当然前面筛选过的话,就不会,需要验证)

    先在以下函数中增加一个case分支,用来接收ping的回传。其中pingEchoReply为ucos的一个消息邮箱。ucos不是本文重点,略过。

    void icmp_input(struct pbuf *p, struct netif *inp)

    剩下部分直接贴上代码:

    ping.c文件:

    //==================================1.头文件声明开始================================== #include "ping.h" #include "lwip/raw.h" #include "DataProcess.h" #include "lwip/icmp.h" //==================================1.头文件声明结束================================== struct raw_pcb *ping_pcb; OS_EVENT *  pingEchoReply;    //ping回复任务 //fuc:建立pcb unsigned char icmp_pcb_init(void) {     ping_pcb = raw_new(IP_PROTO_ICMP);     if(!ping_pcb){         return 1;     } } //fuc:组装icmp的报文 //fuc:发送icmp数据包 void ping_send(u8 ip_addr1,u8 ip_addr2,u8 ip_addr3,u8 ip_addr4) {     struct pbuf *p;     struct ip_addr ipAddr;     struct icmp_echo_hdr *iecho;          //本机地址     IP4_ADDR(&ipAddr, Para.MIP[0], Para.MIP[1], Para.MIP[2], Para.MIP[3]);     ip_addr_set(&ping_pcb->local_ip, &ipAddr);     //目标地址     IP4_ADDR(&ipAddr, ip_addr1, ip_addr2, ip_addr3, ip_addr4);     ip_addr_set(&ping_pcb->remote_ip, &ipAddr);     p = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr), PBUF_RAM);     if(!p){         DebugMsg("ping send failed\r\n", 0);         return;     }     //组装icmp的报文     iecho = (struct icmp_echo_hdr *)p->payload;     iecho->type = 8; //类型     iecho->code = 0; //code     iecho->id =htons(0x0200)  ;     //id     iecho->seqno =htons(0x5800); //报文序列号     iecho->chksum = 0;  //校验和清0     iecho->chksum = inet_chksum(p->payload, sizeof(struct icmp_echo_hdr));//从算校验和     //发送ping数据包     raw_sendto(ping_pcb, p, &ping_pcb->remote_ip);     pbuf_free(p); } void PingTask(void *p_arg) {     INT8U err;     while(1)     {         OSTimeDlyHMSM(0, 0, 5, 0);              //每5秒执行一次任务                  ping_send(Para.GAT[0],Para.GAT[1],Para.GAT[2],Para.GAT[3]);         //ping_send(192,168,1,27);         OSSemPend(pingEchoReply,1500,&err); //请求信号量,并启动1.5s超时         if(err!=0){                             //任务超时             DebugMsg("ping time out\r\n", 0);         }else{              DebugMsg("ping success\r\n", 0);         }         DebugMsg("cur pipe=%d\r\n", My.DPipe);  //打印当前通道     } } //ping任务创建 #define PING_STACK_SIZE (1024) #define PING_TASK_PRIO (5) static OS_STK PingOut_stack[PING_STACK_SIZE]; void PingTaskCreate(void) {     icmp_pcb_init();      pingEchoReply = OSSemCreate(0);      OSTaskCreate(PingTask, NULL,&PingOut_stack[PING_STACK_SIZE-1],PING_TASK_PRIO); }

    ping.h文件(可以删掉一部分东西的):

    #ifndef _PING_H_ #define _PING_H_ #include "ucos_ii.h" #ifdef __cplusplus extern "C" { #endif //====================================头文件声明开始================================== //====================================头文件声明结束================================== //====================================宏定义开始====================================== typedef int pid_t; #define IPPROTO_IP 0 /* dummy for IP */ #define IPPROTO_ICMP 1 /* control message protocol */ #define IPPROTO_IGMP 2 /* internet group management protocol */ #define IPPROTO_GGP 3 /* gateway^2 (deprecated) */ #define IPPROTO_TCP 6 /* tcp */ #define IPPROTO_PUP 12 /* pup */ #define IPPROTO_UDP 17 /* user datagram protocol */ #define IPPROTO_IDP 22 /* xns idp */ #define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */ #define IPPROTO_RAW 255 /* raw IP packet */ #define IPPROTO_MAX 256 //====================================宏定义结束====================================== extern OS_EVENT *  pingEchoReply;    //ping回复任务 #endif

    转载请注明原文地址: https://ju.6miu.com/read-1123272.html

    最新回复(0)