2014-04-30 60 views
1

我有Contiki应用程序,这让我发疯。如果我删除printf,应用程序无法正常工作

我必须计算Tmote Sky的能量消耗。我使用energest,这是一段代码,我在能耗预测函数中使用,这是定期调用:

lpm_time = energest_type_time(ENERGEST_TYPE_LPM); 
cpu_time = energest_type_time(ENERGEST_TYPE_CPU); 
rx_time = energest_type_time(ENERGEST_TYPE_LISTEN); 
tx_time = energest_type_time(ENERGEST_TYPE_TRANSMIT); 
lpm = lpm_time - prev_times.lpm_time; 
cpu = cpu_time - prev_times.cpu_time; 
rx = rx_time - prev_times.rx_time; 
tx = tx_time - prev_times.tx_time; 

consumed_energy = (I_LPM * lpm + I_CPU * cpu + I_RX * rx + I_TX * tx) * VOLTS/RTIMER_ARCH_SECOND; /* mJ = mA * seconds * volts */ 

/*printf("lpm %lu, cpu %lu, rx %lu, tx %lu, prl %lu, prc %lu, prr %lu, prt %lu\n", 
     lpm_time, cpu_time, rx_time, tx_time, prev_times.lpm_time, prev_times.cpu_time, prev_times.rx_time, prev_times.tx_time);*/ 

prev_times.lpm_time = lpm_time; 
prev_times.cpu_time = cpu_time; 
prev_times.rx_time = rx_time; 
prev_times.tx_time = tx_time; 

的问题是应用程序正常工作只有在printf,现在是已启用注释。 如果它仍然保留注释,我可以接收consumed_energy变量的无意义值,或者COOJA仿真停止,并显示Java Illegal read - out of bounds消息。

这是为什么发生?可能是什么原因? 这是一件很奇怪的事情。

在此先感谢。


该文件的完整代码是这样的:

volatile static struct energest_times prev_times; 


float update_consumption() 
{ 
    uint32_t lpm_time; 
    uint32_t cpu_time; 
    uint32_t rx_time; 
    uint32_t tx_time; 
    uint32_t lpm; 
    uint32_t cpu; 
    uint32_t rx; 
    uint32_t tx; 
    float consumed_energy; 

    lpm_time = energest_type_time(ENERGEST_TYPE_LPM); 
    cpu_time = energest_type_time(ENERGEST_TYPE_CPU); 
    rx_time = energest_type_time(ENERGEST_TYPE_LISTEN); 
    tx_time = energest_type_time(ENERGEST_TYPE_TRANSMIT); 
    lpm = lpm_time - prev_times.lpm_time; 
    cpu = cpu_time - prev_times.cpu_time; 
    rx = rx_time - prev_times.rx_time; 
    tx = tx_time - prev_times.tx_time; 

    consumed_energy = (I_LPM * lpm + I_CPU * cpu + I_RX * rx + I_TX * tx) * VOLTS/RTIMER_ARCH_SECOND; /* mJ = mA * seconds * volts */ 

    printf("lpm %lu, cpu %lu, rx %lu, tx %lu, prl %lu, prc %lu, prr %lu, prt %lu\n", 
      lpm_time, cpu_time, rx_time, tx_time, prev_times.lpm_time, prev_times.cpu_time, prev_times.rx_time, prev_times.tx_time); 

    prev_times.lpm_time = lpm_time; 
    prev_times.cpu_time = cpu_time; 
    prev_times.rx_time = rx_time; 
    prev_times.tx_time = tx_time; 

    printf("Consumed energy: %ld\n", (int32_t) consumed_energy); 

    return consumed_energy; 
} 

功能是定期由另一个功能,每分钟一次调用。

+0

嗯,它是Java还是C? –

+0

@z̍̄̒ͪ̚我不认为Java有'printf()'。 – unwind

+2

@aliants显示更多代码,这个片段非常小。症状指向内存损坏。 – unwind

回答

2

如果你有多个线程使用非线程安全的库,你可以在Java或C中看到。在这种情况下,你有时会得到正确的价值,有时你会得到正确的一半,有时你会感觉不到。

如果您添加了printf例如System.out.printf()或任何IO或sleep()或使用调试步骤遍历代码,这确实会减慢应用程序的运行速度,因此每个线程都会花费很少的时间在库中,从而间接避免冲突。

您是否使用多个线程?您所调用的库/方法是否安全?

+0

我想我们可以合理地假设如果'prev_times'声明中使用的'volatile'关键字的含义与Java的含义相近,我会说printf实际上改变了'prev_times'的值,即当前线程可见 – Lolo

+0

@Lolo'volatile'在C中意味着它不能被优化,它并不意味着visibiliy /线程安全。 –