c कोर्टेक्स एम 7 पर घड़ी चक्र की गणना करना




arm embedded (2)

डॉक्स पर फिर से देख, अब मैं एआरएम टीआरएम में एक टाइपो या कॉपी-पेस्ट त्रुटि की अविश्वसनीय रूप से संदिग्ध हूं। 0xe0000fb0 को ITM_LAR, DWT_LAR और FP_LSR (और * _LSR के लिए समतुल्य) के पते के रूप में दिया गया है। चूंकि अन्य सभी आईटीएम रजिस्टरों पृष्ठ 0xe0000000 में हैं, ऐसा लगता है जैसे प्रांतस्था-एम 7 दस्तावेजों के उस हिस्से के लिए जिम्मेदार कोई भी व्यक्ति कॉर्टेक्स-एम 4 रजिस्टर परिभाषाओं को लेता है, आईटीएम पेज पर नया एलएआर और एलएसआर जोड़ा, फिर कॉपी किया गया उन्हें डीडब्ल्यूटी और एफपीबी पृष्ठों के नामों को अद्यतन करने के लिए, लेकिन पतों को अद्यतन करने के लिए अनदेखा किया गया।

मैं अपने खाने के लिए शर्त लगाता हूं कि आप अनजाने आईटीएम_एलआर (या असली एफपी_एलआर) को अनलॉक कर रहे हैं, और डीडब्लूएलएलएल वास्तव में 0xe000 1 एफबी 0 पर है।

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

टीआरएम में तालिका अजीब दिख रही है और जैसा कि अन्य दस्तावेज दिखाता है कि आप बेस में 0xFB0 और 0xFB4 को जोड़ते हैं, कॉर्टेक्स-एम 7 के लिए शेष डीडब्ल्यूटी 0xE0001xxx है और वास्तव में ऐसा प्रतीत होता है कि एलएआर और एलएसआर एट 0xE0001FB0 और 0xE0001FB4 हैं ।

मैं कोर्टेक्स एम 4 पर घड़ी चक्र की गिनती को मापना है और अब इसे कॉर्टेक्स एम 7 पर करना चाहेंगे। बोर्ड का उपयोग मैं 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;
}

समस्या यह है कि जब मैं एम 7 पर चलाता हूं और 0x40000001 में बदलने के बजाय 0x40000000 रहता है तो चक्र सूची में हमेशा शून्य होता है, इसलिए DWT_CTRL रजिस्टर नहीं बदला है। मैंने जो अन्य पदों में पढ़ा है, उससे ऐसा लगता है कि आपको डीडब्लूएसीटीआरएल को बदलने में सक्षम होने के लिए 0xC5ACCE55 पर एफपी_एलआर रजिस्टर सेट करना होगा।

मैंने इन परिभाषाओं को जोड़ा (नीचे दोनों 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_PTR);
            }
        }
    }
}

जब मैं असम्मेन्ट प्रिंट को कॉल करता हूं तो मुझे 0xC5ACCE55 मिलता है, लेकिन फ़ंक्शन की वापसी के बाद जब मैं इसे मुद्रित करता हूं तो मुझे 0x00000000 मिलता है और मुझे पता नहीं क्यों है क्या मैं सही रास्ते पर हूं या यह पूरी तरह गलत है?

संपादित करें: मुझे लगता है कि यह भी उल्लेख करना अच्छा होगा कि मैंने फ़ंक्शन में सभी अतिरिक्त कोड के बिना कोशिश की है और केवल LAR रजिस्टर को बदलने की कोशिश की है।

बीआर गुस्ताव


मैं अपनी खुद की रजिस्टर परिभाषा बनाने के बारे में सलाह दूंगा जब उन्हें CMSIS के भाग के रूप में परिभाषित किया जाता है - ऐसा करने के लिए यह आवश्यक है कि दोनों दस्तावेज और आपकी यह व्याख्या सही है। इस स्थिति में ऐसा प्रतीत होता है कि दस्तावेज़ीकरण वास्तव में गलत है, लेकिन सीएमएसआईएस हेडर सही हैं। यह सही है कि दस्तावेजों को सही करने के लिए सीएमएसआईएस हेडर स्वचालित रूप से सत्यापित करना आसान है, इसलिए मैं हर बार सीएमएसआईएस पर विश्वास करता हूं।

मुझे यकीन नहीं है कि रजिस्टर FP_LAR क्या उल्लेख हो सकता है, लेकिन आपका पता असाइनमेंट का संदर्भ ITM_LAR , लेकिन ऐसा लगता है कि आप DWT_LAR इरादा DWT_LAR जो कि कॉर्टेक्स-एम 4 की कमी है।

मेरी इस पर विश्वास करने की मेरी सलाह के बावजूद, सीएमएसआईएस 4.00 DWT_LSR / SWT_LAR लिए मास्क को परिभाषित करने के लिए, लेकिन मेरा मानना ​​है कि वे इसी आईटीएम मास्क के समान हैं I

यह भी ध्यान दें कि LAR एक लेखन-केवल रजिस्टर है - इसे पढ़ने का कोई भी प्रयास अर्थहीन है।

आपका कोड सीएमएसआईएस का उपयोग होगा:

#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;
            }
        }
    }
}