私はFreeRTOSをSTM32F407で使用しています。間違ったコンテキストスイッチの復元に問題があります。コードは、この内部のタスクコードのようになります:FreeRTOSが間違ったコンテキストスイッチの復元
char *ptr = pvPortMalloc(sizeof(char) * size);
memcpy(ptr, buf, size);
...
log("Before:");
logItoa((int)ptr);
blockingFunction(); // Here preemption will occur
log("After:");
logItoa((int)ptr);
blockingFunction()ptr
を使用していません。
STR R0, [R7, #24]
私は(^ 1)アドレス(R7 + 24)の下に値を確認し、データメモリおよびそれを参照してください。私はptr
の指すアドレスは命令が格納されていることを、見ることができるデバッグ 動的に割り当てられたデータのアドレスは正常に保存されます。
コンテキスト復元後、変数ptr
をチェックして、新しく割り当てられたデータを参照していないことを確認して、アドレス(^ 1)の値をチェックして値が変更されていないことを確認します。レジスタ(アドレスカウントに使用される)はプリエンプション前と同じではありません。
それぞれのローカル変数がデータメモリから間違って取得されるため、それぞれのローカル変数が同じでない場合があります。
スタックオーバーフローの問題がある場合、どうすればデバッグできますか?
最も簡単な方法は、タスクのスタックサイズを増やして、問題がなくなるかどうかを確認することです。これが小さすぎる場合は、システムスタックサイズを増やすこともできます。どのツールチェーンを使用していますか?また、私はmallocがタスクループ内にないと仮定します。 –
FreeRTOSヒープサイズにはほとんどのRAMが割り当てられ、xPortGetMinimumEverFreeHeapSize()は約50MBの空き容量を返します。私は自分の仕事ごとにさらに2倍のスタックサイズを割り当てました。それぞれのタスクに対して、uxTaskGetStackHighWaterMarkは、スタックオーバーフローが発生しないことを示す値を返します。私がチェックしなかった唯一のタスクはLWiPスレッドですが、問題はないと思います。 私はgcc-arm-none-eabi-5_4-2016q3を使用しています。 これはタスクループ内ですが、ループは次のように始まります。 xQueueReceive() これは1時間に1回ブロックされません。 もちろん、最後にメモリが解放されます。 –
それはスタックオーバーフローの問題のようには聞こえません。レジスタの格納と復元は、xPortPendSVHandler(自動的に格納されているものは別として)で行われます。あなたはここでデバッグすることができますが、すべてのコンテキストスイッチのためにここに来るので、タスクを復元するときにそれをキャッチするのは難しいことがあります。 –