
本帖最后由 sjtu_zhang 于 2018-6-7 14:04 编辑 前几天浏览网页看到有关于SystemView的介绍,觉得很有用,花了点时间研究了一下,效果还不错。在论坛里搜索了一下已经有朋友在FreeRTOS用上了,我这里是用在UCOS上的,分享给大家。 首先什么是SystemView? “SystemView 是一个用于虚拟分析嵌入式系统的工具包。SystemView 可以完整的深入观察一个应用程序的运行时行为,这远远超出一个调试器所能提供的。这在开发和处理具有多个线程和事件的复杂系统时尤其有效。” SystemView的原理简单来讲是这样的:首先上位机PC端有一个处理程序,下位机ARM上需增加部分代码,用于记录嵌入式系统的一些数据,通过连接的仿真器接口将数据传输到上位机,然后PC端的处理程序处理这些数据,由于数据传输使用的是SEGGER J-link的实时传输技术(RTT),所以SystemView可以实时分析和展示数据。分析的内容包括中断、任务、软件定时器执行的时间,切换的时间,以及发生的事件等,这些分析都是实时的,丝毫不影响下位机的运行。这样就可以验证我们设计的整个嵌入式系统是否按照我们的预期在工作,比如任务的切换逻辑,中断的触发等。它可以应用于带有RTOS的系统,也支持裸机,对于下位机资源的消耗量也是比较少的。 使用方法: 由于我自己的项目是基于UCOS,所以这里我仅给出UCOS下的实现方法。Micrium官方也有介绍以及使用指导,地址:http://doc.micrium.com/display/osiiidoc/Including+SystemView,可以参照这个网页的介绍,如果不想阅读英文文档的朋友,那就按照我写的步骤来吧。 准备工作:UCOSIII(内核版本3.06.00以上,原因是从这个版本开始UCOSIII内部就集成了SystemView的功能,移植起来很方便)。PC端SystemView安装包(当前版本2.52),下位机SystemView源码包(当前版本2.52),下载地址:http://www.segger.com/products/development-tools/systemview/。 说明:Micirum官方还没有放出UCOSIII内核版本3.06.00以上的源码包,我是从Micirum网站上提供的移植好的其他开发板工程里面提取的,比如这个:http://www.micrium.com/download/stm32f746g-disco_flash-drive/,内核是3.06.00,我自己用的是3.06.02的内核。另外官方并没有给出3.06.00版本的UCOSIII对应Keil的port移植文件。这个就用以前版本内核的移植文件就好了。 步骤: (1)将SystemView源码包拷贝至项目工程中,添加对应操作系统的文件(SEGGER_SYSVIEW_Config_uCOSIII.c 和SEGGER_SYSVIEW_uCOSIII.c )以及SEGGER_RTT.c和SEGGER_SYSVIEW.c。 (2)配置os_cfg.h
注:打开API_ENTER和API_EXIT之后会增加触发的SystemView事件数量,这可能导致SystemView出现overflow的问题。如果这样的话disable这两个宏定义。 (3)配置os_cfg_trace.h
(4)配置SEGGER_RTT_Conf.h
(5)配置SEGGER_SYSVIEW_Conf.h
(6)修改SEGGER_SYSVIEW_Config_uCOSIII.c 在这个文件中有两个宏函数: SYSVIEW_TIMESTAMP_FREQ SYSVIEW_CPU_FREQ 原始文件两个函数都定义为BSP_ClkFreqGet(BSP_CLK_ID_SYSCLK),这个需要根据使用的具体ARM型号实现,这里给出STM32F429的实现函数: 4 A5 u' e9 }. \' t2 iHAL_RCC_GetSysClockFreq(); (这个是基于ST的HAL库函数)# v6 D" ^5 R& i1 e, o9 e 另外定义:
这个是F429的RAM起始地址。 Tips:如果希望在SystemView中显示具体的中断名称,而不是单调的中断号,可以修改 _cbSendSystemDeesc()函数中对于中断号的描述,比如这样:
(7)初始化SystemView 在应用程序中增加os_trace.h头文件引用以及调用OS_TRACE_INIT()初始化函数。 (8)修改应用程序代码 在每个中断服务函数的开头和结尾分别加入如下代码: 开头:
结尾:
添加了如上所示的代码之后,操作系统的内核就可以记录中断的信息了。 (9)关于UCOS 以上八个步骤完成后,就可以在SystemView中观察到中断的信息,但是看不到我们创建的任务的信息,原因是UCOS的移植port文件,这里需要修改os_cpu_c.c这个文件,注释掉以下代码:
添加:
到这里实际上细心的朋友应该看出来了,UCOSIII之前的版本应该也是支持SystemView的,具体怎么做留给有兴趣的朋友尝试吧。 以上就是详细的使用步骤了,贴一张我自己的结果: 最后说明一下SystemView的免费版本是有记录上限的为100万个,大约可以记录十几秒的信息,一般的调试足够了,pro版本没有限制,可以一直记录,这对于那些偶现的Bug查错很有帮助,当然价钱也很棒。 最后:转载请注明出处。 |
目前用着没问题。啥也不动可以一直抓下去。只要按下触摸屏的任意位置,就会出现一个小框1 }5 Y4 A! u5 a8 @8 t
Invalid packet received. Rcording stopped. google了下发现http://forum.segger.com/index.ph ... OS-start-recording/% ?! Y1 k* [8 u5 }
这个问题是
Problem has been solved via mail. For completeness:/ _4 b( S" q! M. j. m1 G5 b2 T
The invalid packets where caused by a locking problem.
In the SEGGER_SYSVIEW_LOCK() / SEGGER_RTT_LOCK() all interrupts which could create SystemView events should be disabled (masked).
; B5 j) @: v# ^0 R2 K. A
For FreeRTOS and Cortex-M3/4 use either following macro or redirect lock and unlock to the FreeRTOS functions.
8 x% P7 R% ^+ q9 }* ?& L! e
但是这个是针对freertos的。而且2.52a版本里面的freertos里面已经fix了这个bug。
不知道ucos keil如何弄? 在keil环境下是这样的: / h8 m. o; W/ z) {/ J
#define SEGGER_RTT_LOCK() { \
unsigned int LockState; \4 Q$ O: @! P7 A! k: a
register unsigned char BASEPRI __asm( "basepri"); \
LockState = BASEPRI; \
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \- G; P8 D- S" A! E3 ?
__schedule_barrier(); x M1 o! S1 U! E
0 x9 i# J$ f8 w' h( n0 B, n
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \1 j p# L/ ]$ L5 ?, e1 u
__schedule_barrier(); \0 P. T4 \$ f1 W# b2 i# H
}
& _" F( N8 u$ \# L+ ]0 l2 G, O
多谢,我去找找和谐版。