Chinaunix首页 | 论坛 | 博客
  • 博客访问: 393087
  • 博文数量: 87
  • 博客积分: 1171
  • 博客等级: 少尉
  • 技术积分: 1068
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-19 14:34
文章分类

全部博文(87)

文章存档

2014年(10)

2013年(24)

2012年(53)

我的朋友

分类: 嵌入式

2012-10-12 21:22:06

#define CLOCK_SECOND CLOCK_CONF_SECOND
typedef int clock_time_t;

 

    struct timer {
  clock_time_t start;
  clock_time_t interval;
};

 

RAW_U32 clock_time()
{

 return raw_tick_count;
}

 

void
timer_set(struct timer *t, clock_time_t interval)
{
  t->interval = interval;
  t->start = clock_time();
}

 

void
timer_reset(struct timer *t)
{
  t->start += t->interval;
}

 

void
timer_restart(struct timer *t)
{
  t->start = clock_time();
}

 

int
timer_expired(struct timer *t)
{
  return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
}

 

 

 

      在主循环里初始化的时:

 while(1) {
    uip_len = tapdev_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();
   tapdev_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) {
   tapdev_send();
 }
      }

    } 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();
   tapdev_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();
   tapdev_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;
}

 

       struct timer periodic_timer, arp_timer;

 

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

 

       periodic_timer->start=xxxx  (这个值是当系统tick递增之后的某个确定值)

       periodic_timer-> interval=50  (这是时间间隔 50个滴答,相当于 500ms)

       

      在whlie(1)里面 先看看有没有数据包到来,最多花费20个tick,

      有数据包,就处理,没有数据包,就判断是否

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();
   tapdev_send();
 }
上面是判断,自上次重置定时器后是否已经500了,如果已经到了,则再次重置定时器触发事件,

  periodic_timer->start=xxxx  (这个值是当系统tick) 

       periodic_timer-> interval=50  (这是时间间隔 50个滴答,相当于 500ms)

 

到了之后,就会当前的所有连接经行uip_periodic, 其实就是把所有的连接都再执行一遍,根据里面的标志位和uip-conn->timer-- 来判断是否有超时数据需要重传。

 

    再下面就是关于UDP 和 ARP 的处理,由于UDP不能主动发送数据,所以在每次轮训的时候,看每个UDP连接是否有数据需要发送,有就发送出去,没有就不发送,     timer_set(&periodic_timer, CLOCK_SECOND / 2);这句代码决定了UDP的发送速率,由于设置的时间间隔的关系,吞吐量已经确定袭来了,如果想提高吞吐量,可以将时间的间隔减小,系统的吞吐量就会提高了,不过这样系统的负载家中了,因为执行了很多无用代码。

 

 

      这个软定时器的本质就是根据tick,设置下它本次应该终止的时间,利用

   timer_expired    

timer_expired(struct timer *t)
{
  return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;

 

来判断是否已经到达了,自己设置的时间间隔。

阅读(1513) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~