ucos下lwip的ping功能实现

做嵌入式网络开发的,想必都用过电脑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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值