LoginSignup
2
1

More than 5 years have passed since last update.

uIPの実装 メインループを読む

Posted at

組込み用のTCP/IPプロトコルスタック uIPのソースを読んでみました。

uIPはlwIPの作者 Adam Dunkels が開発したTCP/IPプロトコルスタックです。lwUPよりも小さい環境で動作します。

ソースコードの場所
* https://github.com/adamdunkels/uip

まずはメインループを読んでみました。

uIPのメインループ

  • メインループは doc/example-mainloop-with-arp.c にあります。

    • ARPなしのexample-mainloop-without-arp.c もあり、こちらは、さらにシンプルです。
    • unix/main.c というのもあります。
  • 初期化です。 タイマ、デバイス、プロトコルスタックの初期化を行い、IPアドレスを設定します。

  • 定期タイマは500msec、ARPタイマは10秒に設定しています。

example-mainloop-with-arp.c
int
main(void)
{
  int i;
  uip_ipaddr_t ipaddr;
  struct timer periodic_timer, arp_timer;

  timer_set(&periodic_timer, CLOCK_SECOND / 2);
  timer_set(&arp_timer, CLOCK_SECOND * 10);

  network_device_init();
  uip_init();

  uip_ipaddr(ipaddr, 192,168,0,2);
  uip_sethostaddr(ipaddr);

  httpd_init();
  • ここからがメインループ
  • network_device_read()で受信パケットをBUFに読み出す
  • BUF-typeがIPならuip_input()でパケットの処理を行う。その結果uip_lenが0より大きければ、パケットを送信する。
  • BUF-typeがARPなら、uip_arp_arpin();でARPを処理する。その結果uip_lenが0より大きければ、パケットを送信する。
example-mainloop-with-arp.c
  while(1) {
    uip_len = network_device_read();
    if(uip_len > 0) {
      if(BUF->type == htons(UIP_ETHTYPE_IP)) {
    uip_arp_ipin();
    uip_input();
    /* If the above function invocation resulted in data that
       should be sent out on the network, the global variable
       uip_len is set to a value > 0. */
    if(uip_len > 0) {
      uip_arp_out();
      network_device_send();
    }
      } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
    uip_arp_arpin();
    /* If the above function invocation resulted in data that
       should be sent out on the network, the global variable
       uip_len is set to a value > 0. */
    if(uip_len > 0) {
      network_device_send();
    }
      }
  • タイマがexpireしたなら、コネクション毎にuip_periodic()の処理をする。その結果uip_lenが0より大きければ、パケットを送信する。
  • UDPが有効なら、UDPのコネクションごとにuip_udp_periodic()でUDPの定期処理を行う。その結果uip_lenが0より大きければ、パケットを送信する。
  • ARPのタイマがexpireしたら、再度ARPのタイマをセットする。
example-mainloop-with-arp.c
    } else if(timer_expired(&periodic_timer)) {
      timer_reset(&periodic_timer);
      for(i = 0; i < UIP_CONNS; i++) {
    uip_periodic(i);
    /* If the above function invocation resulted in data that
       should be sent out on the network, the global variable
       uip_len is set to a value > 0. */
    if(uip_len > 0) {
      uip_arp_out();
      network_device_send();
    }
      }

#if UIP_UDP
      for(i = 0; i < UIP_UDP_CONNS; i++) {
    uip_udp_periodic(i);
    /* If the above function invocation resulted in data that
       should be sent out on the network, the global variable
       uip_len is set to a value > 0. */
    if(uip_len > 0) {
      uip_arp_out();
      network_device_send();
    }
      }
#endif /* UIP_UDP */

      /* Call the ARP timer function every 10 seconds. */
      if(timer_expired(&arp_timer)) {
    timer_reset(&arp_timer);
    uip_arp_timer();
      }
    }
  }
  return 0;
}

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1