在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
uboot中ethernet網口實現分析
本文乃fireaxe原創,使用GPL釋出,可以自由拷貝,轉載。但轉載請保持文件的完整性,並註明原作者及原連結。內容可任意使用,但對因使用該內容引起的後果不做任何保證。作者:[email protected]部落格:fireaxe.blog.chinaunix.net
在FPGA中使用Verilog實現I2C通訊
按照I2C標準的官方時序 可以看出時序看起來很簡單,不過它嚴格的按照時序要求來傳送資料,馬虎不得的,特別是起始和停止的條件,起始必須要時鐘線SCL為高電平時資料線SDA拉低;而停止時必須要時鐘線SCL為高電平時資料線SDA拉高;中間的資料的每一位傳送都是必須要求在時鐘