Измерение тактов на кортексе m7

Я измерял счетчик тактов на кортексе m4 и теперь хотел бы сделать это на кортексе m7. Я использую плату STM32F746ZG.

Для м4 все работало с:

volatile unsigned int *DWT_CYCCNT;
volatile unsigned int *DWT_CONTROL;
volatile unsigned int *SCB_DEMCR;

void reset_cnt(){
    DWT_CYCCNT   = (volatile unsigned int *)0xE0001004; //address of the register
    DWT_CONTROL  = (volatile unsigned int *)0xE0001000; //address of the register
    SCB_DEMCR    = (volatile unsigned int *)0xE000EDFC; //address of the register
    *SCB_DEMCR   = *SCB_DEMCR | 0x01000000;
    *DWT_CYCCNT  = 0; // reset the counter
    *DWT_CONTROL = 0; 
}

void start_cnt(){
    *DWT_CONTROL = *DWT_CONTROL | 0x00000001 ; // enable the counter
}

void stop_cnt(){
     *DWT_CONTROL = *DWT_CONTROL & 0xFFFFFFFE ; // disable the counter    
}

unsigned int getCycles(){
    return *DWT_CYCCNT;
}

Проблема состоит в том, что регистр DWT_CTRL не изменяется при запуске на m7 и остается 0x40000000 вместо изменения на 0x40000001, поэтому счетчик циклов всегда равен нулю. Из того, что я читал в других сообщениях, кажется, что вам нужно установить регистр FP_LAR в 0xC5ACCE55, чтобы иметь возможность изменять DWT_CTRL.

Я добавил эти определения (попробовал оба адреса FP_LAR_PTR ниже):

#define FP_LAR_PTR ((volatile unsigned int *) 0xe0000fb0) //according to reference
//#define FP_LAR_PTR ((volatile unsigned int *) 0xe0002fb0) //according to guy on the internet
// Lock Status Register lock status bit
#define DWT_LSR_SLK_Pos                1
#define DWT_LSR_SLK_Msk                (1UL << DWT_LSR_SLK_Pos)
// Lock Status Register lock availability bit
#define DWT_LSR_SLI_Pos                0
#define DWT_LSR_SLI_Msk                (1UL << DWT_LSR_SLI_Pos)
// Lock Access key, common for all
#define DWT_LAR_KEY                    0xC5ACCE55

и эта функция:

void dwt_access_enable(unsigned int ena){
    volatile unsigned int *LSR;
    LSR = (volatile unsigned int *) 0xe0000fb4;
    uint32_t lsr = *LSR;;
    //printf("LSR: %.8X - SLI MASK: %.8X\n", lsr, DWT_LSR_SLI_Msk);

    if ((lsr & DWT_LSR_SLI_Msk) != 0) {
        if (ena) {
            //printf("LSR: %.8X - SLKMASK: %.8X\n", lsr, DWT_LSR_SLK_Msk);
            if ((lsr & DWT_LSR_SLK_Msk) != 0) {    //locked: access need unlock
                *FP_LAR_PTR = DWT_LAR_KEY;
                printf("FP_LAR directly after change: 0x%.8X\n", *FP_LAR_PTR);
            }
        } else {
            if ((lsr & DWT_LSR_SLK_Msk) == 0) {   //unlocked
                *FP_LAR_PTR = 0;
                 //printf("FP_LAR directly after change: 0x%.8X\n", *FP_LAR_P,TR);
            }
        }
    }
}

Когда я вызываю некомментированную печать, я получаю 0xC5ACCE55, но когда я печатаю ее после возврата функции, я получаю 0x00000000, и я понятия не имею, почему. Я на правильном пути или это совершенно неправильно?

Изменить: Я думаю, что было бы также хорошо упомянуть, что я пытался без всего дополнительного кода в функции и только пытался изменить регистр LAR.

Б.Р. Густав

 old_timer13 июл. 2016 г., 23:02
Я использую обнаружение stm32f7 с микроконтроллером STM32F746NGH6
 G. Johnsson14 июл. 2016 г., 00:25
Нет, это не так, и это эффект проблемы, которую я пытаюсь описать. Мне как-то нужно иметь возможность изменить бит 0 в DWT_CTRL. Я попробую ответ Notlikethat ниже и вернусь с результатом :)
 Clifford14 июл. 2016 г., 10:45
Я сообщил об ошибке документации в ARM через их обратную связь с документацией.
 old_timer13 июл. 2016 г., 18:58
В вашем Cortex-M7 эта функция реализована? Существуют и другие таймеры (systick), которые в случае их реализации могут также подсчитывать тактовые частоты ядра ARM.
 old_timer14 июл. 2016 г., 05:37
Из моих собственных экспериментов выяснилось, что DWT_LAR и DWT_LSR находятся в 0xE0001FB0 и 0xE0001FB4. Документация по вооружению неверна, но таблица TRM выглядит немного подозрительно, имея только эти два регистра без 0x1xxx
 old_timer13 июл. 2016 г., 23:00
хм, пока я получаю 0x00000000, когда я читаю 0xE0001000, я получаю 0xFFF02003, когда я читаю 0xE00FF004
 G. Johnsson13 июл. 2016 г., 17:59
О, мой плохой, я этого не заметил, все же кажется, что я иногда могу читать из этого. В любом случае, если мы игнорируем мою ошибку, я все равно получаю 0 тактов, когда я: запускаю счетчик -> вызываю функцию, которую хочу измерить -> останавливаю счетчик -> считываю тактовые циклы. Я попытался без какого-либо чтения из регистра LAR, если это разрушило бы это, и это все еще не работает.
 G. Johnsson13 июл. 2016 г., 20:08
Когда я читаю DWT_CTRL, он говорит 0x40000000, в соответствии сweb.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/... на стр. C1-48 и C1-49 25-й бит NOCYCCNT должен быть равен 1, если CYCCNT не поддерживается, и в этом случае он равен 0. Надеюсь, я ответил на то, что вы спросили.
 old_timer13 июл. 2016 г., 23:26
пытаясь установить младшие биты (включая включение счетчика циклов) в элементе управления DWT, они считывают нули. так действительно ли это запись в dwt control?
 old_timer13 июл. 2016 г., 23:18
ладно, при настройке TRCENA в DEMCR я также вижу 0x40000000, но в счетчике DWT счетчик отсутствует.
 Notlikethat13 июл. 2016 г., 17:46
 old_timer13 июл. 2016 г., 23:02
Таблица 11-1 показывает регистры DWT. В зависимости от реализации вашего процессора некоторые из этих регистров могут отсутствовать. Любой регистр, который настроен как отсутствующий, читает как ноль
 Clifford14 июл. 2016 г., 10:31
Если вы «читали в других сообщениях», полезно предоставить ссылку или цитату, чтобы мы могли проверить, что то, что вы читаете, действительно актуально. CM7 не имеет регистра FP_LAR AFAIK, поэтому неясно, на что вы ссылаетесь - хотя в моем ответе я сделаю обоснованное предположение, и оно отличается от регистра, к которому вы обращаетесь.

Ответы на вопрос(2)

когда они определены как часть CMSIS - для этого требуется, чтобы и документация, и ваша интерпретация были правильными. В этом случае кажется, что документация действительно неверна, но заголовки CMSIS верны. Намного проще автоматически проверять заголовки CMSIS, чем проверять правильность документации, поэтому я каждый раз доверял бы CMSIS.

Я не уверен, что зарегистрироватьсяFP_LAR может относиться к, но ваше назначение адресов относится кITM_LAR, но более вероятно, что вы намеревалисьDWT_LAR которой не хватает Cortex-M4.

Несмотря на мой совет доверять этому, CMSIS 4.00 не определяет маски дляDWT_LSR/SWT_LAR, но я считаю, что они идентичны соответствующим маскам ITM.

Обратите внимание также, чтоLAR этотолько для записи зарегистрироваться - любая попытка прочитать это бессмысленно.

Ваш код с использованием CMSIS будет:

#include "core_cm7.h"  // Applies to all Cortex-M7

void reset_cnt()
{
    CoreDebug->DEMCR |= 0x01000000;
    DWT->CYCCNT = 0; // reset the counter
    DWT->CTRL = 0; 
}

void start_cnt()
{
    DWT->CTRL |= 0x00000001 ; // enable the counter
}

void stop_cnt()
{
     DWT->CTRL &= 0xFFFFFFFE ; // disable the counter    
}

unsigned int getCycles()
{
    return DWT->CYCCNT ;
}

// Not defined in CMSIS 4.00 headers - check if defined
// to allow for possible correction in later versions
#if !defined DWT_LSR_Present_Msk 
    #define DWT_LSR_Present_Msk ITM_LSR_Present_Msk ;
#endif
#if !defined DWT_LSR_Access_Msk 
    #define DWT_LSR_Access_Msk ITM_LSR_Access_Msk ;
#endif
#define DWT_LAR_KEY 0xC5ACCE55

void dwt_access_enable( unsigned ena )
{
    uint32_t lsr = DWT->LSR;;

    if( (lsr & DWT_LSR_Present_Msk) != 0 ) 
    {
        if( ena ) 
        {
            if ((lsr & DWT_LSR_Access_Msk) != 0) //locked: access need unlock
            {    
                DWT->LAR = DWT_LAR_KEY;
            }
        } 
        else 
        {
            if ((lsr & DWT_LSR_Access_Msk) == 0) //unlocked
            {   
                DWT->LAR = 0;
            }
        }
    }
}
 Notlikethat14 июл. 2016 г., 22:45
@Clifford FWIW, FP_LAR - это LAR CoreSight дляФлэш-патч / точка останова (который на самом деле не поддерживает то, что названо в первую очередь, иди разберись ...)
 Clifford14 июл. 2016 г., 22:59
@Notlikethat: Ах! FP = FlashPatch (не с плавающей точкой). Однако в этом случае представляется более вероятным, что DWT_LAR / LSR были предназначены. Документация неверна и для FP_LAR / LSR. FPB не определен в CMSIS core_cm7.h - я ожидаю, что он будет более полезным для отладчиков, чем для прямого доступа из кода - более того, он не реализован на всех устройствах CM7.
 old_timer14 июл. 2016 г., 15:36
Точно так же, как исправить документы, если их никто не читает? Я уже разместил билет, чтобы вооружиться этим, посмотрим, куда он идет, но, по крайней мере, кто-то там был уведомлен.
 old_timer14 июл. 2016 г., 15:35
Вы исходите из предположения, что CMSIS верна. Что также плохо / хорошо, если предположить, что документы верны. Кто-то написал заголовки CMSIS, используя какой-то ресурс. Для компании лучше всего иметь одну базу данных и генерировать адреса документации и заголовочные файлы. Держу пари, что это исключение, а не правило. CMSIS имеет свой собственный багаж, может быть вырезан и вставлен из него в случае сомнений, но не думайте, что он более правильный, чем документы.
 Clifford14 июл. 2016 г., 22:35
@dwelch: я ничего не предполагаю; Я просто говорю, что CMSIS поддается автоматическому модульному тестированию и валидации таким же образом, как и документация. Даже если бы CMSIS соответствовал документации, это было бы не хуже, чем реализованный пользователем код из документации - зачем изобретать его заново? Более того, core_cmX является основополагающим для всей CMSIS и используется тысячами проектов - гораздо больше разработчиков, чем, возможно, прочитали бы документацию с таким уровнем детализации. В CMSIS и DWT_LAR / LSR отличаются от документации (и ITM), что более правдоподобно.
 Clifford14 июл. 2016 г., 22:44
@dwelch: Вам все еще нужно прочитать документацию, чтобы узнать, для чего нужны регистры и как они работают - CMSIS не скажет вам этого. В этом случае, безусловно, верно, что использование CMSIS позволило бы избежать этой проблемы. Если бы я использовал CMSIS и обнаружил проблему, я бы перепроверил документацию таким же образом (в обратном порядке), но начать с CMSIS было бы меньше работы.
Решение Вопроса

я теперь невероятно подозрительно отношусь к ошибке опечатки или копирования-вставки в ARM TRM. 0xe0000fb0 задается как адрес ITM_LAR, DWT_LARа также FP_LSR (и эквивалентно для * _LSR). Поскольку все остальные регистры ITMявляются на странице 0xe0000000 это выглядит очень похоже на то, кто бы ни отвечал за эту часть документации Cortex-M7, взял определения регистров Cortex-M4, добавил новые LAR и LSR на страницу ITM, а затем скопировал их на страницы DWT и FPB обновление имен, но с видом на обновление адресов.

Держу пари, что вы невольно разблокируете ITM_LAR (или реальный FP_LAR), а DWT_LAR фактически равен 0xe0001fb0.

РЕДАКТИРОВАТЬ по dwelch

Кто-то должен кому-то ужин.

hexstring(GET32(0xE0001FB4));
hexstring(GET32(0xE0001000));
hexstring(GET32(0xE0001004));
hexstring(GET32(0xE0001004));

PUT32(0xE000EDFC,0x01000000);

hexstring(GET32(0xE0001FB4));
hexstring(GET32(0xE0001000));
hexstring(GET32(0xE0001004));
hexstring(GET32(0xE0001004));

PUT32(0xE0001000,0x40000001);

hexstring(GET32(0xE0001FB4));
hexstring(GET32(0xE0001000));
hexstring(GET32(0xE0001004));
hexstring(GET32(0xE0001004));

PUT32(0xE0001FB0,0xC5ACCE55);
PUT32(0xE0001000,0x40000001);

hexstring(GET32(0xE0001FB4));
hexstring(GET32(0xE0001000));
hexstring(GET32(0xE0001004));
hexstring(GET32(0xE0001004));

выход

00000000
00000000
00000000
00000000
00000003
40000000
00000000
00000000
00000003
40000000
00000000
00000000
00000001
40000001
0000774F
0000B311

Таблица в TRM выглядит забавно, и, как показывает другая документация, вы добавляете 0xFB0 и 0xFB4 к базе, остальная часть DWT для Cortex-M7 равна 0xE0001xxx, и действительно, кажется, что LAR и LSR являются 0xE0001FB0 и 0xE0001FB4 ,

 old_timer14 июл. 2016 г., 05:36
@ Notlikethat я отредактировал твой ответ вместо того, чтобы добавить свой, это было твоим выводом, я только что сделал эксперимент несколькими днями ранее чем OP Пожалуйста, отредактируйте по своему вкусу (или удалите все мои правки вместе, что угодно).
 G. Johnsson18 июл. 2016 г., 11:56
0xe0001fb0 у меня тоже работает! Теперь единственное, что он показывает больше тактов для операций dft и fft по сравнению с m4, но это другая проблема :)
 G. Johnsson14 июл. 2016 г., 00:04
Хорошо, я обязательно попробую, когда вернусь в понедельник и вернусь к тебе. Я также читал где-то еще, что ссылка была неправильной, но он предложил 0xe0002Вместо этого fb0, но я попробовал это, и это не сработало.
 Notlikethat14 июл. 2016 г., 00:11
Да, e0002fb0 будет выглядеть как соответствующая блокировка для блока FPB, как я намекал. Кажется, парень посередине - единственный, кого никто не пробовал;)
 G. Johnsson14 июл. 2016 г., 00:16
Да, также я думаю, что я должен изменитьFP_LAR_PTR в кодеDWT_LAR_PTRЯ запутался при исследовании этого :)

Ваш ответ на вопрос