給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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...