Araiさん
修正版で何度かテストしても発生しませんし、24時間以上動作させても発生しなくなりました。不具合の証拠が提出できないので、引っ込めました。
解消した理由について究明できてませんが、RZのEthernetInterfaceの実装において、複数の場所でus_ticker_read()を利用しているということから、us_ticker_read()の戻り値がラップアラウンドするタイミングでなんらかの問題があったのであろうと判断しています。
mbed-src-v442-pre(v444)においても、割り込み禁止に関する部分をコメントアウトするだけで再現できます。
実はTCPのコネクションを確立する必要すらなく、以下のプログラムでも再現可能です。接続先のサーバ用意する必要はありません。LANケーブルを繋げなくてもOKです。
main.cpp
#include "mbed.h"
#include "EthernetInterface.h"
EthernetInterface eth;
Serial pc(USBTX, USBRX);
int main()
{
eth.init(); //Use DHCP
eth.connect();
while(1) {
uint32_t t1 = us_ticker_read();
wait_ms(5000);
// Thread::wait(5000);
uint32_t t2 = us_ticker_read();
pc.printf("t1:%u t2:%u t2-t1:%u\r\n", t1, t2, (t2-t1));
}
eth.disconnect();
}
※実際には毎度1:11:31も待てないので、wrap_arround=32;としてテストしています。162秒ほどで発生させることが可能です。
RZはメモリもCPUも有り余っているので、Tickerやwaitではなくて、RTOSのRtosTimerやThread::waitを使うべきなんでしょうね。
ARMコンパイラの動作については了解しました。ありがとうございます。
↓こうする必要があるという事ですね。危ないので覚えておきます。
確かに、暗黙的なdoubleから整数型への変換は整数部がオーバーフローする時の動作は未定義なので実装依存でした。
組み込み系だと最大値に丸める実装が定番なんでしょうか。
(uint32_tへのキャストを指定しなければそうなっても仕方が無いと思いますが、指定しているので違う気も...)
UNIX系だと、整数化後に代入先のサイズに切り詰める実装が多いのでこちらを期待してしまいした。元のコードを書いた方も同じ認識だったのではないかと。
※Linux(x86, x86_64)+GCC, MacOS X(x86_64)+LLVM, HP-UX(IA64)+HP aCCのいずれも後者でした。