章节6 目标板配置 - Segger SystemView使用手册(译文)

本文博客链接:http://blog.csdn.net/bjr2016,作者:bjr2016,未经允许不得转载。

章节6 目标板配置


为了匹配目标设备和应用程序,可以对SEGGER SystemView进行配置。默认的编译配置标志都已经预先配置了一个有效值,用来匹配大多数系统的需求。通常不需要修改。
可以通过更改编译Flags来修改SystemView的默认配置,这些Flags可以添加在SEGGER_SYSVIEW_Conf.h文件中。

6.1 系统特定配置

为了匹配目标系统,需要进行以下编译配置。SEGGER_SYSVIEW_Conf.h中的示例配置定义了配置能够匹配大多数系统(例如,带有Embedded Studio、GCC、IAR或Keil ARM的Cortex-M芯片设备)。如果使用的系统不在示例配置中,则必须进行相应地调整。

有关系统特定配置的详细描述,请参阅第69页的支持的cpu。

6.1.1 SEGGER_SYSVIEW_GET_TIMESTAMP()

获取用于SystemView事件的系统时间戳的函数宏定义。
在Cortex-M3/M4芯片中,可以将Cortex-M核的循环计数器用于系统时间戳。
在Cortex-M3/M4中:地址为 (U32)(0xE0001004))

在其他大多数芯片中,系统时间戳一般用定时器产生。在默认配置下,系统时间戳可以使用用户提供的函数SEGGER_SYSVIEW_X_GetTimestamp()来获取。
其他核心中:地址为SEGGER_SYSVIEW_X_GetTimestamp()

参考SEGGER_SYSVIEW_Config_embOS_CM0.c 或者 SEGGER_SYSVIEW_Config_NoOS_RX.c 中的例子。

注意

在SEGGER_SYSVIEW_Init的参数中,必须提供系统的时间戳频率。

6.1.2 SEGGER_SYSVIEW_TIMESTAMP_BITS

作为系统时间戳的时钟源的低位有效bit位数。
如果使用未修改的时钟源作为系统时间戳,有效位的数量是时钟源的位宽(即32或16位)。
默认值:32(使用32位时钟源)

节省带宽的例子
由于SystemView包使用了可变长度的编码,所以较少时间戳位数可以节省缓冲空间和带宽。

就像在Cortex-M3/4芯片上的Cortex-M的循环计数器,一个32位时钟源可以移动4位,使得只有28位有效的时间戳位,而在SEGGER_SYSVIEW_Init使用的时间戳频率,是核心时钟频率除以16。

#define SEGGER_SYSVIEW_GET_TIMESTAMP() ((*(U32 *)(0xE0001004)) >> 4)
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 28.

6.1.3 SEGGER_SYSVIEW_GET_INTERRUPT_ID

用于定义获取当前活动中断ID的宏定义函数。
在Cortex-M芯片中,可以从ICSR中读到激活的向量表。
在Cortex-M3/4芯片上的默认值: ((*(U32 *)(0xE000ED04)) & 0x1FF)
在Cortex-M0/1芯片上的默认值: ((*(U32 *)(0xE000ED04)) & 0x3F)

在其他设备上,活动中断可以直接从中断控制器中获取,可以保存在通用中断处理函数中的变量中,或者必须在每个中断函数中手动指定。
默认情况下,可以使用用户提供的函数SEGGER_SYSVIEW_X_GetInterruptId()来指定,或者直接替换宏定义。

6.1.4 SEGGER_SYSVIEW_LOCK()

用于锁定SystemView,防止SystemView传输被打断。比如防止中断。
SEGGER_SYSVIEW_LOCK()必须保存前一个锁状态,并在SEGGER_SYSVIEW_UNLOCK()中恢复锁状态。

记录一个SystemView事件不能被记录另一个事件打断。因此,所有被SystemView记录的中断中(调用SEGGER_SYSVIEW_RecordEnterISR / SEGGER_SYSVIEW_RecordExitISR),调用一个instrumented的函数(比如一个OS API函数),会立即引起一个上下文切换,或者可能创建其他的SystemView事件,因此这种操作是必须禁止的。
SEGGER_SYSVIEW_LOCK()可以使用与SEGGER_RTT_LOCK()相同的锁定机制。
默认值:SEGGER_RTT_LOCK()
SEGGER_RTT_LOCK()在SEGGER_RTT_Conf.h中为大多数系统(也就是带有嵌入式Studio、GCC、IAR或Keil ARM和RX设备的cortexm设备)定义。如果宏没有定义或空,则必须提供它以匹配目标系统。

6.1.5 SEGGER_SYSVIEW_UNLOCK()

用于解锁被中断的SystemView传输,会恢复前一个中断状态。

SEGGER_SYSVIEW_UNLOCK()函数可以和SEGGER_RTT_UNLOCK一样的用法。
默认值:SEGGER_RTT_UNLOCK()

SEGGER_RTT_UNLOCK() 在SEGGER_RTT_Conf.h中已经为适配大多数系统作了定义(带有嵌入式Studio、GCC、IAR或Keil ARM和使用IAR的RX芯片的Cortex-M核芯片)。如果没有定义这个宏或宏定义为空,则必须提供适合目标系统的定义。

6.2 通用配置

下面的编译标志主要用于优化或者更改SystemView事件录制的方式。
默认的编译配置标志已经预先配置了匹配大多数系统的需求的有效值,通常不需要修改。

6.2.1 SEGGER_SYSVIEW_RTT_BUFFER_SIZE

SystemView用于记录缓冲区的字节数。
在大多数情况下,对于连续记录,1024字节的缓冲区就足够了。根据目标接口速度、目标速度和系统负载,缓冲区大小可能要增加到4096字节。
对于单次记录,缓冲区大小决定了可以记录的事件数。根据负载的不同,系统可能会产生10到50个kByte / s。推荐一个至少8 kByte的缓冲区,到整个空闲的RAM空间。缓冲区也可以在外部RAM中。
对于死后分析,缓冲区大小决定了可供分析的事件的最大数目。推荐的缓冲区大小和单次记录一样。
默认值:1024字节

SEGGER_SYSVIEW_RTT_CHANNEL

RTT通道是用于SystemView事件记录和通信。0表示自动选择

注意:

在SEGGER_RTT_Conf.h中定义的SEGGER_RTT_MAX_NUM_UP_BUFFERS的值不能大于SEGGER_SYSVIEW_RTT_CHANNEL。

默认值:0

6.2.3 SEGGER_SYSVIEW_USE_STATIC_BUFFER

如果这个值设为1,SystemView将使用静态缓冲区创建SystemView事件。这样通常能够节省空间,因为只有一个缓冲区是必需的,而任务栈可以尽可能小。当使用静态缓冲区时,SystemView锁调用之间执行的关键代码需要稍微长一点时间。
如果设为0,SystemView事件是创建在堆栈上 。确保所有的任务栈,以及用于中断的C堆栈都足够大,可以容纳最大的SystemView事件(~ 228字节)。只有在将堆栈缓冲区传输到RTT缓冲区时,才可以使用SystemView锁。

默认值:1

6.2.4 SEGGER_SYSVIEW_POST_MORTEM_MODE

设为1,可以使能死后分析模式。
在事后分析模式中,系统使用一个循环缓冲区,这样可以让所有事件保持最新的记录,而不是缓冲区满时就删除事件。(译者注:存在疑问,与之前的意思表达冲突

注意

当使用J-Link调试器主动读取RTT数据时,不要使用事后分析模式。
默认值:0

6.2.5 SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT

配置在死后模式中发送同步和系统信息事件的频率。确保在SystemView缓冲区中至少有一个同步。
推荐的同步频率: Buffer Size / 16
默认值:8 = 每256个数据包同步一次

6.2.6 SEGGER_SYSVIEW_ID_BASE

从SystemView包中记录的ID中减去的值。
ID是任务ID,定时器ID或者资源ID,它们通常指向RAM中的结构。在操作系统和中间件API事件中发送的参数也可以通过instrumentation来编码为id。

注意

如果操作系统没有指向任务ID,定时器ID或者资源ID的话,SEGGER_SYSVIEW_ID_BASE必须设为0
当SystemView包使用一个可变长度的指针编码时,正确地重新建立地址可以节省缓冲空间和带宽。
定义系统中使用的最低内存地址。
应用程序通过SEGGER_SYSVIEW_SetRAMBase可以覆盖这个值。
在不确定的情况下,将SEGGER_SYSVIEW_ID_BASE设为0
默认值:0x1000 0000

6.2.7 SEGGER_SYSVIEW_ID_SHIFT

在SystemView包中记录的ID偏移的位数。

注意

如果操作系统没有指向任务ID,定时器ID或者资源ID的话,SEGGER_SYSVIEW_ID_SHIFT必须设为0
当SystemView包使用一个可变长度的指针编码时,正确地偏移地址可以节省缓冲空间和带宽。
对于32位处理器上的大多数应用程序,SystemView事件中记录的所有id都是真正的指针,并且是4的倍数,因此最低的2位可以被安全地忽略。
在不确定的情况下,把SEGGER_SYSVIEW_ID_SHIFT设为0
默认值:2

SEGGER_SYSVIEW_MAX_STRING_LEN

SystemView事件记录的最大字符串长度。
字符串被用于SystemView printf样式的用户函数,以及SEGGER_SYSVIEW_SendSysDesc和SEGGER_SYSVIEW_RecordModuleDescription。确保SEGGER_SYSVIEW_MAX_STRING_LEN匹配这些函数中使用的字符串长度。
最大支持的字符串长度为255字节
默认值:128

6.2.9 SEGGER_SYSVIEW_MAX_ARGUMENTS

使用SEGGER_SYSVIEW_PrintfHost、SEGGER_SYSVIEW_PrintfHostEx、SEGGER_SYSVIEW_WarnfHost SEGGER_SYSVIEW_ErrorfHost时发送参数的最大数量。
如果在应用程序中没有使用这些函数,则SEGGER_SYSVIEW_MAX_ARGUMENTS可以设置为0,使静态缓冲区最小。
默认值:16

6.2.10 SEGGER_SYSVIEW_BUFFER_SECTION

可以将SystemView RTT缓冲区放入专用的数据段,而不是默认的数据段。这允许将缓冲区放入外部内存或在指定的地址。
当定义SEGGER_SYSVIEW_BUFFER_SECTION时,该部分必须在链接器脚本中定义。
默认:SEGGER_RTT_SECTION或未定义
在Embedded Studio中的例子

//
// SEGGER_SYSVIEW_Conf.h
//
#define SEGGER_SYSVIEW_BUFFER_SECTION "SYSTEMVIEW_RAM"
//
// flash_placement.xml
//
"ExtRAM">
"No" name="SYSTEMVIEW_RAM" start="0x40000000" />

6.2.11 RTT配置

下面的编译标志是用于优化或者修改RTT模块的。
大多数情况下不需要修改这些标志。

6.2.11.1 BUFFER_SIZE_UP

用于RTT终端输出通道的字节数
RTT可用于printf终端输出,无需修改。BUFFER_SIZE_UP定义了可以缓冲多少字节。
如果不使用RTT终端输出,则将BUFFER_SIZE_UP定义为最小值4。
默认值:1024 字节

6.2.11.2 BUFFER_SIZE_DOWN

用于RTT终端输入通道的字节数。
RTT可以在终端输入通道接收来自主机的输入。BUFFER_SIZE_DOWN定义了从主机发送一次可以缓冲多少字节。
如果不使用RTT终端输入,则将BUFFER_SIZE_DOWN定义为它的最小值为4。
默认值:16 字节

6.2.11.3 SEGGER_RTT_MAX_NUM_UP_BUFFERS

最大RTT输出缓冲区的数量。缓冲区0总是用于RTT终端输出,因此要使用SystemView,SEGGER_RTT_MAX_NUM_UP_BUFFERS必须至少有2个。
默认值:2

6.2.11.4 SEGGER_RTT_MAX_NUM_DOWN_BUFFERS

最大RTT输入缓冲区的数量。缓冲区0总是用于RTT终端输入,因此要使用SystemView,SEGGER_RTT_MAX_NUM_UP_BUFFERS必须至少有2个。(译者注:此处是否应该是DOWN_BUFFERS至少有2个
默认值:2

6.2.11.5 SEGGER_RTT_MODE_DEFAULT

预初始化RTT终端通道的模式(缓冲区0)
默认值:SEGGER_RTT_MODE_NO_BLOCK_SKIP

6.2.11.6 SEGGER_RTT_PRINTF_BUFFER_SIZE

通过RTT printf发送字符块时的缓冲区大小。如果不用SEGGER_RTT_Printf时,可以定义为0。
默认值:64

6.2.11.7 SEGGER_RTT_SECTION

RTT控制块可以被放置到专门的部分,而不是默认的数据部分。这允许将其放置在已知地址,以便使用J-Link能够自动检测或容易指定搜索范围。
如果定义了SEGGER_RTT_SECTION,应用程序必须确保该部分是有效的,要么是在启动代码中初始化为0,要么在应用程序开始时显式地调用SEGGER_RTT_Init()。SEGGER_RTT_Init()是由SEGGER_SYSVIEW_Init()隐式调用的。
默认值:未定义

6.2.11.8 SEGGER_RTT_BUFFER_SECTION

RTT终端缓冲区放置的位置,最好放置在专门的部分,而不是放到默认数据段。允许放到外部RAM或者一个给定的地址。
默认值:SEGGER_RTT_SECTION 或者不定义

6.3 优化SystemView

为了从目标系统获得最精确的运行时信息,记录工具代码需要快速、最少侵入性、小且高效。SystemView代码被编写为高效且不具有干扰性。SystemView的速度和大小是目标和编译器配置的问题。下面的部分描述如何优化SystemView。

6.3.1 编译器优化

SystemView目标系统模块的编译器优化应该始终打开(即使是在调试版本中),用于生成快速的记录路径,从而减少开销,并减少对应用程序的干扰。
是否支持速度或大小优化的配置依赖于编译器的。在某些情况下,平衡的配置可能比只优化速度的配置更快。

6.3.2 录制优化

SystemView使用一个可变长度的编码来存储和传输事件,这使得在调试接口上节省了缓冲空间和带宽。
一些事件参数的大小可以通过编译时配置进行优化。
缩小id位数
ID是指向RAM中的符号的指针,例如任务ID是指向任务控制块的指针。为了尽量减少记录的id长度,它们可以缩小。
可以从指针中减去SEGGER_SYSVIEW_ID_BASE从而得到ID。它可以从指针中减去基RAM地址,而指针仍然是唯一的,但是变成了更小的ID。例如,如果RAM范围是0x20000000到0x20001000,那么建议将SEGGER_SYSVIEW_ID_BASE定义为0x20000000,它将使得指针0x20000100变为ID 0x100,这样只需要两个而不是四个位来存储它。
SEGGER_SYSVIEW_ID_SHIFT是一个指针通过右移多少位数得到ID。如果所有的记录指针都是4字节对齐,那么SEGGER_SYSVIEW_ID_SHIFT可以被定义为2。然后,一个指针0x20000100右移2位将会有ID 0x8000040,或者与之前的SEGGER_SYSVIEW_ID_BASE的减法一样,这个ID为0x20000000,ID为0x40,只需要记录一个字节。

时间戳的来源

SystemView中的事件时间戳被记录为时间戳与前一个事件的差值。这节省了缓冲空间。
当建议使用时间戳源使用最高时间分辨率的CPU时钟频率时,较低的时间戳频率可能会节省额外的缓冲空间,因为时间戳增量较低(时间间隔会比较低,导致需要保存的时间位数变短)。
使用CPU时钟频率为160 MHz时,时间戳会右移到4位,导致一个时间戳 10 MHz的频率(100 ns决议),少和4位编码。
当时间戳大小不再是32 -比特时,例如它在0xFFFFFFFF之前结束,SEGGER_SYSVIEW_TIMESTAMP_BITS必须被定义为时间戳大小,例如为28时将一个32位的时间戳右移4位。

6.3.3 缓冲区配置

SystemView和RTT的记录和通信缓冲区大小可以设置在目标配置中。
在大多数情况下,连续记录1-4k字节用于连续记录是足够的,另外甚至允许SystemView使用一个小的内部RAM。
对于单次和死后模式,建议采用更大的缓冲区。在这种情况下,SEGGER_SYSVIEW_RTT_BUFFER_SIZE可以设置为更大的值。为了将SystemView记录缓冲区放入外部RAM中,可以定义SEGGER_SYSVIEW_BUFFER_SECTION,并相应地修改链接器脚本。
如果只使用SystemView,且不使用RTT的终端输出,则在SEGGER_RTT_Conf.h中使用的BUFFER_SIZE_UP。可以设置为较小的值以节省内存。

你可能感兴趣的:(segger)