В STM32 регистры, используя которые, можно достаточно просто осуществлять подсчет времени исполнения различных участков кода.
Один из этих регистров – DWT_CYCCNT, расположенный по адресу 0xE0001004, представляет собой счетчик тактов микроконтроллера. Чтобы запустить его на счет, необходимо установить младший бит (CYCCNTENA) регистра DWT_CONTROL.
#define DWT_CYCCNT *(volatile unsigned long *)0xE0001004
#define DWT_CONTROL *(volatile unsigned long *)0xE0001000
#define SCB_DEMCR *(volatile unsigned long *)0xE000EDFC
SCB_DEMCR |= 0x01000000;
DWT_CONTROL|= 1; // enable the counter
DWT_CYCCNT = 0;
for(i=0;i<1000;i++){};
time=DWT_CYCCNT;
=======================================================
#define DWT_CYCCNT *(volatile uint32_t *)0xE0001004
#define DWT_CONTROL *(volatile uint32_t *)0xE0001000
#define SCB_DEMCR *(volatile uint32_t *)0xE000EDFC
static inline uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
void init_dwt()
{
SCB_DEMCR |= 0x01000000;
DWT_CYCCNT = 0;
DWT_CONTROL|= 1; // enable the counter
}
int main(void)
{
init_dwt();
DWT_CYCCNT=0; // сброс счётчика цилов процессора
DoSome();
uint32_t cycles=DWT_CYCCNT; // чтение количества циклов
}
===========================================================
организация задержки
uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000);
while (DWT_Compare(tp));
}
==========================================================
uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000));
while (DWT_Compare(tp));
}
If your Cortex M microcontroller have DWT (Data Watchpoint and Trace) unit, you can use its register to count the number of cycles in which some code is executed. This could be useful for performance measuring. Simple cycle counter on ARM microcontroller having DWT unit could be implemented like this:
#include <stdint.h>
volatile uint32_t count = 0;
// addresses of registers
volatile uint32_t *DWT_CONTROL = (uint32_t *)0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *)0xE000EDFC;
// enable the use DWT
*DEMCR = *DEMCR | 0x01000000;
// Reset cycle counter
*DWT_CYCCNT = 0;
// enable cycle counter
*DWT_CONTROL = *DWT_CONTROL | 1 ;
// some code here
// .....
// number of cycles stored in count variable
count = *DWT_CYCCNT;
The DWT is an optional debug unit that provides watchpoints, data tracing, and system profiling for the processor.A full DWT contains four comparators that you can configure as a
Один из этих регистров – DWT_CYCCNT, расположенный по адресу 0xE0001004, представляет собой счетчик тактов микроконтроллера. Чтобы запустить его на счет, необходимо установить младший бит (CYCCNTENA) регистра DWT_CONTROL.
#define DWT_CYCCNT *(volatile unsigned long *)0xE0001004
#define DWT_CONTROL *(volatile unsigned long *)0xE0001000
#define SCB_DEMCR *(volatile unsigned long *)0xE000EDFC
SCB_DEMCR |= 0x01000000;
DWT_CONTROL|= 1; // enable the counter
DWT_CYCCNT = 0;
for(i=0;i<1000;i++){};
time=DWT_CYCCNT;
=======================================================
#define DWT_CYCCNT *(volatile uint32_t *)0xE0001004
#define DWT_CONTROL *(volatile uint32_t *)0xE0001000
#define SCB_DEMCR *(volatile uint32_t *)0xE000EDFC
static inline uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
void init_dwt()
{
SCB_DEMCR |= 0x01000000;
DWT_CYCCNT = 0;
DWT_CONTROL|= 1; // enable the counter
}
int main(void)
{
init_dwt();
DWT_CYCCNT=0; // сброс счётчика цилов процессора
DoSome();
uint32_t cycles=DWT_CYCCNT; // чтение количества циклов
}
===========================================================
организация задержки
uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000);
while (DWT_Compare(tp));
}
==========================================================
uint32_t DWT_Get(void)
{
return DWT_CYCCNT;
}
__inline
uint8_t DWT_Compare(int32_t tp)
{
return (((int32_t)DWT_Get() - tp) < 0);
}
void DWT_Delay(uint32_t us) // microseconds
{
int32_t tp = DWT_Get() + us * (SystemCoreClock/1000000));
while (DWT_Compare(tp));
}
If your Cortex M microcontroller have DWT (Data Watchpoint and Trace) unit, you can use its register to count the number of cycles in which some code is executed. This could be useful for performance measuring. Simple cycle counter on ARM microcontroller having DWT unit could be implemented like this:
#include <stdint.h>
volatile uint32_t count = 0;
// addresses of registers
volatile uint32_t *DWT_CONTROL = (uint32_t *)0xE0001000;
volatile uint32_t *DWT_CYCCNT = (uint32_t *)0xE0001004;
volatile uint32_t *DEMCR = (uint32_t *)0xE000EDFC;
// enable the use DWT
*DEMCR = *DEMCR | 0x01000000;
// Reset cycle counter
*DWT_CYCCNT = 0;
// enable cycle counter
*DWT_CONTROL = *DWT_CONTROL | 1 ;
// some code here
// .....
// number of cycles stored in count variable
count = *DWT_CYCCNT;
The DWT is an optional debug unit that provides watchpoints, data tracing, and system profiling for the processor.A full DWT contains four comparators that you can configure as a
- hardware watchpoint
- an ETM trigger
- a PC sampler event trigger
- a data address sampler event trigger.
The first comparator, DWT_COMP0, can also compare against the clock cycle counter, CYCCNT. You can also use the second comparator, DWT_COMP1, as a data comparator. A reduced DWT contains one comparator that you can use as a watchpoint or as a trigger. It does not support data matching. The DWT if present contains counters for:
- clock cycles (CYCCNT)
- folded instructions
- Load Store Unit (LSU) operations
- sleep cycles
- CPI, that is all instruction cycles except for the first cycle
- interrupt overhead.
Note
An event is generated each time a counter overflows.
You can configure the DWT to generate PC samples at defined intervals, and to generate interrupt event information.
The DWT provides periodic requests for protocol synchronization to the ITM and the TPIU, if the your implementation includes the Cortex-M3 TPIU.
Lists the DWT registers. Depending on the implementation of your processor, some of these registers might not be present. Any register that is configured as not present reads as zero.
a. Possible reset values are:
0x40000000 if four comparators for watchpoints and triggers are present
0x4F000000 if four comparators for watchpoints only are present
0x10000000 if only one comparator is present
0x1F000000 if one comparator for watchpoints and not triggers is present
0x00000000 if DWT is not present.
DWT registers are described in the ARMv7M Architecture Reference Manual. Peripheral Identification. Component Identification registers are described in the ARM CoreSight Components Technical Reference Manual.
Note
• Cycle matching functionality is only available in comparator 0.
• Data matching functionality is only available in comparator 1.
• Data value is only sampled for accesses that do not produce an MPU or bus fault. The PC is sampled irrespective of any faults. The PC is only sampled for the first address of a burst.
• The FUNCTION field in the DWT_FUNCTION1 register is overridden for comparators given by DATAVADDR0 and DATAVADDR1 if DATAVMATCH is also set in DWT_FUNCTION1. The comparators given by DATAVADDR0 and DATAVADDR1 can then only perform address comparator matches for comparator 1 data matches.
• If the data matching functionality is not included during implementation it is not possible to set DATAVADDR0, DATAVADDR1, or DATAVMATCH in DWT_FUNCTION1. This means that the data matching functionality is not available in the implementation. Test the availability of data matching by writing and reading the DATAVMATCH bit in DWT_FUNCTION1. If this bit cannot be set then data matching is unavailable.
• PC match is not recommended for watchpoints because it stops after the instruction. It mainly guards and triggers the ETM.
вот такая http://portofino1.ru/dying-light-zombi-s-parkurom-ne-zakazyvali/
ОтветитьУдалить