2017-03-20 17 views
0

私は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)の値をチェックして値が変更されていないことを確認します。レジスタ(アドレスカウントに使用される)はプリエンプション前と同じではありません。
それぞれのローカル変数がデータメモリから間違って取得されるため、それぞれのローカル変数が同じでない場合があります。
スタックオーバーフローの問題がある場合、どうすればデバッグできますか?

+0

最も簡単な方法は、タスクのスタックサイズを増やして、問題がなくなるかどうかを確認することです。これが小さすぎる場合は、システムスタックサイズを増やすこともできます。どのツールチェーンを使用していますか?また、私はmallocがタスクループ内にないと仮定します。 –

+0

FreeRTOSヒープサイズにはほとんどのRAMが割り当てられ、xPortGetMinimumEverFreeHeapSize()は約50MBの空き容量を返します。私は自分の仕事ごとにさらに2倍のスタックサイズを割り当てました。それぞれのタスクに対して、uxTaskGetStackHighWaterMarkは、スタックオーバーフローが発生しないことを示す値を返します。私がチェックしなかった唯一のタスクはLWiPスレッドですが、問題はないと思います。 私はgcc-arm-none-eabi-5_4-2016q3を使用しています。 これはタスクループ内ですが、ループは次のように始まります。 xQueueReceive() これは1時間に1回ブロックされません。 もちろん、最後にメモリが解放されます。 –

+0

それはスタックオーバーフローの問題のようには聞こえません。レジスタの格納と復元は、xPortPendSVHandler(自動的に格納されているものは別として)で行われます。あなたはここでデバッグすることができますが、すべてのコンテキストスイッチのためにここに来るので、タスクを復元するときにそれをキャッチするのは難しいことがあります。 –

答えて

1

Cortex-Mの主な問題は、割り込みの優先順位の割り当てとスタックオーバーフローが誤っているため、FreeRTOSの後のバージョンではこれらの両方のエラーのトラップが多く発生していますが、

configASSERT()が定義されていますか、どのバージョンのFreeRTOSを使用していますか?後のバージョンでは、より役に立つconfigASSERT()が使用されます。

configCHECK_FOR_STACK_OVERFLOWが2に設定されていて、スタックオーバーフローフックが定義されていますか?

+0

configassertは次のように定義されています。 #define configASSERT(x)if((x)== 0){taskDISABLE_INTERRUPTS(); for(;;);} バージョンは8.2.3です。 はい、スタックオーバーフローフックを使用し、mallocもフックに失敗しました。彼らからは何の問題も報告されていない。 –

+0

別のタスクがこのタスクスタックにスタンプしているのでしょうか? –

0

問題の原因が見つかりました。 blockingFunction()の中に明示的に記入したバッファーがあった。バッファーが小さすぎてタスクのTCBを上書きしました。

関連する問題