Cコンパイラは、私が期待していない変数を最適化しているようです。問題のコードは次のとおりです。予期せぬ変数を削除するCオプティマイザ
uint32_t GetSysTick(void);
uint32_t timeout = GetSysTick() + 9000; //9sec
while(len && (GetSysTick() < timeout))
{
... some code that will decrement len
}
コンパイラは、「タイムアウト」変数を最適化します。通常、whileループはlenがゼロになると終了しますが、プロセスが予想以上に時間がかかると、タイムアウトがタイムアウトを超えたら終了します。もちろん、タイムアウトが最適化されていれば、これは起こりません。タイムアウトを揮発性として定義すると、最適化されずに維持されるはずですが、技術的には揮発性ではないと確信しています。私はここで何が欠けていますか? GetSysTick()の戻り値にvolatileを使用する必要がありますか? (それが正当なものであるかどうかわからない)
完全性のためにここではGetSysTickとsystickの宣言があります。どちらも別のCファイルにあります。 systickは割り込みでミリ秒ごとにインクリメントされます。
static volatile uint32_t systick=0;
uint32_t GetSysTick(void)
{
return systick;
}
「GetSysTick」はどのように宣言されていますか? [ask]を参照し、[mcve]を提供してください。ビジー待機は良い考えではないことに注意してください。割り込み/セマフォ/タイマなどの使用を改善しました。 – Olaf
あなたはコンパイラがそれをやっていると思いますか?ループ内でタイムアウトを印刷しましたか? –
@AlexK .:あなたはポイントがあります。しかし、変数を出力するためのコードを追加すると、コード生成(Heisenberg-Effect)に影響を与える可能性があります。アセンブリコードを確認するか、デバッガを使用する方がよいでしょう。 – Olaf