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

 #include <common.h>
#include <command.h>
#include <net.h> char _ctoi(char c)
{
if(c>=''&&c<='')return c-'';
if(c>='a'&&c<='f')return c-'a'+;
return ;
} int _atoi(char* s)
{
unsigned int a=;
unsigned int b=;
int i=;
while(s[i]){
a*=;
a+=_ctoi(s[i]);
i++;
}
return a;
} int _atox(char* s)
{
unsigned int a=;
unsigned int b=;
int i=;
while(s[i]){
a<<=;
a|=_ctoi(s[i]);
i++;
if(i>=)break;
}
return a;
} int _strlen(char*s)
{
int i=;
while(s[i]){
i++;
}
return i;
} void _getmac(char* s,char* eth)
{
unsigned char a=;
int i=;
while(s[i]){
a<<=;
a|=_ctoi(s[i]);
if((i&)==){
eth[i>>]=a;
a=;
}
i++;
}
} int do_udp_broadcast(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
uchar eth[]= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
char* UdpServerIP="255.255.255.255";
int dest_port = , src_port =;
uchar *str;
int len; switch(argc){
case :
puts("Params error, try again\nusage: [udp_b] [string] or [udp_b] [dest_port] [src_port] [string]\n");
return ;
break;
case :
str = argv[];
len = strlen(str);
break;
case :
dest_port = _atoi(argv[]);
src_port = _atoi(argv[]);
str = argv[];
len = strlen(argv[]);
break;
default:
return ;
break;
} printf("len=%d\n",len);
show_boot_progress();
if(NetLoop_UDP(eth,UdpServerIP,dest_port,src_port,str,len)<){
show_boot_progress(-);
return ;
} return ;
} U_BOOT_CMD(
udp_b, , , do_udp_broadcast,
"Send or receive UDP broadcast to/from server using UDP protocol",
"[udp_b] [string] or [udp_b] [dest_port] [src_port] [string]"
);

4. 给common目录的makefile添加

COBJS-$(CONFIG_CMD_UDP) += cmd_udp.o

5. 在net目录新建文件udp处理函数,udp.c和udp.h

udp.c

 #include <common.h>
#include <watchdog.h>
#include <command.h>
#include <net.h>
#include <miiphy.h>
#include "udp.h" void
UdpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len) //这个函数是处理包,先放下,有空再写
{
//printf("handler udp packet\n");
printf("Receive udp packet: %s\n",pkt);
} void
udpSend(void)
{
uchar *pkt;
pkt = (uchar *)NetTxPacket;
pkt += NetSetEther(pkt, UdpServerEther, PROT_IP);
NetSetIP (pkt, UdpServerIP, UdpServerPort, UdpOurPort, data_len);
pkt += IP_HDR_SIZE;
memcpy(pkt, pkt_data, data_len);
(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + data_len);
} void
UdpStart(const uchar *remoteeth, char *remoteip, int remoteport,int thisport, const char *data, int datalength)
{
UdpServerEther = remoteeth;
UdpServerIP = string_to_ip(remoteip);
UdpServerPort = remoteport;
UdpOurPort = thisport;
pkt_data = data;
data_len = datalength; udpSend();
printf("Send,ready to receive...\n");
}

udp.h

 #ifndef __UDP_H__
#define __UDP_H__ static uchar *UdpServerEther;
static IPaddr_t UdpServerIP;
static int UdpServerPort;/* The UDP port at their end
*/
static int UdpOurPort;/* The UDP port at our end
*/
static uchar *pkt_data;
static int data_len; void UdpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len); #endif

5. 修改net目录的net.c,在最下面加入NetLoop_UDP函数,并添加udp.h头文件引用 #include "udp.h"

 int
NetLoop_UDP(const uchar* remorteth, char* remoteip, int remoteport, int thisport, const char* data, int datalength)
{
bd_t *bd = gd->bd; /* XXX problem with bss workaround */
NetTxPacket = NULL; if (!NetTxPacket){
int i;
/*
* Setup packet buffers, aligned correctly.
*/
NetTxPacket = &PktBuf[] + (PKTALIGN - );
NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
for (i = ; i < PKTBUFSRX; i++) {
NetRxPackets[i] = NetTxPacket + (i+)*PKTSIZE_ALIGN;
}
} eth_halt();
if (eth_init(bd) < ) {
eth_halt();
return(-);
} restart:
eth_getenv_enetaddr("ethaddr", NetOurEther);
/*
* Start the ball rolling with the given start function. From
* here on, this code is a state machine driven by received
* packets and timer events.
*/
NetInitLoop(TFTP); switch (net_check_prereq (TFTP)) {
case :
/* network not configured */
eth_halt();
return (-); case :
NetSetHandler(UdpHandler);
UdpStart(remorteth,remoteip, remoteport, thisport, data, datalength);
break;
} /*
* Main packet reception loop. Loop receiving packets until
* someone sets `NetState' to a state that terminates.
*/
for (;;) {
/*
* Check the ethernet for a new packet. The ethernet
* receive routine will process it.
*/
eth_rx();
NetSetHandler(UdpHandler); /*
* Abort if ctrl-c was pressed.
*/
if (ctrlc()) {
eth_halt();
puts ("\nAbort by Ctrl+C\n");
return (-);
}
}
}

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

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

  1. Udp广播的发送与接收(C#+UdpClient) 上篇

    简介: Udp广播消息用在局域网的消息传递很方便.本文使用UdpClient类在WPF下实现Udp广播收发 发送: void MainWindow_Loaded(object sender, Rout ...

  2. [Python] socket发送UDP广播实现聊天室功能

    一.说明 本文主要使用socket.socket发送UDP广播来实现聊天室功能. 重点难点:理解UDP通讯流程.多线程.UDP广播收发等. 测试环境:Win10\Python3.5. 程序基本流程:创 ...

  3. 通过UDP广播实现Android局域网Peer Discovering

    本文是对个人笔记中内容的整理,部分代码及图片来自互联网,由于不好找到原始出处,所以未加注明. 如有痛感,联系删除. 本文将介绍以下知识点: TCP与UDP的区别: 单播.多播.广播: Java中实现U ...

  4. 【Netty】UDP广播事件

    一.前言 前面学习了WebSocket协议,并且通过示例讲解了WebSocket的具体使用,接着学习如何使用无连接的UDP来广播事件. 二.UDP广播事件 2.1 UDP基础 面向连接的TCP协议管理 ...

  5. UDP广播-缓冲区过小

    上次介绍到了关于客户端实时刷新摄像头所识别的图片的一些方法,采用了了UDP广播的技术做处理.理论上是没有问题的,将客户端运行在不同电脑上也能很好的看到效果,运行日志也没看出啥问题,结果今天翻看日志的时 ...

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

    随着倒计时的响声,自觉无心工作,只想为祖国庆生. 最近有遇到过这样一个问题,将摄像头识别的行人,车辆实时显示在客户端中.有提供接口,会以Json的数据的形式将实时将识别的对象进行Post提交.所以我们 ...

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

    1.UDP的基础知识 我们将会把重点放在一个无连接协议即用户数据报协议(UDP)上,它通常用在性能至关重要并且能够容忍一定的数据报丢失的情况下. 面向连接的传输(如TCP)管理了两个网络端点之间的连接 ...

  8. .net 使用TCP模拟UDP广播通信加强广播通信的稳定性

    应用场景:当每一台终端开启程序后发出消息,其他终端必须收到消息然后处理 思路1:使用UDP广播.     缺点:UDP广播信号不稳定,无法确定每一台机器能接收到信号 思路2:将一台主机作为服务器,使用 ...

  9. Netty学习摘记 —— UDP广播事件

    本文参考 本篇文章是对<Netty In Action>一书第十三章"使用UDP广播事件"的学习摘记,主要内容为广播应用程序的开发 消息POJO 我们将日志信息封装成名 ...

随机推荐

  1. Installshield如何实现升级覆盖文件

    这个简单的问题,问过的人不计其数,但是反馈者寥寥,并且往往不能顺利达成目标,只能采取复杂方式来实现,这里吐槽一下IS的帮助文档,很庞大很全,但是有些小技巧就是不讲. 网友冰雪孤独哥今天提供了及时的反馈 ...

  2. 参数*args和**args区别

    #*args(元组)和**args(字典)的区别 def tuple_test(*args): for i in args: print 'hello'+i s=('xuexi','mili') tu ...

  3. CNN for NLP (CS224D)

    斯坦福课程CS224d: Deep Learning for Natural Language Processing lecture13:Convolutional neural networks - ...

  4. mysql max_allowed_packet

    系统linux > show global max_allowed_packet; >set global max_allowed_packet=1024*1024: 退出mysql,重启 ...

  5. kindeditor本地上传报错,只限初学者

    困扰了我三天的问题,话说百度真的害死人啊,百度上有说路劲错了的,有说包没导的,有说还要改plugins里面的文件的!其实这个都不用动,也有说服务器问题的,还有说缓存的,还有说是ecplise的,反正我 ...

  6. Flex 关闭浏览器

    在Actionscript 2及以前,要打开任何网址,只需调用全局函数getURL()即可.在Actionscript 3中,已经取消了getURL()这个全局函数,取而代之的是flash.net包中 ...

  7. final关键字

    1.final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的.在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会再 被扩展,那么就设计为fi ...

  8. 浅谈五大Python Web框架

    转载:http://feilong.me/2011/01/talk-about-Python-web-framework 说到Web Framework,Ruby的世界Rails一统江湖,而Pytho ...

  9. uva 10820

    /* 交表 _________________________________________________________________________________ #include < ...

  10. etl学习系列1——etl工具安装

    ETL(Extract-Transform-Load的缩写,即数据抽取.转换.装载的过程),对于企业或行业应用来说,我们经常会遇到各种数据的处理,转换,迁移,所以了解并掌握一种etl工具的使用,必不可 ...