1. 程式人生 > >在uboot中使用UDP協議實現UDP通訊

在uboot中使用UDP協議實現UDP通訊

本文所講的uboot是基於海思晶片的uboot(如HI3520D)。因為TFTP協議是基於UDP協議,所以本文大部分程式碼是直接使用TFTP的。在寫程式碼之前複習一下TFTP報文和UDP報文的結構。


每行佔64位(bit),共8位元組(byte)。

UDP報文:太網包頭+IP包頭+UDP包頭+資料

TFTP報文:太網包頭+IP包頭+UDP包頭+TFTP包頭+資料

填充太網包頭+IP包頭+UDP包頭的話直接呼叫TFTP報文的就可以了。

步驟:

一、像TFTP命令一樣寫一個UDP命令

我直接在cmd_net.c中新增如下程式碼(當然也可以新建一個cmd_udp.c,那樣的話要在u-boot-2010.06/include/configs/hi3520d.h檔案裡面新增

#define CONFIG_CMD_UDP,,並且在common目錄的Makefile裡面新增COBJS-$(CONFIG_CMD_UDP) += cmd_udp.o):


在下面實現netboot_UDP_TCP 函式,記得定義一下這個函式。

static int netboot_UDP_TCP (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
{
	extern ulong upload_addr;
	extern ulong upload_size;
	char *s;
	char *end;
	int   rcode = 0;
	int   size;
	ulong addr;

	/* pre-set load_addr */
	if ((s = getenv("loadaddr")) != NULL) {
		load_addr = simple_strtoul(s, NULL, 16);
	}

	switch (argc) {
	case 1:
		break;
	case 2:	
		pkt_data = argv[1]; 
		break;
	default: cmd_usage(cmdtp);
		show_boot_progress (-80);
		return 1;
	}
	show_boot_progress (80);
	if ((size = NetLoop(proto)) < 0) {
		show_boot_progress (-81);
		return 1;
	}
	show_boot_progress (81);
	/* NetLoop ok, update environment */
	netboot_update_env();

	/* done if no file was loaded (no errors though) */
	if (size == 0) {
		show_boot_progress (-82);
		return 0;
	}
	/* Loading ok, check if we should attempt an auto-start */
	if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
		char *local_args[2];
		local_args[0] = argv[0];
		local_args[1] = NULL;

		printf ("Automatic boot of image at addr 0x%08lX ...\n",
			load_addr);
		show_boot_progress (82);
		rcode = do_bootm (cmdtp, 0, 1, local_args);
	}

	if (rcode < 0)
		show_boot_progress (-83);
	else
		show_boot_progress (84);
	return rcode;
}

二、為了清楚一點我在net目錄下touch一個udp.c和udp.h檔案

第一步之後會跳到net目錄下的net.c的NetLoop函式,但是在switch(protocol)裡面新增

case UDP:

UdpStart();

break;

UDP協議在net.h裡面新增


Udpstart函式在udp.c裡面實現,所以接下來會跳到net目錄下的udp.c檔案裡面,udp.c和udp.h程式碼如下:

udp.c(主要是傳送已經填充好的報文,這裡傳送函式直接呼叫TFTP協議使用的傳送函式):

#include <common.h>
#include <command.h>
#include <net.h>
#include "tftp.h"
#include "bootp.h"
#include "udp.h"

#define TIMEOUT	 	1000		/* Seconds to timeout for a lost pkt	*/
#ifndef	CONFIG_NET_RETRY_COUNT
# define TIMEOUT_COUNT	10		/* # of timeouts before giving up  */
#else
# define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT * 2)
#endif

static ulong UdpTimeoutMSecs = TIMEOUT;
static int UdpTimeoutCountMax = TIMEOUT_COUNT;

/*
 * These globals govern the timeout behavior when attempting a connection to a
 * TFTP server. UdpRRQTimeoutMSecs specifies the number of milliseconds to
 * wait for the server to respond to initial connection. Second global,
 * UdpRRQTimeoutCountMax, gives the number of such connection retries.
 * UdpRRQTimeoutCountMax must be non-negative and UdpRRQTimeoutMSecs must be
 * positive. The globals are meant to be set (and restored) by code needing
 * non-standard timeout behavior when initiating a TFTP transfer.
 */
ulong UdpRRQTimeoutMSecs = TIMEOUT;
int UdpRRQTimeoutCountMax = TIMEOUT_COUNT;

static IPaddr_t UdpServerIP;
static int	UdpServerPort;		/* The UDP port at their end		*/
static int	UdpOurPort;		/* The UDP port at our end		*/
static int	UdpTimeoutCount;		

static void UdpSend (void);
static void UdpTimeout (void);

/**********************************************************************/

static void
UdpSend (void)
{
	volatile uchar *	pkt;
	volatile uchar *	xp;
	int			len = 0;
	int			uplen=0;
	volatile ushort *s;


	/*
	 *	We will always be sending some sort of packet, so
	 *	cobble together the packet headers now.
	 */
	pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
	len = strlen(pkt_data);
	memcpy(pkt, pkt_data, len);
	printf("pkt_data=%s,len=%d\n", pkt_data,len);
	NetSendUDPPacket(NetServerEther, UdpServerIP, UdpServerPort, UdpOurPort, len);
}


static void
UdpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
	ushort proto;
	ushort *s;
	int i;
	printf("receive udp packet\n");
	s = (uchar *)pkt;
	printf("len=%d\n",len);
	printf("%.*s\n", len, s);
	
}


static void
UdpTimeout (void)
{
	if (++UdpTimeoutCount > UdpTimeoutCountMax) {
		puts ("\nRetry count exceeded; starting again\n");
		NetStartAgain ();
	} else {
		puts ("T ");
		NetSetTimeout (UdpTimeoutMSecs * CFG_HZ, UdpTimeout);
		UdpSend ();
	}
}


void
UdpStart (void)
{
	char *ep;             /* Environment pointer */

	/*
	 * Allow the user to choose UDP blocksize and timeout.
	 * UDP protocol has a minimal timeout of 1 second.
	 */

	if ((ep = getenv("udptimeout")) != NULL)
		UdpTimeoutMSecs = simple_strtol(ep, NULL, 10);

	if (UdpTimeoutMSecs < 1000) {
		printf("UDP timeout (%ld ms) too low, "
			"set minimum = 1000 ms\n",
			UdpTimeoutMSecs);
		UdpTimeoutMSecs = 1000;
	}

	UdpServerIP = NetServerIP;
	
#if defined(CONFIG_NET_MULTI)
	printf ("Using %s device\n", eth_get_name());
#endif		
	UdpTimeoutCountMax = UdpRRQTimeoutCountMax;

	NetSetTimeout (UdpTimeoutMSecs * CFG_HZ, UdpTimeout);
	NetSetHandler (UdpHandler);

	UdpServerPort = 75;//WELL_KNOWN_PORT;
	UdpTimeoutCount = 0;
	UdpOurPort = 1024;
	UdpPktLen = 0;

	/* zero out server ether in case the server ip has changed */
	memset(NetServerEther, 0, 6);

	UdpSend ();


udp.h

#ifndef __UDP_H__
#define __UDP_H__

extern void UdpStart (void);

#endif


三、程式碼基本實現完了,最後是測試

在這裡千萬別像TFTP命令一樣用69埠和TFTP伺服器測試UDP協議。否則Wireshark抓到的包是TFTP協議的包,因為TFTP伺服器把收到的UDP包當成是TFTP包了,並且TFTP包都會有一個操作選項(已經定義好的),所以抓到是unknown的包。

這裡最好是使用能接收UDP包的工具當伺服器,比如在綠軟家園裡面下載的YAT、TCP&UDP測試工具 V1.02等等。這次測試使用的是YAT,開啟YAT並設定uboot的IP、埠號1024、伺服器埠號75


現在在uboot中開始發包,資料為字串:funanfengfunanfengfunanfeng

Wireshark抓到的包:


YAT伺服器端收到的資料:


現在測試在uboot裡面接收伺服器發過來的資料:

從伺服器向uboot發一個字串:abcdefgabcdefg


Wireshark抓到的包:


在uboot中收到接收到伺服器發過來的字串,但是不知為什麼發完資料包之後還發過來一個空包,在其他的測試工具就沒這種現象,有待解決。


相關推薦

uboot使用UDP協議實現UDP通訊

本文所講的uboot是基於海思晶片的uboot(如HI3520D)。因為TFTP協議是基於UDP協議,所以本文大部分程式碼是直接使用TFTP的。在寫程式碼之前複習一下TFTP報文和UDP報文的結構。 每行佔64位(bit),共8位元組(byte)。 UDP報文:太網包頭+

C#基於TCP、UDP協議的網路通訊實現(unity)

一、TCP協議: TCP協議是面向有連線的,所以伺服器要與客戶端建立連線 伺服器端: using System; using System.Net.Sockets; using System.Net; using System.Text; public static

MFC利用CSocket實現UDP通訊

     原始碼請到此處下載。 基本介面如下:                          UDP通訊時雙方地位是對等的,不用像TCP那樣要在伺服器端設定一個監聽Socket。      第一

FPGA千兆網UDP協議實現

技術 pga 進程 linux class inf fin font spa 上一篇百兆網接口的設計與使用,我們接著來進行FPGA百兆網UDP(User Datagram Protocol)協議的設計。 1)UDP簡介 在此,參考博主夜雨翛然的博文“https://w

UDP協議實現聊天小程式

  今天我們用之前講解過的UDP協議來寫一個最基礎,最簡單的網路聊天程式。 //我們通過udp協議來實現一個簡單的網路聊天程式 //這是客戶端的實現 //過程: // 1.建立套接字 // 2.繫結地址資訊 // 3.向服務端傳送資料 // 4.接

python :通過udp協議實現客戶端與服務端的互動

(1)服務端 建立socket 繫結目的ip和埠號、 資料互動 import socket udpSer = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #這裡的SOCK_DGRAM 為udp流 udpSe

(C#)使用udp協議實現訊息的接收

1.udp-伺服器端的實現 使用udp協議傳輸資料不需要建立連線 第一步建立Socket,第二步給伺服器的Socket繫結ip和port,這個Socket就可以通過這個ip和port接收資料了。 第三步接收資料,在本例中通過新建執行緒的方式來接收資料,將執行緒設定為後臺執行緒,這樣在程序

基於udp協議的Socket通訊案例

傳送端程式碼 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.ne

基於UDP協議實現P2P語音聊天系統(C#版本)

原創性申明概述基於事件模型的UDP通訊框架(適用於網路包編解碼)】已經實現過了UDP的分包傳送資料的功能,而這篇文章主要是一個應用,使用UDP協議傳送語音和文字等資訊。在這個系統中沒有服務端和客戶端,相互通訊都是直接相互聯絡的,能夠很好的實現效果。具體實現1、語言資料來源獲取

Socket網路程式設計(二)UDP協議實現聊天工具

package UDP_chat; import java.awt.BorderLayout; import java.awt.Frame; import java.awt.List; import java.awt.Panel; import java.awt.TextField; import jav

MFC UDP CSocket實現區域網通訊

派生一個MyScoket 基於CSocket #include class CChatDlg; class MySocket : public CSocket { public: MySocket(); MySocket(CCha

Linux下基於UDP協議實現的聊天室專案(附原始碼)

好久沒來更新了,這段時間一直在著手完成這個專案,由於之前沒有接觸過這種稍大型的專案,而且對於C/S架構以及UDP通訊的瞭解也不是很深,所以前面很大的一段時間都被浪費掉了,做了很大無用功。 剛開始弄的時候,也是在網上搜了很多資料,找了很多版本,發現大都有

利用UDP協議實現兩臺電腦之間的資訊交流

關於UDP:將資料及源和目的封裝成資料包中,不需要建立連線;每個資料報的大小在限制在64k內;因無連線,是不可靠協議;不需要建立連線,速度快 使用udp協議主要涉及到兩個類:DatagramSocket,DatagramPacket DatagramSocket: 用於建

計算機網路TCP協議UDP協議的比較

在計算機網路層次結構的運輸層中,TCP協議、UDP協議解決了端到端的通訊問題。 在這裡的協議即為軟體,用以解決計算機網路的通訊互聯問題。 計算機網路層次結構概述 現代計算機網路基本層次結構由5個層次組成,自頂向下為:應用層、運輸層、網路層、資料

UDP】- 實現UDP通訊

目錄 基於LwIP實現UDP通訊 1 什麼是UDP UDP,即使用者資料包協議,屬於TCP/IP 中的傳輸層。同樣,TCP,即傳輸控制協議,也是屬於TCP/IP傳輸層。這兩者區別在此處不加以解釋,本文主要講解如何通過LwIP實現UDP傳輸。 UDP

使用UDP協議實現文字互動

  網路通訊協議有很多種,目前應用最廣泛的是TCP/IP協議(Transmission Control Protocal/Internet Protoal傳輸控制協議/英特網互聯協議),它是一個包括TCP協議和IP協議,UDP(User Datagram Protocol)協議和其它一些協議的協議組。 &n

基於TCP與UDP協議的socket通訊

基於TCP與UDP協議的socket通訊 C/S架構與初識socket   在開始socket介紹之前,得先知道一個Client端/服務端架構,也就是 C/S 架構,網際網路中處處充滿了 C/S 架構(Client/Server),比如我們需要玩英雄聯盟,就必須連線至英雄聯盟的伺服器上,那麼對於我們玩家來說

mqtt協議實現即時通訊-activemq nginx.支援JS,JAVA,微信小程式

MQTT協議通訊   簡述:            使用MQTT協議實現後臺推送、及時通訊等功能。本案例實現了web-js端、微信小程式端、Java client端、Java serv

ubootethernet網口實現分析

本文乃fireaxe原創,使用GPL釋出,可以自由拷貝,轉載。但轉載請保持文件的完整性,並註明原作者及原連結。內容可任意使用,但對因使用該內容引起的後果不做任何保證。作者:[email protected]部落格:fireaxe.blog.chinaunix.net

在FPGA使用Verilog實現I2C通訊

按照I2C標準的官方時序 可以看出時序看起來很簡單,不過它嚴格的按照時序要求來傳送資料,馬虎不得的,特別是起始和停止的條件,起始必須要時鐘線SCL為高電平時資料線SDA拉低;而停止時必須要時鐘線SCL為高電平時資料線SDA拉高;中間的資料的每一位傳送都是必須要求在時鐘