现在AT91SAM9G45开发板上裸机运行了一个图像采集程序,需要把所采得的数据传输到PC上进行显示。一般来说像这种场景有两种解决方案。
一个是移植linux搭建Web服务器。把图像采集程序写到linux应用层,再利用linux天然利于做服务器的基因搭建Web Server。socket调用丢包过去即可。不过要考虑图像的帧率,也许需要压缩后再进行传输。
另外可以在裸机情况下移植TCP/IP协议,如LwIP、uIP等。目前采用uIP进行移植。
抓包跟踪UDP传输
uIP支持TCP/UDP传输,UDP是无连接的协议,因而会更快,适用于视频图像的传输。可以用抓包软件分析UDP建立的过程。
##事件回调过程#
static void app_init(void)
{
printf("P: APP Init ... ");
printf("webserver\n\r");
httpd_init();
#ifdef __DHCPC_H__
printf("P: DHCPC Init\n\r");
dhcpc_init(MacAddress.addr, 6);
#endif
}
看整个协议的初始化函数app_init
,完成基本的http server设置后调用dhcpc_init
函数获取IP地址,这个函数首先会用UDP方式组播,包括请求DNS服务器。DNS服务器返回数据,数据里就有动态IP。这时程序会进入while(1)循环中等待数据。一旦tapdev_read
监听到数据,程序执行顺序为uip_input() -> uip_process(UIP_DATA) -> UIP_UDP_APPCALLL。以太网收到的数据存储在全局变量uip_buf中。
在dhcpc.h
中宏定义了UIP_UDP_APPCALLL的用户实现版本dhcpc_appcall
#define UIP_UDP_APPCALL dhcpc_appcall
void dhcpc_appcall(void)
{
handle_dhcp();
}
这个回调函数在收到携带动态IP的数据包后调用(也就是事件驱动)。然后开始handle dhcp,真正得到了自动获取的IP。
#如何主动发数据# 现在uIP需要作为UDP Server发数据(不需要建立连接)。首先需要做基本的本地端口配置。
uip_ipaddr(ipaddr,202,201,13,242);
conn= uip_udp_new(&ipaddr, HTONS(6677));
if(conn != NULL)
uip_udp_bind(conn,6678);
这里的uip_udp_new在本地做远端IP和端口的配置,并不发起连接,所以在抓包工具中只能找到发起的一个ARP请求。而在Server发数据的时候才能侦听到数据包。
下一步是在回调函数dhcpc_appcall中加入自定义实现发数据的CallBack函数pass_data()。
void dhcpc_appcall(void)
{
handle_dhcp();
pass_data();
}
void pass_data();
{
if(uip_poll())
{
uip_send("Hello\r\n", sizeof("Hello\r\n"));
}
}
uip_poll
每隔一段时间轮询后发送数据。
Reference
[1] http://blog.csdn.net/wuhzossibility/article/details/7993336
[2].http://www.cnblogs.com/CodeHXH/archive/2012/01/19/2327426.html
[3].http://www.cnblogs.com/way_testlife/archive/2010/10/05/1844434.html