给Hi3518e的Uboot添加UDP广播收发功能

基于个人兴趣,决定实现一个和方案公司提供的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

时间: 2024-10-20 19:37:53

给Hi3518e的Uboot添加UDP广播收发功能的相关文章

C#中Udp广播的发送与接收(UdpClient)

简介: Udp广播消息用在局域网的消息传递很方便.本文使用UdpClient类在WPF下实现Udp广播收发 发送: 1 void MainWindow_Loaded(object sender, RoutedEventArgs e) 2 { 3 Loaded -= MainWindow_Loaded; 4 UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 0)); 5 IPEndPoint endpoint = new

【Netty】UDP广播事件

一.前言 前面学习了WebSocket协议,并且通过示例讲解了WebSocket的具体使用,接着学习如何使用无连接的UDP来广播事件. 二.UDP广播事件 2.1 UDP基础 面向连接的TCP协议管理端到端的连接,在连接生命周期中,发送的消息会有序并且可靠地进行传输,最后连接有序地终止.然而,在无连接协议(如UDP)中,没有持久连接的概念,每个消息(UDP数据报)都是独立的传输,此外,UDP没有TCP的纠错机制(即每个对等体会确认其接收到的分组,并且发送者会重传未确认的分组). UDP的限制比T

Netty实战十三之使用UDP广播事件

1.UDP的基础知识 我们将会把重点放在一个无连接协议即用户数据报协议(UDP)上,它通常用在性能至关重要并且能够容忍一定的数据报丢失的情况下. 面向连接的传输(如TCP)管理了两个网络端点之间的连接的建立,在连接的生命周期内的有序和可靠的消息传输,以及最后,连接的有序终止.相比之下,在类似于UDP这样的无连接协议中,并没有持久化连接这样的概念,并且每个消息(一个UDP数据报)都是一个单独的传输单元. 此外,UDP也没有TCP的纠错机制,其中每个节点都将确认它们所接收到的包,而没有被确认的包将会

UDP广播 与 TCP客户端 --服务端

随着倒计时的响声,自觉无心工作,只想为祖国庆生. 最近有遇到过这样一个问题,将摄像头识别的行人,车辆实时显示在客户端中.有提供接口,会以Json的数据的形式将实时将识别的对象进行Post提交.所以我们这边先写一个web服务来持续接收数据,再将数据进行解析存入数据库.到这里为止,数据没有问题,都全部存入数据库中,这样还剩下一个实时刷新识别图片的问题.之前的处理方法是每隔5秒左右去读取数据库最新消息,用Timer计时器来解决,这样的话确实能解决问题,但是感觉不是最好的方法,因为摄像头识别的对象有时效

Udp广播的发送和接收(ios+AsyncUdpSocket)下篇

接上篇C#的Udp广播的发送和接收 http://www.cnblogs.com/JimmyBright/p/4637090.html ios中使用AsyncUdpSocket处理Udp的消息非常方便 准备工作: 在github上找到cocoaAsyncSocket,下载下来,把其中AsyncUdpSocket.h和AsyncUdpSocket.m文件copy到你的项目中,其他文件都不需要.copy到swift环境下会自动提示创建桥接文件,点击确认就可以了. 发送Udp: 上面代码对局域网广播消

Android 通过局域网udp广播自动建立socket连接

Android开发中经常会用到socket通讯.由于项目需要,最近研究了一下这方面的知识. 需求是想通过wifi实现android移动设备和android平台的电视之间的文件传输与控制. 毫无疑问这中间一定需要用到socket来进行通信.今天就两台设备的握手连接方式分享一下吧,该方法只是本人个人想法的实现,仅供参考,如有雷同,不胜荣幸. 要想使用socket进行通讯,就必须知道服务端的IP地址,我使用的是通过udp局网广播来实现局网内服务端的搜寻建立连接.以下是代码实现. 首先是客户端: pub

android 发送UDP广播,搜寻服务器建立socket链接

应用场景:客户端(手机,pc)需要搜寻所在局域网内的服务器并获得服务器地址. 方法简介:客户端发送UDP广播,服务收到广播后得到客户端ip地址,然后向客户端发送一次socket链接,客户端收到socket链接,获得服务器地址. 相关知识: UPD.TCP.TCP是面向链接的,可靠的通信方式.UDP是面向非链接的通讯方式.TCP的建立比较麻烦,要经过"三次握手".而UDP的建立比较简单,发送方只管把内容发送出去,不管接收方是否收到.UDP的传输分为:单播,多播,广播.其中,多播和广播是通

工位上的Python——一个简单的UDP广播实例

最近状态神勇,头脑清晰,趁此良机,多多学习,多多看书,把以前看不懂的地方重新看了下,收获匪浅,现把两个简单的小例子献给大家: 先是一个简单的UDP广播接收的小服务器,使用UDP广播,需要注意下协议的使用,已经最最重要的socket选项的设置,设置为传说中的"socket.SO_BROADCAST",不需要有监听,接收客户端的消息使用recvfrom,发送消息使用sendto: 代码如下: !/usr/bin/env python  #coding:utf-8 import socket

uboot 添加命令

uboot中有几十个常用的命令,可以帮助我们快速实现数据的拷贝.传递.状态显示等需求 但是这还不够 ,我们需要更多的命令实现差异化,uboot提供的命令也不够 添加命令需要三步: 这里就举一个例子  添加 一个名字叫test的命令 添加前一定要检测不要和存在的命令重名 一 .添加命令实现函数的文件 在common 文件夹下添加文件  cmd_show.c 这里面推荐这么命名,可以看到这个文件夹下都是这么命名的 ,我们也不要换了   当然是可以改的   只要和第二步配合好就行了 里面这么写就好 #