рд╕реА ++, рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рд░рдЬрд┐рд╕реНрдЯрд░

рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░!


рдЕрдм рдХрдИ рд╡рд░реНрд╖реЛрдВ рд╕реЗ, рдореИрдВ рд╕реА + + рдореЗрдВ stm32 рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рд╕рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред


рдЗрд╕ рд╕рдордп рдХреЗ рджреМрд░рд╛рди, рдореИрдВрдиреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдЬрдорд╛ рдХреА рд╣реИ рдЬреЛ рдЕрдиреНрдп рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдмреНрдпрд╛рдЬ рдХреА рд╣реЛ рд╕рдХрддреА рд╣реИред


рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреНрд░рд╢реНрдиреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП: рдореИрдВ QtCreator + gcc + gdb + openocd рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдИ рдмрд╛рд░ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╡рд╣рд╛рдБ рдирд╣реАрдВ рд░реБрдХрддрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдкрдХреЛ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдмрддрд╛рддрд╛ рд╣реВрдБред


рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдкрд░, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдкрд░рд┐рдзреАрдп рдЪрд╛рд▓рдХ рд╣реИрдВред рдЪрд▓реЛ рдЙрдирдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред


рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВ, рдпрджрд┐ рд╕рдВрднрд╡ рд╣реЛ, рддреЛ рдПрд╕рдкреАрдПрд▓, рдПрдЪрдПрдПрд▓ рдФрд░ рднрдЧрд╡рд╛рди рдЬреИрд╕реЗ рд░рд╛рдХреНрд╖рд╕реЛрдВ рдХреЗ рд╕рд╛рде рдЦрд┐рд▓рд╡рд╛рдбрд╝ рди рдХрд░реЗрдВ, рднрдЧрд╡рд╛рди рдореБрдЭреЗ рдорд╛рдл рдХрд░реЗрдВ, рдХреНрдпреВрдмрдореИрдХреНрд╕, рдкреИрд╕реЗ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, "рдмрдбрд╝реА рдорд╢реАрдиреЛрдВ рдХреЗ рд▓рд┐рдП" рд░реВрдкрд░реЗрдЦрд╛ рдХреА рд╡рд┐рдЪрд╛рд░рдзрд╛рд░рд╛, рд╡рд╣рд╛рдБ рд╢рд╛рддрд┐рд░ рд╣реИред рд▓рдЪреАрд▓реЗ рдФрд░ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рди рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреЛрдИ рдЗрд╕рдХреЗ рд╕рд╛рде рдмрд╣рд╕ рдХрд░реЗрдЧрд╛) рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдмрдбрд╝реЗ рдФрд░ рдЙрдк-рд░реВрдкреА рдорд╢реАрди рдХреЛрдб рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдкрд░ рдХрдИ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдСрдкрд░реЗрд╢рди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рд╣рд╛рдВ, рдЖрдзреБрдирд┐рдХ рдирд┐рдпрдВрддреНрд░рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЬрд┐рд╕ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╣ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╕рдм рдХреБрдЫ рдХрд░рдиреЗ рджреЗрдВред


рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд▓рд┐рдП рдкрд░рд┐рдзреАрдп рдкреНрд░рдмрдВрдзрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛:


  • рд╕рднреА рдирд┐рд░рдВрддрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╢реАрди рдХреЛрдб рдореЗрдВ рдЧрд┐рд░рдирд╛ рдЪрд╛рд╣рд┐рдП;
  • рд╕рдВрдХрд▓рдХ рдХреЛ рдХрд╛рд░реНрдп рдХреЗ рд╢реЗрд░ рдХреА рд╣рд┐рд╕реНрд╕реЗрджрд╛рд░реА рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рд╕рд╛рде рд╣реА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рджрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП;
  • рдореИрдХреНрд░реЛ рдЬрд░реВрд░рдд рдирд╣реАрдВ рдХрдо рд╕реЗ рдХрдо рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд╣рд╛рдВ рдпрд╣ рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рдХрдордЬреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреЗрддреГрддреНрд╡ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ;
  • рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдХреЛрдб рдкрдардиреАрдпрддрд╛ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдВрднрд╡рддрдГ рдХреЗрд╡рд▓ рдЖрд▓рд╕реА рдиреЗ рд░рдЬрд┐рд╕реНрдЯрд░ рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдмрд╛рдЗрдХ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдпрд╣ рдПрдХ рд╢рд┐рдлреНрдЯ рдкреНрд▓рд╕ рд▓реЙрдЬрд┐рдХрд▓ рдСрдкрд░реЗрд╢рдВрд╕ рдПрдХ рд▓рд╛ рд╕реАрдПрдордПрд╕рдЖрдИрдПрд╕ рд╣реИ, рдФрд░ рдореИрдХреНрд░реЛрдЬрд╝ рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдЬреЛ рдЕрдкрдиреЗ рдЬрдЯрд┐рд▓ рдЖрдВрддреНрд░реЛрдВ рдореЗрдВ рд╕рдорд╛рди рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрд╕рдЯреА рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рд╢реИрд▓реА рдореЗрдВ рд╣реИрдВред рдПрдХ рд╕рдордп рдкрд░, рдореИрдВрдиреЗ рднреА рдмрд┐рдЯ рдлрд╝реАрд▓реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛, рдЖрдЦрд┐рд░рдХрд╛рд░, рдореИрдВ рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдЖрдпрд╛, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВ рдЖрдкрдХрд╛ рдкрд░рд┐рдЪрдп рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред


рдЗрд╕рдХреЗ рдмрд╛рдж, рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рдЪреАрдиреА рдПрд╕рдЯреАрдПрдо 32 рдПрдл 103 рдФрд░ рдЙрд╕рдХреЗ рдлреНрд▓реИрд╢ рдПрдХреНрд╕реЗрд╕ рдХрдВрдЯреНрд░реЛрд▓ рд░рдЬрд┐рд╕реНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдмрд╣реБрдд рдкреНрдпрд╛рд░реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЬреЛ рдХрд┐ рд╡рд╣рд╛рдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрджрд╛рд╣рд░рдг рд╕рд░рд▓ рдФрд░ рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛ред



flash CMSIS 72:


FLASH->ACR = (FLASH->ACR &
              (~(FLASH_ACR_LATENCY_Msk
                 | FLASH_ACR_PRFTBE_Msk ))) //    
             | FLASH_ACR_LATENCY_1          //   ,    
             | FLASH_ACR_PRFTBE;

, ? , - , , . . , , :


0x80001ec                  04 4a        ldr r2, [pc, #16]   ; (0x8000200 <main()+20>)
0x80001ee  <+    2>        13 68        ldr r3, [r2, #0]
0x80001f0  <+    4>        23 f0 17 03  bic.w   r3, r3, #23
0x80001f4  <+    8>        43 f0 12 03  orr.w   r3, r3, #18
0x80001f8  <+   12>        13 60        str r3, [r2, #0]

, : --. ?


. .


, . . flash :


struct Regs {
    uint32_t ACR;   
    //      
};

:


struct ACR {
    constexpr static uint8_t LATENCY[]{ 0, 3 };
    constexpr static uint8_t HLFCYA[]{ 3, 1 };
    constexpr static uint8_t PRFTBE[]{ 4, 1 };
    constexpr static uint8_t PRFTBS[]{ 5, 1 };
};  

тАФ , тАФ . Python SVD .


, . constexpr :


constexpr static uint32_t base = 0x40022000; //    
INLINE constexpr static volatile Regs* rg()
{
    return reinterpret_cast<volatile Regs*>(base);
}

base , (, , , , ) . .


INLINE


#ifndef INLINE
#define INLINE __attribute__((__always_inline__)) inline 
#endif

, . , , gcc .


flash :


INLINE static void setLatency(Flash::Latency latency, bool prefetchBufferEnable = false) 
{ 
    setRegister(rg()->ACR,
        ACR::LATENCY, static_cast<uint8_t>(latency),
        ACR::PRFTBE, prefetchBufferEnable
    ); 
}

, : , . latency , . static_cast<uint8_t>(latency) , , , Latency :


enum class Latency : uint8_t {
    zeroWaitState = 0b000,
    oneWaitState = 0b001,
    twoWaitStates = 0b010
};


Flash::setLatency(Flash::Latency::twoWaitStates, true);

:


0x80001ec                  04 4a        ldr r2, [pc, #16]   ; (0x8000200 <main()+20>)
0x80001ee  <+    2>        13 68        ldr r3, [r2, #0]
0x80001f0  <+    4>        23 f0 17 03  bic.w   r3, r3, #23
0x80001f4  <+    8>        43 f0 12 03  orr.w   r3, r3, #18
0x80001f8  <+    12>       13 60        str r3, [r2, #0]

CMSIS: --, .


? setRegister. :


template<typename T, typename V, typename... Args>
INLINE constexpr static void setRegister(volatile uint32_t& reg,
                                         const T field,
                                         const V value,
                                         const Args... args)
{
    uint32_t mask = setMaskR(field, value, args...);
    uint32_t val = setBitsR(field, value, args...);

    reg = (reg & (~mask)) | val;
}

( uint32_t) тАФ . .
:


template<typename V, typename T>
INLINE constexpr static uint32_t setBitsR(T field, V val)
{
    return (val << (field[0]));
}

template<typename V, typename T, typename... Args>
INLINE constexpr static uint32_t  setBitsR(T field, V val, Args... args)
{
    return (val << (field[0])) | setBitsR(args...);
}  

template<typename V, typename T>
INLINE constexpr static uint32_t setMaskR(T field, V val)
{
    return ((((1 << field[1]) - 1) << field[0]));
}

template<typename V, typename T, typename... Args>
INLINE constexpr static uint32_t  setMaskR(T field, V val, Args... args)
{
    return ((((1 << field[1]) - 1) << field[0])) | setMaskR(args...);
}

"" . " " , , , , , , .


setRegister? . , - - тАФ . , , , , volatile, , . , , .


. :


Flash::setLatency(Flash::Latency::twoWaitStates, true);
Flash::setLatency(Flash::Latency::oneWaitState, true);

--:


0x80001ec                  07 4a        ldr r2, [pc, #28]   ; (0x800020c <main()+32>)
0x80001ee  <+    2>        13 68        ldr r3, [r2, #0]
0x80001f0  <+    4>        23 f0 17 03  bic.w   r3, r3, #23
0x80001f4  <+    8>        43 f0 12 03  orr.w   r3, r3, #18
0x80001f8  <+   12>        13 60        str r3, [r2, #0]        ;  
0x80001fa  <+   14>        13 68        ldr r3, [r2, #0]
0x80001fc  <+   16>        23 f0 17 03  bic.w   r3, r3, #23
0x8000200  <+   20>        43 f0 11 03  orr.w   r3, r3, #17
0x8000204  <+   24>        13 60        str r3, [r2, #0]        ;  

:


template<typename T>
INLINE constexpr static uint32_t getRegField(volatile uint32_t& reg,
                                             const T field)
{
    uint32_t mask = (((1 << field[1]) - 1) << field[0]); 
    return ((reg & mask) >> field[0]);
}

.


тАФ :


INLINE static bool getLatencyPrefetch()
{
    return getRegField(rg()->ACR,
                       ACR::LATENCY,
                       ACR::PRFTBE);
}

flash :


struct Flash {
    constexpr static uint32_t base = 0x40022000; //<   

struct ACR {
    constexpr static uint8_t LATENCY[]{ 0, 3 };
    constexpr static uint8_t HLFCYA[]{ 3, 1 };
    constexpr static uint8_t PRFTBE[]{ 4, 1 };
    constexpr static uint8_t PRFTBS[]{ 5, 1 };
};    

enum class Latency : uint8_t {
    zeroWaitState = 0b000,
    oneWaitState = 0b001,
    twoWaitStates = 0b010
};

INLINE constexpr static volatile Regs* rg()
{
    return reinterpret_cast<volatile Regs*>(base);
}

INLINE static void setLatency(Flash::Latency latency, bool prefetchBufferEnable = false) 
{ 
    Utility::setRegister(rg()->ACR,
        ACR::LATENCY, static_cast<uint8_t>(latency),
        ACR::PRFTBE, prefetchBufferEnable
    ); 
}
INLINE static bool getLatencyPrefetch()
{
    return getRegField(rg()->ACR,
                       ACR::LATENCY,
                       ACR::PRFTBE);
}
};    

. , , . .


- , .


, . , DSP-. тАФ .


All Articles