web-dev-qa-db-ja.com

STM32-DWTサイクルカウンターを有効にする方法

STM32F7-Discoveryボードを使用していますが、DWTサイクルカウンターを有効にしようとしています。私がオンラインで見たことから、これを有効にするのにこれで十分です:

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;

ただし、そのコードを実行しても、値は変更されないか、操作がスキップされます(何が起こっているのかよくわかりません)。

私はメモリ内のアドレスへのポインタを作成して、何も役に立たずに直接変更しようとしました。例:

volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC;
*DEMCR = *DEMCR | 0x01000000;
*DWT_CYCCNT = 0;
*DWT_CONTROL = *DWT_CONTROL | 1;

現在、私が入手した唯一の方法は、Visual Studio(VisualGDBを使用)でデバッガーを使用してステップスルーする場合で、DWT-> CTRLの値をON値に変更すると、サイクルカウンターが開始します。それを除けば、コードを変更する価値を得ることができないようです。

編集:これらのコード行がタスクを実行していないだけでなく、クラッシュして継続しないという動作を引き起こしている可能性のあるもの。

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= 1;

これらのコード行を実行した後、それらのメモリ位置の値はすべて同じままであり、実行されるはずの操作で変更されることはありません。

例えば。 :

//DWT_CTRL_CYCCNTENA_Msk = 1
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk 

DWT-> CTRLの値は0x40000001になるはずですが、デフォルト値0x40000000のままです。

以下の図は、実行時に何が起こっているかの例です。

変更前変更後

10
KenQueso

Dbg regsのロックを解除するために欠落している可能性があります(DWT-> LAR = 0xC5ACCE55):以下のシーケンスは、私のためにpbを解決しました:

      CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
      DWT->LAR = 0xC5ACCE55; 
      DWT->CYCCNT = 0;
      DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
7
Howard Plouch

それがSTM32F7でも同じかどうかはわかりませんが、これはSTM32F4のCMSISヘッダーを使用して正しく実行する方法です(このモジュールを提供するCortex-M3/4(/ 7?)で実際に動作するはずです)。

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

トレースモジュールも有効にする必要があります。コードは割り込みセーフではないことに注意してください!一般に、カウンタはフリーランニングのままにしておき、タイミングのスナップショットの違いを取得する必要があります。

ツールチェーンがコードを妨害しないことを確認してください。 OpenOCD/gdbでは、手動プロファイリング機能を提供するツールについてはわかりません。

コメントですでに強調したように、Do n'tレジスタには自家製の定義を使用します。 ST(およびARM)は、標準の周辺モジュールにCMSISヘッダーを提供します(DWTおよびCoreDebugは実際にはARM IPs)を使用する必要があります。これにはmagicを使用しないことも含まれます)数値、ただし定義された定数/マクロ。

詳細については、「アーキテクチャリファレンスマニュアル」を参照してください。 注意:「アーキテクチャアプリケーションレベルリファレンスマニュアル」もありますが、これは必要なものではありません。

(ハワードが指摘したように)DWTレジスターへのアクセスをロック解除するために欠落していることを除いて、あなたはすべてを正しく行っています。コードでは次のようになります。

volatile uint32_t *DWT_CONTROL = (uint32_t *) 0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *) 0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *) 0xE000EDFC;
volatile uint32_t *LAR  = (uint32_t *) 0xE0001FB0;   // <-- added lock access register

*DEMCR = *DEMCR | 0x01000000;     // enable trace
*LAR = 0xC5ACCE55;                // <-- added unlock access to DWT (ITM, etc.)registers 
*DWT_CYCCNT = 0;                  // clear DWT cycle counter
*DWT_CONTROL = *DWT_CONTROL | 1;  // enable DWT cycle counter

ARMv7-Mアーキテクチャリファレンスマニュアルに記載されているように、ロックメカニズムはソフトウェアアクセスにのみ適用されることに注意してください。 DAPアクセスは常に許可されます(そのため、デバッガーを使用してサイクルカウンターを有効にできます)。

STM32F7ドキュメントARMドキュメント の両方にタイプミスがあり、ロックアクセスレジスタのアドレスとして0xE0000FB0を指定していることに注意してください( こちら を参照)。提供されたCMSISコアレジスター定義(core_cm7.h)を使用すると、この問題が正しいため、この問題を回避できます。もちろん、Olafが述べたように、より効率的でした;)

3
paolok17