1

我有一个让我发疯的 Contiki 应用程序。

我必须计算 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 模拟停止并显示 JavaIllegal 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;
}

该函数由另一个函数定期调用,每分钟一次。

4

1 回答 1

2

You can see this in Java, or C if you have multiple threads using a library which is not thread safe. In this situation, you some times get the right value and sometimes you get half right and sometimes you get non-sense.

If you add a printf e.g. System.out.printf() or any IO or sleep() or step through the code using debugging, this really slows down your application so each thread spends a very small percentage of it's time in the library and thus indirectly avoids conflicts.

Are you using multiple threads? Is the library/methods you are calling thread safe?

于 2014-04-30T10:25:47.797 回答