本文博客链接:http://blog.csdn.net/bjr2016,作者:bjr2016,未经允许不得转载。
本节描述如果设置和配置不同CPU的SystemView模块。
SEGGER SystemView几乎支持任何目标CPU,然而,只有CPU支持后台内存访问(ARM cortexm和Renesas RX)时,才支持连续录制。
在其他CPU中,SystemView可以用单次或死后分析模式。请参阅第46页的单次录制。
为了使SystemView正常运行,需要完成一些特定于目标的配置。
下面的一些cpu描述了这个配置。
录制模式 | 是否支持 |
---|---|
连续模式 | 支持 |
单次模式 | 支持 |
死后模式 | 支持 |
在Cortex-M3/Cortex-M4上,时间戳源可以是一个循环计数器,可以保证循环准确的事件记录。
在记录事件时,为了节省带宽,循环计数器可以选择右移,即4位,以使核心速度的时间戳频率除以16。
配置
//
// Use full cycle counter for higher precision
//
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004))
#define SEGGER_SYSVIEW_TIMESTAMP_BITS (32)
//
// Use cycle counter divided by 16 for smaller size / bandwidth
//
#define SEGGER_SYSVIEW_GET_TIMESTAMP() ((*(U32 *)(0xE0001004)) >> 4)
#define SEGGER_SYSVIEW_TIMESTAMP_BITS (28)
当前活动的中断可以直接通过读取Cortex0-M ICSR[8:0]来识别,这是中断控制器状态寄存器(ICSR)中的向量表区域。
配置
//
// Get the interrupt Id by reading the Cortex-M ICSR[8:0]
//
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF)
锁定和解锁可以通过禁止中断来防止传输中的记录被打断。在Cortex-M3/Cortex-M4中,不是所有的中断都需要被禁止,只有那些本身可能产生SystemView事件或者在OS中导致任务切换的中断。
默认情况下,优先级掩码设置为32,已使用一个优先级为32或更低(更高的数值)来禁用所有中断。
确保屏蔽所有可以发送RTT数据的中断,例如生成SystemView事件,或导致任务切换。当在发送RTT数据时,当高优先级中断不能被掩盖时,SEGGER_RTT_MAX_INTERRUPT_PRIORITY需要相应地调整。(高优先级=低优先级)栓塞的默认值:128u
FreeRTOS的缺省配置:configMAX_SYSCALL_INTERRUPT_PRIORITY:(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY < <(8 - configPRIO_BITS))
如有疑问,请禁用所有中断
配置
//
// RTT locking for GCC toolchains in SEGGER_RTT_Conf.h
//
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \
__asm volatile ("mrs %0, basepri \n\t" \
"mov r1, $32 \n\t" \
"msr basepri, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
//
// Define SystemView locking in SEGGER_SYSVIEW_Conf.h
//
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
SEGGER_SYSVIEW_Conf.h
/*********************************************************************
* (c) SEGGER Microcontroller GmbH & Co. KG *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Conf.h
Purpose : SEGGER SysView configuration for Cortex-M3 / Cortex-M4.
*/
#ifndef SEGGER_SYSVIEW_CONF_H
#define SEGGER_SYSVIEW_CONF_H
/*********************************************************************
*
* SysView timestamp configuration
*/
// Cortex-M cycle counter.
#define SEGGER_SYSVIEW_GET_TIMESTAMP() ((*(U32 *)(0xE0001004)))
// Number of valid bits low-order delivered as timestamp.
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
/*********************************************************************
*
* SysView Id configuration
*/
// Default value for the lowest Id reported by the application.
// Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase().
#define SEGGER_SYSVIEW_ID_BASE 0x20000000
// Number of bits to shift the Id to save bandwidth.
// (i.e. 2 when all reported Ids (pointers) are 4 byte aligned)
#define SEGGER_SYSVIEW_ID_SHIFT 0
/*********************************************************************
*
* SysView interrupt configuration
*/
// Get the currently active interrupt Id. (read Cortex-M ICSR[8:0]
= active vector)
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF)
/*********************************************************************
*
* SysView locking
*/
// Lock SysView (nestable)
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
// Unlock SysView (nestable)
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
#endif
/*************************** End of file ****************************/
SEGGER_SYSVIEW_Config_NoOS_CM3.c
/*********************************************************************
* (c) SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Config_NoOS.c
Purpose : Sample setup configuration of SystemView without an OS.
Revision: $Rev: 7745 $
*/
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_Conf.h"
// SystemcoreClock can be used in most CMSIS compatible projects.
// In non-CMSIS projects define SYSVIEW_CPU_FREQ.
extern unsigned int SystemCoreClock;
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
// The application name to be displayed in SystemViewer
#define SYSVIEW_APP_NAME "Demo Application"
// The target device name
#define SYSVIEW_DEVICE_NAME "Cortex-M4"
// Frequency of the timestamp. Must match SEGGER_SYSVIEW_Conf.h
#define SYSVIEW_TIMESTAMP_FREQ (SystemCoreClock)
// System Frequency. SystemcoreClock is used in most CMSIS compatible projects.
#define SYSVIEW_CPU_FREQ (SystemCoreClock)
// The lowest RAM address used for IDs (pointers)
#define SYSVIEW_RAM_BASE (0x10000000)
// Define as
1 if the Cortex-M cycle counter is used as SystemView timestamp. Must match SEGGER_SYSVIEW_Conf.h
#ifndef USE_CYCCNT_TIMESTAMP
#define USE_CYCCNT_TIMESTAMP 1
#endif
// Define as
1 if the Cortex-M cycle counter is used and there might be no debugger attached while re
#ifndef ENABLE_DWT_CYCCNT
#define ENABLE_DWT_CYCCNT (USE_CYCCNT_TIMESTAMP & SEGGER_SYSVIEW_POST_MORTEM_MODE)
#endif
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
#define DEMCR (*(volatile unsigned long*) (0xE000EDFCuL))
// Debug Exception and Monitor Control Register
#define TRACEENA_BIT (1uL << 24)
// Trace enable bit
#define DWT_CTRL (*(volatile unsigned long*) (0xE0001000uL))
// DWT Control Register
#define NOCYCCNT_BIT (1uL << 25)
// Cycle counter support bit
#define CYCCNTENA_BIT (1uL << 0)
// Cycle counter enable bit
/*********************************************************************
*
* _cbSendSystemDesc()
*
* Function description
* Sends SystemView description strings.
*/
static void _cbSendSystemDesc(void) {
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME);
SEGGER_SYSVIEW_SendSysDesc("I#15=SysTick");
}
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
void SEGGER_SYSVIEW_Conf(void) {
#if USE_CYCCNT_TIMESTAMP
#if ENABLE_DWT_CYCCNT
//
// If no debugger is connected, the DWT must be enabled by the application
//
if ((DEMCR & TRACEENA_BIT) == 0) {
DEMCR |= TRACEENA_BIT;
}
#endif
//
// The cycle counter must be activated in order
// to use time related functions.
//
if ((DWT_CTRL & NOCYCCNT_BIT) == 0) { // Cycle counter supported?
if ((DWT_CTRL & CYCCNTENA_BIT) == 0) { // Cycle counter not enabled?
DWT_CTRL |= CYCCNTENA_BIT; // Enable Cycle counter
}
}
#endif
SEGGER_SYSVIEW_Init(SYSVIEW_TIMESTAMP_FREQ,SYSVIEW_CPU_FREQ,0, _cbSendSystemDesc);
SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
}
/*************************** End of file ****************************/
与Cortex-M4相同的特性/设置等。要了解更多信息,请参阅第70页的Cortex-M3 / Cortex-M4。
缓存Cache
当将RTT缓冲区设置为可缓存(cacheable)的SystemView时,通过J-Link和RTT进行连续记录模式的性能略低(性能下降了小于1%)。这是因为J-Link需要在访问RTT缓冲区时执行缓存维护操作。
录制模式 | 是否支持 |
---|---|
连续模式 | 支持 |
单次模式 | 支持 |
死后分析 | 支持 |
Cortex-M0、Cortex-M0 +和Cortex-M1没有循环计数寄存器。事件时间戳必须由应用程序时钟源(例如系统定时器,SysTick)提供。可以使用SEGGER_SYSVIEW_X_GetTimestamp()来实现该功能。
当应用程序使用SysTick中断时,如RTOS,SysTick处理程序应该增加SEGGER_SYSVIEW_TickCnt,否则必须将SysTick处理程序添加到应用程序并作相应地配置。
配置
//
// SEGGER_SYSVIEW_TickCnt has to be defined in the module which
// handles the SysTick and must be incremented in the SysTick
// handler before any SYSVIEW event is generated.
//
// Example in embOS RTOSInit.c:
//
// unsigned int SEGGER_SYSVIEW_TickCnt; // <<-- Define SEGGER_SYSVIEW_TickCnt.
// void SysTick_Handler(void) {
// #if OS_PROFILE
// SEGGER_SYSVIEW_TickCnt++; // <<-- Increment SEGGER_SYSVIEW_TickCnt asap.
// #endif
// OS_EnterNestableInterrupt();
// OS_TICK_Handle();
// OS_LeaveNestableInterrupt();
// }
//
extern unsigned int SEGGER_SYSVIEW_TickCnt;
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
#define SCB_ICSR
(*(volatile U32*) (0xE000ED04uL)) // Interrupt Control State Register
#define SCB_ICSR_PENDSTSET_MASK (1UL << 26) // SysTick pending bit
#define SYST_RVR
(*(volatile U32*) (0xE000E014uL)) // SysTick Reload Value Register
#define SYST_CVR
(*(volatile U32*) (0xE000E018uL)) // SysTick Current Value Register
/*********************************************************************
*
* SEGGER_SYSVIEW_X_GetTimestamp()
*
* Function description
* Returns the current timestamp in ticks using the system tick
* count and the SysTick counter.
* All parameters of the SysTick have to be known and are set via
* configuration defines on top of the file.
*
* Return value
* The current timestamp.
*
* * Additional information
* SEGGER_SYSVIEW_X_GetTimestamp is always called when interrupts are
* disabled. Therefore locking here is not required.
*/
U32 SEGGER_SYSVIEW_X_GetTimestamp (void) {
U32 TickCount;
U32 Cycles;
U32 CyclesPerTick;
//
// Get the cycles of the current system tick.
// SysTick is down-counting, subtract the current value from the number of cycles per
//
CyclesPerTick = SYST_RVR + 1;
Cycles = (CyclesPerTick - SYST_CVR);
//
// Get the system tick count.
//
TickCount = SEGGER_SYSVIEW_TickCnt;
//
// If a SysTick interrupt is pending, re-read timer and adjust result
//
if ((SCB_ICSR & SCB_ICSR_PENDSTSET_MASK) != 0) {
Cycles = (CyclesPerTick - SYST_CVR);
TickCount++;
}
Cycles += TickCount * CyclesPerTick;
return Cycles;
}
当前活动的中断可以直接通过读取Cortex-M的ICSR[5..0]寄存器获取,ICSR[5..0]是中断控制状态寄存器ICSR的活动向量表区域。
配置
//
// Get the interrupt Id by reading the Cortex-M ICSR[5:0]
//
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F)
锁定和接收SystemView和RTT是相同的。
配置
//
// RTT locking for GCC toolchains in SEGGER_RTT_Conf.h
//
#define SEGGER_RTT_LOCK () { \
unsigned int LockState; \
__asm volatile ("mrs %0, primask \n\t" \
"mov r1, $1 \n\t" \
"msr primask, r1 \n\t" \
: "=r" (LockState) \
: \
: "r1" \
);
#define SEGGER_RTT_UNLOCK () __asm volatile ("msr primask, %0 \n\t" \
: \
: "r" (LockState) \
: \
); \
}
//
// Define SystemView locking in SEGGER_SYSVIEW_Conf.h
//
#define SEGGER_SYSVIEW_LOCK () SEGGER_RTT_LOCK ()
#define SEGGER_SYSVIEW_UNLOCK () SEGGER_RTT_UNLOCK ()
SEGGER_SYSVIEW_Conf.h
/*********************************************************************
* (c) SEGGER Microcontroller GmbH & Co. KG *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Conf.h
Purpose : SEGGER SysView configuration for Cortex-M0, Cortex-M0+,
and Cortex-M1
*/
#ifndef SEGGER_SYSVIEW_CONF_H
#define SEGGER_SYSVIEW_CONF_H
/*********************************************************************
*
* SysView timestamp configuration
*/
// Retrieve a system timestamp via user-defined function
#define SEGGER_SYSVIEW_GET_TIMESTAMP () SEGGER_SYSVIEW_X_GetTimestamp ()
// number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
/*********************************************************************
*
* SysView Id configuration
*/
// Default value for the lowest Id reported by the application.
// Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase().
#define SEGGER_SYSVIEW_ID_BASE 0x20000000
// Number of bits to shift the Id to save bandwidth.
// (i.e. 2 when all reported Ids (pointers) are 4 byte aligned)
#define SEGGER_SYSVIEW_ID_SHIFT 0
/*********************************************************************
*
* SysView interrupt configuration
*/
// Get the currently active interrupt Id. (read Cortex-M ICSR[8:0]
= active vector)
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID () ((*(U32 *)(0xE000ED04)) & 0x3F)
/*********************************************************************
*
* SysView locking
*/
// Lock SysView (nestable)
#define SEGGER_SYSVIEW_LOCK () SEGGER_RTT_LOCK ()
// Unlock SysView (nestable)
#define SEGGER_SYSVIEW_UNLOCK () SEGGER_RTT_UNLOCK ()
#endif
/*************************** End of file ****************************/
SEGGER_SYSVIEW_Config_embOS_CM0.c
/*********************************************************************
* (c) SEGGER Microcontroller GmbH & Co. KG *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
File : SEGGER_SYSVIEW_Config_embOS_CM0.c
Purpose : Sample setup configuration of SystemView with embOS
on Cortex-M0/Cortex-M0+/Cortex-M1 systems which do not
have a cycle counter.
Revision: $Rev: 7750 $
Additional information:
SEGGER_SYSVIEW_TickCnt has to be defined in the module which handles
the SysTick and must be incremented in the SysTick_Handler.
This configuration can be adopted for any other OS and device.
*/
#include "RTOS.h"
#include "SEGGER_SYSVIEW.h"
#include "SEGGER_SYSVIEW_embOS.h"
//
// SystemcoreClock can be used in most CMSIS compatible projects.
// In non-CMSIS projects define SYSVIEW_CPU_FREQ directly.
//
extern unsigned int SystemCoreClock;
//
// SEGGER_SYSVIEW_TickCnt has to be defined in the module which
// handles the SysTick and must be incremented in the SysTick
// handler before any SYSVIEW event is generated.
//
// Example in embOS RTOSInit.c:
//
// unsigned int SEGGER_SYSVIEW_TickCnt; // <<-- Define SEGGER_SYSVIEW_TickCnt.
// void SysTick_Handler(void) {
// #if OS_PROFILE
// SEGGER_SYSVIEW_TickCnt++; //
<<-- Increment SEGGER_SYSVIEW_TickCnt before calling OS_EnterNestableInterrupt.
// #endif
// OS_EnterNestableInterrupt();
// OS_TICK_Handle();
// OS_LeaveNestableInterrupt();
// }
//
extern unsigned int SEGGER_SYSVIEW_TickCnt;
/*********************************************************************
*
* Defines, fixed
*
**********************************************************************
*/
#define SCB_ICSR
(*(volatile U32*) (0xE000ED04uL)) // Interrupt Control State Register
#define SCB_ICSR_PENDSTSET_MASK (1UL << 26) // SysTick pending bit
#define SYST_RVR
(*(volatile U32*) (0xE000E014uL)) // SysTick Reload Value Register
#define SYST_CVR
(*(volatile U32*) (0xE000E018uL)) // SysTick Current Value Register
/*********************************************************************
*
* Defines, configurable
*
**********************************************************************
*/
// The application name to be displayed in SystemViewer
#ifndef SYSVIEW_APP_NAME
#define SYSVIEW_APP_NAME "Demo Application"
#endif
// The target device name
#ifndef SYSVIEW_DEVICE_NAME
#define SYSVIEW_DEVICE_NAME "Cortex-M0"
#endif
// Frequency of the timestamp. Must match SEGGER_SYSVIEW_Conf.h
#ifndef SYSVIEW_TIMESTAMP_FREQ
#define SYSVIEW_TIMESTAMP_FREQ (SystemCoreClock)
#endif
// System Frequency. SystemcoreClock is used in most CMSIS compatible projects.
#ifndef SYSVIEW_CPU_FREQ
#define SYSVIEW_CPU_FREQ (SystemCoreClock)
#endif
// The lowest RAM address used for IDs (pointers)
#ifndef SYSVIEW_RAM_BASE
#define SYSVIEW_RAM_BASE (0x20000000)
#endif
#ifndef SYSVIEW_SYSDESC0
#define SYSVIEW_SYSDESC0 "I#15=SysTick"
#endif
//#ifndef SYSVIEW_SYSDESC1
// #define SYSVIEW_SYSDESC1 ""
//#endif
//#ifndef SYSVIEW_SYSDESC2
// #define SYSVIEW_SYSDESC2 ""
//#endif
/*********************************************************************
*
* _cbSendSystemDesc()
*
* Function description
* Sends SystemView description strings.
*/
static void _cbSendSystemDesc (void) {
SEGGER_SYSVIEW_SendSysDesc ("N=" SYSVIEW_APP_NAME ",O=embOS,D=" SYSVIEW_DEVICE_NAME);
#ifdef SYSVIEW_SYSDESC0
SEGGER_SYSVIEW_SendSysDesc (SYSVIEW_SYSDESC0);
#endif
#ifdef SYSVIEW_SYSDESC1
SEGGER_SYSVIEW_SendSysDesc (SYSVIEW_SYSDESC1);
#endif
#ifdef SYSVIEW_SYSDESC2
SEGGER_SYSVIEW_SendSysDesc (SYSVIEW_SYSDESC2);
#endif
}
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
void SEGGER_SYSVIEW_Conf (void) {
SEGGER_SYSVIEW_Init (SYSVIEW_TIMESTAMP_FREQ, SYSVIEW_CPU_FREQ,
&SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
SEGGER_SYSVIEW_SetRAMBase (SYSVIEW_RAM_BASE);
OS_SetTraceAPI (&embOS_TraceAPI_SYSVIEW); // Configure embOS to use SYSVIEW.
}
/*********************************************************************
*
* SEGGER_SYSVIEW_X_GetTimestamp()
*
* Function description
* Returns the current timestamp in ticks using the system tick
* count and the SysTick counter.
* All parameters of the SysTick have to be known and are set via
* configuration defines on top of the file.
*
* Return value
* The current timestamp.
*
* Additional information
* SEGGER_SYSVIEW_X_GetTimestamp is always called when interrupts are
* disabled. Therefore locking here is not required.
*/
U32 SEGGER_SYSVIEW_X_GetTimestamp (void) {
U32 TickCount;
U32 Cycles;
U32 CyclesPerTick;
//
// Get the cycles of the current system tick.
// SysTick is down-counting, subtract the current value from the number of cycles per
//
CyclesPerTick = SYST_RVR + 1;
Cycles = (CyclesPerTick - SYST_CVR);
//
// Get the system tick count.
//
TickCount = SEGGER_SYSVIEW_TickCnt;
//
// If a SysTick interrupt is pending, re-read timer and adjust result
//
if ((SCB_ICSR & SCB_ICSR_PENDSTSET_MASK) != 0) {
Cycles = (CyclesPerTick - SYST_CVR);
TickCount++;
}
Cycles += TickCount * CyclesPerTick;
return Cycles;
}
/*************************** End of file ****************************/
录制模式 | 是否支持 |
---|---|
连续模式 | 支持/否 |
单次模式 | 支持 |
死后分析 | 支持 |
略
录制模式 | 是否支持 |
---|---|
连续模式 | 支持 |
单次模式 | 支持 |
死后分析 | 支持 |
略
录制模式 | 是否支持 |
---|---|
连续模式 | 否 |
单次模式 | 支持 |
死后分析 | 支持 |
在没有被sections覆盖的cpu上,SystemView可以使用在singleshot模式中。
要正确运行SystemView,必须配置与之前那些CPU同样的项目: