OK,uip_arp.c中还有两个函数,楼下继续. 最后两个函数:
1.看代码:
1. /*-----------------------------------------------------------------------------------*/ 2. /**
3. * Periodic ARP processing function. 4. *ARP周期性处理函数.
5. * This function performs periodic timer processing in the ARP module 6. * and should be called at regular intervals. The recommended interval 7. * is 10 seconds between the calls.
8. *此函数在ARP模块中施行周期性处理,它应该每隔一段时间就调用一次.推荐为10秒. 9. */
10. /*-----------------------------------------------------------------------------------*/ 11. void
12. uip_arp_timer(void) 13. {
14. struct arp_entry *tabptr; 15.
16. ++arptime;
17. for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { 18. tabptr = &arp_table[i];
19. if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && 20. arptime - tabptr->time >= UIP_ARP_MAXAGE) { 21. memset(tabptr->ipaddr, 0, 4); 22. } 23. } 24. }
复制代码
1. #define UIP_ARP_MAXAGE 120//即20分钟.
复制代码
从这里可以看出,ARP表项中的更新时间是一个数,每调用一个上面这个函数,这个数就加1. 这个周期性处理函数的作用就是每隔一段时间把超过20分钟都没有更新过的表项扔掉.
2.看代码:
1. /*-----------------------------------------------------------------------------------*/ 2. /**
3. * Initialize the ARP module.初始化ARP模块. 4. *
5. */
6. /*-----------------------------------------------------------------------------------*/ 7. void
8. uip_arp_init(void) 9. {
10. for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { 11. memset(arp_table[i].ipaddr, 0, 4); 12. } 13. }
一目了解,所谓初始化就是把数组中很一个表项都扔掉,清空成0,变成空表项. 到这里,并于ARP的代码就说到这里,欢迎提问.
UIP中文文档第一 与设备驱动接口
实现设备驱动与uIP的对接,需要开发者实现如下七个接口程序: #define uip_input() 处理一个输入的数据包。
#define uip_periodic(conn) 通过连接号,对连接周期性进行处理。
#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags!=UIP_CLOSED)
#define uip_periodic_conn(conn) 周期性处理一个连接,此操作要借助指向这个连接的结构体的指针。
#define uip_poll_conn(conn) 请求轮询(poll)某一指定连接.
#define uip_udp_periodic(conn) 周期性处理udp连接,此操作要借助连接号。 #define uip_udp_periodic_conn(conn) 周期性处理一udp连接,要借助指向此连接结构体的指针。
还有一个变量在接口中用到: u8_t uip_buf [UIP_BUFSIZE+2] uip包缓冲区。
下面对以上接口进行详细介绍: 1. #define uip_input() 处理输入数据包。
此函数应该在设备从网络上接收到数据包时得到调用。设备驱动应该在调用此函数之前,将接收到的数据包内容存入uip_buf缓冲区,并将其长度赋给uip_len变量。
此函数返回时,如果系统有数据要输出,会直接将数据存入uip_buf,并将其长度值赋给uip_len。如果没有数据要发送,则将uip_len赋0. 通常使用此函数的方法如下:
1. uip_len = devicedriver_poll(); 2. if(uip_len > 0) { 3. uip_input(); 4. if(uip_len > 0) { 5. devicedriver_send(); 6. } 7. }
注意:
如果你写的uip设备驱动需要使用ARP协议(Address Resolution Protocal),比如说在以太网内使用uip的时候,你就得在调用此函数之前先调用uip的ARP代码:
1. #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 2. uip_len = ethernet_devicedrver_poll(); 3. if(uip_len > 0) {
4. if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { 5. uip_arp_ipin(); 6. uip_input(); 7. if(uip_len > 0) { 8. uip_arp_out();
9. ethernet_devicedriver_send(); 10. }
11. } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { 12. uip_arp_arpin(); 13. if(uip_len > 0) {
14. ethernet_devicedriver_send(); 15. } 16. }
使用例程:example-mainloop-with-arp.c, and example-mainloop-without-arp.c. 此接口定义于uip.h的第257行。 2. #define uip_periodic(conn) 周期性处理一连接,需借助其连接号。
此函数对uip的tcp连接进行一些必要的周期性处理(定时器,轮询等),它应该在周期性uip定时器消息到来时被调用。它应该对每一个连接都得到调用,不管连接是打开的还是关闭的。
此函数返回时,可能会有要传送出去的数据包等待得到服务,包内容会被放到uip包缓冲区中。如果真的有数据包需要送出,则uip_len的值会被置为一个大于零的数,此时设备驱动应该将数据包发送出去。(这一段与(1)中相应段落的意思应该是一致的。) 通常调用此函数时,会使用一个如下的for循环:
1. for(i = 0; i < UIP_CONNS; ++i) { 2. uip_periodic(i); 3. if(uip_len > 0) { 4. devicedriver_send(); 5. } 6. }
注意:
如果你所写的设备驱动需要使用ARP协议(Address Resolution Protocal),例如是在以太网中使用uip,你就得在调用驱动函数发送传出数据之间调用uip_arp_out()函数:
1. for(i = 0; i < UIP_CONNS; ++i) { 2. uip_periodic(i); 3. if(uip_len > 0) { 4. uip_arp_out();
5. ethernet_devicedriver_send(); 6. } 7. }
参数:
conn 将要轮询的连接号。 使用例程:
example-mainloop-with-arp.c, and example-mainloop-without-arp.c. 此接口函数定义于uip.h的301行。 3. #define uip_periodic_conn(conn)
对一个连接进行周期性处理,需要借助指向其结构体的指针
这个函数与uip_periodic执行的操作是相同的,不同之处仅在于传入的参数是一个指向uip_conn结构体的指针。此函数可以用于对某个连接强制进行周期性处理。 参数:
conn 指向要进行处理的连接结构体的指针。 此接口函数定义于uip.h的323行。 4. #define uip_poll_conn(conn) 请求对特定连接进行轮询
函数功能与uip_periodic_conn()相同,但不是执行任何定时器处理。轮询以得到新数据。 参数:
conn 指向要进行处理的连接结构体uip_conn的指针。 此接口函数定义于uip.h的337行。 5. #define uip_udp_periodic(conn) 借助连接号,周期性处理udp连接。
此函数基本上与uip_periodic()相同,区别之处仅在于这里处理的是udp连接。其调用方式也与uip_periodic()类似:
1. for(i = 0; i < UIP_UDP_CONNS; i++) { 2. uip_udp_periodic(i); 3. if(uip_len > 0) { 4. devicedriver_send(); 5. } 6. }
注意:
对于uip_periodic()函数,在uip中使用arp和以太网时,要特别注意一些事情,这对于uip_udp_periodic()也一样:
1. for(i = 0; i < UIP_UDP_CONNS; i++) { 2. uip_udp_periodic(i); 3. if(uip_len > 0) {
4. uip_arp_out();
5. ethernet_devicedriver_send(); 6. } 7. }
参数:
conn 要处理的udp连接号 使用例程:
example-mainloop-with-arp.c, and example-mainloop-without-arp.c. 此接口定义于uip.h的373行。
6. #define uip_udp_periodic_conn(conn)
周期性处理udp连接,需借助指向该连接结构体的指针。
函数功能与uip_udp_periodic(conn)相同,不同之处在于所用参数为指向连接结构体的指针而非连接号。此函数可用于强制执行周期性处理某连接。 参数:
conn 指向要处理的udp连接的uip_udp_conn结构体的指针。 此接口定义于uip.h的 390 行。
7. 变量 u8_t uip_buf[UIP_BUFSIZE+2] uip数据包缓冲区
uip_buf数列用于盛放传入/传出的数据包。设备驱动应将传入的数据放于此缓冲区中。发送数据时,设备驱动从缓冲区中读取链路层的头和TCP/IP头。链路层头的大小在UIP_LLH_LEN中定义。 注意:
应用数据无需放在这个缓冲区中,所以设备驱动需要从uip_appdata指针所指的地方读取数据。下面是一个例子:
1. void
2. devicedriver_send(void) 3. {
4. hwsend(&uip_buf[0], UIP_LLH_LEN);
5. if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { 6. hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); 7. } else {
8. hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
9. hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); 10. } 11. }
此变量于uip.c的139 定义。 此变量被uip_process()引用。 追加:下面是原文档中另一页的内容,但仅有一项,且与本页内容一体,所以追加于本页.