Uboot增加UDP收发和广播功能
背景:
因项目需求,要在Uboot里面添加UDP通讯,广播功能,从主机获取一些参数配置(IP等)。Uboot没有TCP/IP协议栈,不支持TCP,只支持简单的网络协议,具体见/uboot_src/net/net.c
MAC问题
网络通讯的前提是有区别的MAC地址
- 烧写自己的MAC地址到Uboot
- 使用唯一的SN或UUID生成(节约MAC地址资源, 适用于局域网内)
使用加密芯片全球唯一的SN,然后转化为MAC地址,检查MAC是否非法(is_valid_ether_addr(&sn[2])
),非法则使用随机MAC(eth_random_addr(ethaddr);
)setenv("ethaddr", ethaddr);
保存MAC地址到uboot环境变量
Uboot增加UDP广播收发功能:
参考:https://segmentfault.com/a/1190000005273491
添加自定义的xx_udp.c和xx_udp.h
根据需要实现以下几部分(/uboot_src/net/
):
实现开始和发送函数
void UdpStart(void)
{
debug("%s\n", __func__);
NetSetTimeout(UDP_TIMEOUT, UdpTimeout);/*超时处理回调*/
net_set_udp_handler(UdpHandler); /*接受包处理回调*/
memset(NetServerEther, 0, sizeof(NetServerEther));/*接受包*/
UdpSend(); /*发送自己的包*/
}
主要是调用API函数:
NetSendUDPPacket(uchar *ether,
IPaddr_t dest,
int dport,
int sport,
int len);
说明:
- ether:目标的以太网地址。如果是广播,则使用全局变量NetBroadcastAddr;如果未知,则指定全零的char[6]={0,0,0,0,0,0}
- dest:目标的IP地址。如果是广播,则指定0;如果是单播,则指定一个ulong值,可使用
string_to_ip()
- dport:远端端口
- sport:源端口
- len:UDP包正文的长度
发送之前需要事先设置好正文,即
memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE, (char *)udp_pkt_data, udp_data_len);
//udp_pkt_data为用户数据, udp_data_len为用户数据长度
实现超时回调函数
/*超时处理回调*/
static void UdpTimeout(void)
{
puts("UdpTimeout\n");
//如果未获取则重试
if(getinfo_ok!=1)
UdpStart();
else
net_set_state(NETLOOP_FAIL);// 结束NetLoop()
return;
}
//
实现接收回调函数
/*接受包处理回调*/
static void UdpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len)
{
debug("%s\n", __func__);
printf("Receive udp packet: %s len:%d\n", pkt, len);
//IP_t *ipPky = pkt - (IP_HDR_SIZE);//IP报头
//IPAddr_t ipFrom = ipPkg->ip_src; //可以用于UDP response
//...
}
在/uboot_src/net/Makefile
添加obj-$(CONFIG_CMD_UDP) += xx_udp.o
修改net.c和net.h
net.c (/uboot_src/include/net.c
)
添加头文件
#if defined(CONFIG_CMD_UDP)
#include "spon_udp.h"
#endif
在NetLoop()
中添加自定义的执行分支
#if defined(CONFIG_CMD_UDP)
case XXXUDP:
UdpStart();
break;
#endif
net.h (/uboot_src/include/net.h
)
添加自定义的协议enum proto_t {xxx, XXXUDP}
添加自定义的数据
#if defined(CONFIG_CMD_UDP)
extern IPaddr_t UdpServerIP;
#endif
添加自定义命令(cmd_udp_xxx)
(具体可见Uboot添加自定义命令),来操作UDP通信
注: uboot里芯片厂商的MAC驱动过滤了广播包(MAC_PACKET_FILTER),修改相关驱动,原厂datasheet里缺少相关寄存器说明
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DD'Notes!
评论