Measuring clock cycle count on cortex m7

前端 未结 2 971
不知归路
不知归路 2021-02-06 03:27

I have been measuring clock cycle count on the cortex m4 and would now like to do it on the cortex m7. The board I use is STM32F746ZG.

For the m4 everything worked with

相关标签:
2条回答
  • 2021-02-06 03:58

    Looking at the docs again, I'm now incredibly suspicious of a typo or copy-paste error in the ARM TRM. 0xe0000fb0 is given as the address of ITM_LAR, DWT_LAR and FP_LSR (and equivalently for *_LSR). Since all the other ITM registers are in page 0xe0000000, it looks an awful lot like whoever was responsible for that part of the Cortex-M7 documentation took the Cortex-M4 register definitions, added the new LAR and LSR to the ITM page, then copied them to the DWT and FPB pages updating the names but overlooking to update the addresses.

    I'd bet my dinner that you're unwittingly unlocking ITM_LAR (or the real FP_LAR), and DWT_LAR is actually at 0xe0001fb0.

    EDIT by dwelch

    Somebody owes somebody a dinner.

    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));
    

    output

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

    The table in the TRM is funny looking and as the other documentation shows you add the 0xFB0 and 0xFB4 to the base, the rest of the DWT for the Cortex-M7 is 0xE0001xxx and indeed it appears that the LAR and LSR are ate 0xE0001FB0 and 0xE0001FB4.

    0 讨论(0)
  • 2021-02-06 04:06

    I would advise against creating your own register definitions when they are defined as part of the CMSIS - to do so requires that both the documentation and your interpretation of it are correct. In this case it appears that the documentation is indeed incorrect, but that the CMSIS headers are correct. It is a lot easier to validate the CMSIS headers automatically than it is to verify the documentation is correct, so I would trust the CMSIS every time.

    I am not sure what register FP_LAR might refer to, but your address assignment refers to ITM_LAR, but it seems more likely that you intended DWT_LAR which Cortex-M4 lacks.

    Despite my advice to trust it, CMSIS 4.00 omits to define masks for DWT_LSR/SWT_LAR, but I believe they are identical to the corresponding ITM masks.

    Note also that the LAR is a write-only register - any attempt to read it is meaningless.

    Your code using CMSIS would be:

    #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;
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题