15

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 Studios (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

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

: 前

: 後

4

4 に答える 4

10

dbg regs のロックを解除できない可能性があります (DWT->LAR = 0xC5ACCE55): 以下のシーケンスで pb が解決されました:

      CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
      DWT->LAR = 0xC5ACCE55; 
      DWT->CYCCNT = 0;
      DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
于 2016-05-20T11:45:55.157 に答える
6

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

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

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

ツールチェーンがコードに干渉しないようにしてください。OpenOCD/gdb にはありません。手動プロファイリング機能を提供するツールについてはわかりません。

コメントですでに強調したように、レジスターに自作の定義を使用しないでください。ST (および ARM) は、使用する必要がある標準周辺モジュール (DWT と CoreDebug は実際には ARM IP です) 用の CMSIS ヘッダーを提供します。これには、マジック ナンバーの使用ではなく、定義済みの定数/マクロの使用が含まれます。

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

于 2016-04-02T23:21:10.057 に答える
4

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 が述べたように、より効率的でした ;)

于 2016-12-16T16:31:26.757 に答える
-1

これは私のために働いた:

//address of the register
volatile unsigned int *DWT_CYCCNT   = (volatile unsigned int *)0xE0001004;     

//address of the register
volatile unsigned int *DWT_CONTROL  = (volatile unsigned int *)0xE0001000;     

//address of the register
volatile unsigned int *DWT_LAR      = (volatile unsigned int *)0xE0001FB0;     

//address of the register
volatile unsigned int *SCB_DEMCR    = (volatile unsigned int *)0xE000EDFC;

...

*DWT_LAR = 0xC5ACCE55; // unlock (CM7)
*SCB_DEMCR |= 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1 ; // enable the counter

...

x = *DWT_CYCCNT;

... テスト中のコード:

y = *DWT_CYCCNT;
x = (y - x); // Elapsed clock ticks, at SystemCoreClock
于 2018-06-21T06:49:01.617 に答える