給Hi3518e的Uboot添加UDP廣播收發功能

来源:http://www.cnblogs.com/steventeng/archive/2016/09/29/add-udp-broadcast-in-uboot.html
-Advertisement-
Play Games

基於個人興趣,決定實現一個和方案公司提供的uboot收發廣播的功能。記錄筆記如下。 SDK版本:Hi3518E_V100R001C01SPC081 1. 由於我手頭的板子的Phy是RMII模式,因此先按這篇帖子進行將uboot預設的網路驅動改為RMII模式。 http://blog.csdn.net ...


基於個人興趣,決定實現一個和方案公司提供的uboot收發廣播的功能。記錄筆記如下。

SDK版本:Hi3518E_V100R001C01SPC081

1. 由於我手頭的板子的Phy是RMII模式,因此先按這篇帖子進行將uboot預設的網路驅動改為RMII模式。

http://blog.csdn.net/skdkjzz/article/details/39931915

2. 然後設置好Phy的CONFIG_PHY_ADDR_U和CONFIG_PHY_ADDR_D,這個我不太懂是為什麼,估計和硬體有關,各位看官可能這裡不能完全照抄,我有空翻一翻Phy的規格書。編輯 u-boot-2010.06\include\configs\hi3518e.h

3. 在common目錄下新建文件cmd_udp.c,新建一個uboot cmd

  1 #include <common.h>
  2 #include <command.h>
  3 #include <net.h>
  4 
  5  char _ctoi(char c)
  6 {
  7     if(c>='0'&&c<='9')return c-'0';
  8     if(c>='a'&&c<='f')return c-'a'+10;
  9     return 0;
 10 }
 11 
 12 int _atoi(char* s)
 13 {
 14     unsigned int  a=0;
 15     unsigned int  b=0;
 16     int i=0;
 17     while(s[i]){
 18         a*=10;
 19         a+=_ctoi(s[i]);
 20         i++;    
 21     }
 22     return a;
 23 }
 24 
 25 int _atox(char* s)
 26 {
 27     unsigned int  a=0;
 28     unsigned int  b=0;
 29     int i=0;
 30     while(s[i]){
 31         a<<=4;
 32         a|=_ctoi(s[i]);
 33         i++;    
 34         if(i>=8)break;
 35     }
 36     return a;
 37 }
 38 
 39 int _strlen(char*s)
 40 {
 41     int i=0;
 42     while(s[i]){
 43         i++;
 44     }
 45     return i;
 46 }
 47 
 48 void _getmac(char* s,char* eth)
 49 {
 50     unsigned char  a=0;
 51     int i=0;
 52     while(s[i]){
 53         a<<=4;
 54         a|=_ctoi(s[i]);            
 55         if((i&1)==1){
 56             eth[i>>1]=a;
 57             a=0;            
 58         }
 59         i++;
 60     }
 61 }
 62 
 63 int do_udp_broadcast(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 64 {
 65     uchar eth[6]= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 66     char* UdpServerIP="255.255.255.255";
 67     int dest_port = 25500, src_port =25300;
 68     uchar *str;
 69     int len;
 70 
 71     switch(argc){
 72     case 1:
 73         puts("Params error, try again\nusage: [udp_b] [string] or [udp_b] [dest_port] [src_port] [string]\n");
 74         return 1;
 75         break;
 76     case 2:
 77         str = argv[1];
 78         len = strlen(str);
 79         break;
 80     case 4:
 81         dest_port = _atoi(argv[1]);
 82         src_port = _atoi(argv[2]);
 83         str = argv[3];
 84         len = strlen(argv[3]);
 85         break;
 86     default:
 87         return 1;
 88         break;
 89     }
 90 
 91     printf("len=%d\n",len);
 92     show_boot_progress(80);
 93     if(NetLoop_UDP(eth,UdpServerIP,dest_port,src_port,str,len)<0){
 94         show_boot_progress(-81);
 95         return 1;
 96     }
 97 
 98     return 0;
 99 }
100 
101 U_BOOT_CMD(
102     udp_b, 4, 1, do_udp_broadcast,
103     "Send or receive UDP broadcast to/from server using UDP protocol",
104     "[udp_b] [string] or [udp_b] [dest_port] [src_port] [string]"
105 );

 

4. 給common目錄的makefile添加

COBJS-$(CONFIG_CMD_UDP) += cmd_udp.o

5. 在net目錄新建文件udp處理函數,udp.c和udp.h

udp.c

 1 #include <common.h>
 2 #include <watchdog.h>
 3 #include <command.h>
 4 #include <net.h>
 5 #include <miiphy.h>
 6 #include "udp.h"
 7 
 8 void
 9 UdpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len)  //這個函數是處理包,先放下,有空再寫
10 {
11     //printf("handler udp packet\n");
12     printf("Receive udp packet: %s\n",pkt);
13 }
14 
15 void  
16 udpSend(void)  
17 {  
18     uchar *pkt;
19     pkt = (uchar *)NetTxPacket;
20     pkt += NetSetEther(pkt, UdpServerEther, PROT_IP);
21     NetSetIP (pkt, UdpServerIP, UdpServerPort, UdpOurPort, data_len);
22     pkt += IP_HDR_SIZE;
23     memcpy(pkt, pkt_data, data_len);
24     (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + data_len);
25 }
26 
27 void
28 UdpStart(const uchar *remoteeth, char *remoteip, int remoteport,int thisport, const char *data, int datalength)
29 {
30     UdpServerEther = remoteeth;
31     UdpServerIP = string_to_ip(remoteip);
32     UdpServerPort = remoteport;
33     UdpOurPort = thisport;
34     pkt_data = data;
35     data_len = datalength;
36 
37     udpSend();
38     printf("Send,ready to receive...\n");
39 }

udp.h

 1 #ifndef __UDP_H__
 2 #define __UDP_H__
 3 
 4 static uchar *UdpServerEther;
 5 static IPaddr_t UdpServerIP;
 6 static int UdpServerPort;/* The UDP port at their end
 7 */
 8 static int UdpOurPort;/* The UDP port at our end
 9 */
10 static uchar *pkt_data;
11 static int data_len;
12 
13 void UdpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len);
14 
15 #endif

5. 修改net目錄的net.c,在最下麵加入NetLoop_UDP函數,並添加udp.h頭文件引用 #include "udp.h"

 1 int
 2 NetLoop_UDP(const uchar* remorteth, char* remoteip, int remoteport, int thisport, const char* data, int datalength)
 3 {
 4     bd_t *bd = gd->bd;
 5 
 6     /* XXX problem with bss workaround */
 7     NetTxPacket = NULL;
 8 
 9     if (!NetTxPacket){
10         int i;
11         /*
12         * Setup packet buffers, aligned correctly.
13         */
14         NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
15         NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
16         for (i = 0; i < PKTBUFSRX; i++) {
17             NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
18         }
19     } 
20 
21     eth_halt();
22     if (eth_init(bd) < 0) {
23         eth_halt();
24         return(-1);
25     }
26 
27     restart:
28     eth_getenv_enetaddr("ethaddr", NetOurEther);
29     /*
30     * Start the ball rolling with the given start function.  From
31     * here on, this code is a state machine driven by received
32     * packets and timer events.
33     */
34     NetInitLoop(TFTP);
35 
36     switch (net_check_prereq (TFTP)) {
37         case 1:
38         /* network not configured */
39         eth_halt();
40         return (-1);
41 
42         case 0:
43         NetSetHandler(UdpHandler);
44         UdpStart(remorteth,remoteip, remoteport, thisport, data, datalength);
45         break;
46     }
47 
48     /*
49     * Main packet reception loop.  Loop receiving packets until
50     * someone sets `NetState' to a state that terminates.
51     */
52     for (;;) {
53         /*
54         * Check the ethernet for a new packet.  The ethernet
55         * receive routine will process it.
56         */
57         eth_rx();
58         NetSetHandler(UdpHandler);
59 
60         /*
61         * Abort if ctrl-c was pressed.
62         */
63         if (ctrlc()) {
64             eth_halt();
65             puts ("\nAbort by Ctrl+C\n");
66             return (-1);
67         }
68     }
69 }

6. 修改net目錄下的makefile,添加

COBJS-$(CONFIG_CMD_NET)  += udp.o

7. 這樣操作後可以通過udp_b命令發送和接收UDP廣播了。實際跑在板子上能發送UDP廣播,但接收不到UDP廣播包。

經過查看晶元規格書之後,發現有寄存器可以屏蔽廣播包,我們查看uboot網路驅動源碼之後發現確實預設將UDP廣播包屏蔽了。

那麼我們修改\drivers\net\hisfv300下的glb.c

將
hieth_writel_bits(ld, 0, GLB_MACTCTRL, BITS_BROAD2CPU_UP);
修改為
hieth_writel_bits(ld, 1, GLB_MACTCTRL, BITS_BROAD2CPU_UP);

8. 修改部分到此結束,現在我們進行測試。我採用的測試工具是我自己用c#寫的udp收發小工具,源碼就不發了,很簡單的小工具。

 

參考鏈接:

http://blog.csdn.net/skdkjzz/article/details/39931915

https://segmentfault.com/a/1190000005273491

http://www.ithao123.cn/content-10639610.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 用戶態和內核態的概念區別 究竟什麼是用戶態,什麼是內核態,這兩個基本概念以前一直理解得不是很清楚,根本原因個人覺得是在於因為大部分時候我們在寫程式時關註的重點和著眼的角度放在了實現的功能和代碼的邏輯性上,先看一個例子: 1)例子 C代碼 void testfork(){ if(0 = = fo ...
  • 一、格式化和掛載數據盤 剛購買的ECS實例(如果選擇了數據盤)在系統登陸後,是需要先格式化數據盤,然後再掛載數據盤。下麵給出一個實例操作: 1、登陸ECS實例,運行fdisk -l 命令查看數據盤。如果執行了fdisk -l 命令後,沒有發現/dev/xvdb,則表示您的實例沒有數據盤,因此無須掛載 ...
  • 希望給如本人一樣的電腦小白,能夠以最快的速度更換固態硬碟及安裝系統。 ...
  • 1.刪除列 案例:刪除前三行的前6列,文件里的內容如下: 123aaabbbbb 234ldfsdglkfd fskgfdlgfdh dsjkgdfgfdlh 操作如下: 1.1將游標移到第一行第一列 1.2按ESC回到一般模式,然後按v,移動游標到第一行第六列,再按ctrl + v 1.3移動游標 ...
  • 然後通過 Ctrl + Shift + Esc 彈出任務管理器點擊文件-->運行新任務 在打開的填寫框裡面輸入 "powershell"同時勾選下方的"以管理員身份運行",確定! 在打開的視窗裡面再次輸入以上的哪內容 運行完成後,再試試就能打開了 上面也可以在磁碟中找到 "Powershell"的路 ...
  • 裝了一個linux,後面直接把它刪掉了,結果電腦重啟的時候重啟不了,總是一開機就出現 grub> 心中無比的惱火,後面想不通了,就打算直接重裝系統,結果重裝系統的過程中遇到了問題,BIOS設了密碼,很久沒用,忘記了,這下慘了,這電腦豈不是要報廢了,網上查閱各種資料,後面發現一個比較好的辦法,解決了B ...
  • 在公有雲發佈一個個人建的靜態站點 要求: 1、使用騰訊雲申請一個雲主機 2、申請萬網個人功能變數名稱 3、使用三種web伺服器來發佈個人的站點 一、首先我選擇了騰訊雲的雲主機: ~1)低消費嘗試一下,當然有錢的可以包年包月 ~2) 由於準備安裝的是Linux系統選擇CentOS ~3)基礎網路,收費便宜點 ...
  • Linux 練習 1、SSH遠程服務的管理操作 A、通過兩種方式來拒絕開放一個埠22(SSH埠): 要求:一種是通過修改配置文件並重新載入配置;另一種是通過命令操作方式來實現開放一個埠,並測試埠是否通。 1.firewalled cmd remove port=22/tcp permanen ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...