SystemView 移植
前言我想要使用 SystemView 可以精确调试 FreeRTOS 系统而且调试接口是 SW 接口不使用串口进行 SystemView 调试。接下来我需要将 SystemView 移植到 STM32G473RCT6 中。如果想和我保持一致那么这里有一些需要准备的东西表1类别名称备注硬件ARM 仿真器我的版本是“高配版独立SN LINK V9”具有 SW 调试接口的主控板MCU 使用 STM332G473RCT6软件STM32 HAL库cubemx 生成FreeRTOS Kernel V10.3.1cubemx 生成FreeRTOS.h 文件开头注释可见版本SystemView官方软件以及配套示例代码资料准备 SystemView 文件从 下载链接 下载并安装好 SystemView 后在安装目录中有如下路径图1需要备份的文件如下可以将他们打包到新建文件夹 SystemView 中之后将其添加到 MDK 的工程中注意 MDK 设置好头文件路径。表2相对路径文件备注\Src\ConfigGlobal.hSEGGER_RTT_Conf.hSEGGER_SYSVIEW_Conf.h\Src\Sample\FreeRTOSV10SEGGER_SYSVIEW_FreeRTOS.cSEGGER_SYSVIEW_FreeRTOS.h适配FreeRTOS Kernel V10.3.1\Src\Sample\FreeRTOSV10\Config\Cortex-MSEGGER_SYSVIEW_Config_FreeRTOS.c\Src\SEGGERSEGGER.hSEGGER_RTT.cSEGGER_RTT.hSEGGER_RTT_printf.cSEGGER_SYSVIEW.cSEGGER_SYSVIEW.hSEGGER_SYSVIEW_ConfDefaults.hSEGGER_SYSVIEW_Int.h移植细节cubemx 生成 HAL 库cubemx 中需要注意的是我使用的 FreeRTOS 如图2所示。图2如图3所示FreeRTOS 设置 configCHECK_FOR_STACK_OVERFLOW 和 configUSE_TRACE_FACILITY 都要使能。图3cubemx 的中断优先级如图4的 Priority Group 所示即默认配置。图4cubemx 的 HAL库时基使用定时器不使用 SysTick 时钟如图5所示。图5文件 SEGGER_SYSVIEW_Conf.h添加如下代码/********************************************************************* * TODO: Add your defines here. * ********************************************************************** */ // 1. 时间戳使用 Cortex-M DWT 周期计数器地址固定 #define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(volatile U32 *)(0xE0001004)) #define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // 2. 中断 ID读取 ICSR 的 ACTIVEVECTOR 字段 #define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(volatile U32 *)(0xE000ED04)) 0x1FF) // 3. ID 压缩STM32G473 指针在 SRAM 中4 字节对齐 #define SEGGER_SYSVIEW_ID_BASE 0x20000000 #define SEGGER_SYSVIEW_ID_SHIFT 2 // 4. 临界区保护与 RTT 共用锁使用 BASEPRI // 注意此值需与 FreeRTOS 的 configMAX_SYSCALL_INTERRUPT_PRIORITY 协调 // 假设你使用 NVIC_PriorityGroup_4configMAX_SYSCALL_INTERRUPT_PRIORITY 0x50 #define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK() #define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK() // 5. 缓冲区大小连续记录 1-4KB 足够 #define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 2048 // 6. 使用静态缓冲区节省栈空间 #define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 #endif // SEGGER_SYSVIEW_CONF_H /*************************** End of file ****************************/文件 SEGGER_RTT_Conf.h不使用 RTT 功能保持默认。文件 SEGGER_SYSVIEW_Config_FreeRTOS.c修改和添加如下代码/********************************************************************* * * Defines, configurable * ********************************************************************** */ // The application name to be displayed in SystemViewer #define SYSVIEW_APP_NAME STM32G473_FreeRTOS // The target device name #define SYSVIEW_DEVICE_NAME STM32G473RCT6 // Frequency of the timestamp. Must match SEGGER_SYSVIEW_GET_TIMESTAMP in SEGGER_SYSVIEW_Conf.h #define SYSVIEW_TIMESTAMP_FREQ (configCPU_CLOCK_HZ) // System Frequency. SystemcoreClock is used in most CMSIS compatible projects. #define SYSVIEW_CPU_FREQ configCPU_CLOCK_HZ // The lowest RAM address used for IDs (pointers) #define SYSVIEW_RAM_BASE (0x20000000) // DWT 寄存器 #define DEMCR (*(volatile unsigned long *)(0xE000EDFCuL)) #define TRACEENA_BIT (1uL 24) #define DWT_CTRL (*(volatile unsigned long *)(0xE0001000uL)) #define NOCYCCNT_BIT (1uL 25) #define CYCCNTENA_BIT (1uL 0) // vTaskSwitchContext 函数内使用宏 traceTASK_SWITCHED_OUT 和 traceTASK_SWITCHED_IN 将这些宏重定向 #undef traceTASK_SWITCHED_OUT #define traceTASK_SWITCHED_OUT() SYSVIEW_RecordTaskStopExec() #undef traceTASK_SWITCHED_IN #define traceTASK_SWITCHED_IN() SYSVIEW_RecordTaskStartExec() /********************************************************************* * * _cbSendSystemDesc() * * Function description * Sends SystemView description strings. */ static void _cbSendSystemDesc(void) { SEGGER_SYSVIEW_SendSysDesc(NSYSVIEW_APP_NAME,DSYSVIEW_DEVICE_NAME,OFreeRTOS); SEGGER_SYSVIEW_SendSysDesc(I#15SysTick, I#14PendSV, I#11SVC \ I#17PVD, I#42TimeBase, I#53RS485_USART, I#71RS485_TIM); } /********************************************************************* * * Global functions * ********************************************************************** */ void SEGGER_SYSVIEW_Conf(void) { // 使能 DWT 周期计数器无调试器连接时必须由应用开启 if ((DEMCR TRACEENA_BIT) 0) { DEMCR | TRACEENA_BIT; } if ((DWT_CTRL NOCYCCNT_BIT) 0) { // 支持 CYCCNT if ((DWT_CTRL CYCCNTENA_BIT) 0) { DWT_CTRL | CYCCNTENA_BIT; } } SEGGER_SYSVIEW_Init(SYSVIEW_TIMESTAMP_FREQ, SYSVIEW_CPU_FREQ, SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc); SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE); }其中 _cbSendSystemDesc 函数的 I#15SysTick 表示“Interrupt #15 SysTick”而 15 是从启动文件 startup_stm32g473xx.s 的中断向量表中得到的其中 __initial_sp 是0号中断号。__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler ; External Interrupts DCD WWDG_IRQHandler ; Window WatchDog DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection DCD RTC_TAMP_LSECSS_IRQHandler ; RTC, TAMP and RCC LSE_CSS through the EXTI line DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line DCD FLASH_IRQHandler ; FLASH DCD RCC_IRQHandler ; RCC DCD EXTI0_IRQHandler ; EXTI Line0 DCD EXTI1_IRQHandler ; EXTI Line1 DCD EXTI2_IRQHandler ; EXTI Line2 DCD EXTI3_IRQHandler ; EXTI Line3 DCD EXTI4_IRQHandler ; EXTI Line4 DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 DCD ADC1_2_IRQHandler ; ADC1 and ADC2 DCD USB_HP_IRQHandler ; USB Device High Priority DCD USB_LP_IRQHandler ; USB Device Low Priority DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt line 0 DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt line 1 DCD EXTI9_5_IRQHandler ; External Line[9:5]s DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break, Transition error, Index error and TIM15 DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 DCD TIM1_TRG_COM_TIM17_IRQHandler ; TIM1 Trigger, Commutation, Direction change, Index and TIM17 DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare DCD TIM2_IRQHandler ; TIM2 DCD TIM3_IRQHandler ; TIM3 DCD TIM4_IRQHandler ; TIM4 DCD I2C1_EV_IRQHandler ; I2C1 Event DCD I2C1_ER_IRQHandler ; I2C1 Error DCD I2C2_EV_IRQHandler ; I2C2 Event DCD I2C2_ER_IRQHandler ; I2C2 Error DCD SPI1_IRQHandler ; SPI1 DCD SPI2_IRQHandler ; SPI2 DCD USART1_IRQHandler ; USART1 DCD USART2_IRQHandler ; USART2 DCD USART3_IRQHandler ; USART3 DCD EXTI15_10_IRQHandler ; External Line[15:10] DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line DCD USBWakeUp_IRQHandler ; USB Wakeup through EXTI line DCD TIM8_BRK_IRQHandler ; TIM8 Break, Transition error and Index error Interrupt DCD TIM8_UP_IRQHandler ; TIM8 Update Interrupt DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger, Commutation, Direction change and Index Interrupt DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare Interrupt DCD ADC3_IRQHandler ; ADC3 DCD FMC_IRQHandler ; FMC DCD LPTIM1_IRQHandler ; LP TIM1 interrupt DCD TIM5_IRQHandler ; TIM5 DCD SPI3_IRQHandler ; SPI3 DCD UART4_IRQHandler ; UART4 DCD UART5_IRQHandler ; UART5 DCD TIM6_DAC_IRQHandler ; TIM6 and DAC13 underrun errors DCD TIM7_DAC_IRQHandler ; TIM7 and DAC24 underrun errors DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 DCD ADC4_IRQHandler ; ADC4 DCD ADC5_IRQHandler ; ADC5 DCD UCPD1_IRQHandler ; UCPD1 DCD COMP1_2_3_IRQHandler ; COMP1, COMP2 and COMP3 DCD COMP4_5_6_IRQHandler ; COMP4, COMP5 and COMP6 DCD COMP7_IRQHandler ; COMP7 DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD CRS_IRQHandler ; CRS Interrupt DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt DCD TIM20_BRK_IRQHandler ; TIM20 Break, Transition error and Index error DCD TIM20_UP_IRQHandler ; TIM20 Update DCD TIM20_TRG_COM_IRQHandler ; TIM20 Trigger, Commutation, Direction change and Index DCD TIM20_CC_IRQHandler ; TIM20 Capture Compare DCD FPU_IRQHandler ; FPU DCD I2C4_EV_IRQHandler ; I2C4 event DCD I2C4_ER_IRQHandler ; I2C4 error DCD SPI4_IRQHandler ; SPI4 DCD 0 ; Reserved DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt line 0 DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt line 1 DCD FDCAN3_IT0_IRQHandler ; FDCAN3 interrupt line 0 DCD FDCAN3_IT1_IRQHandler ; FDCAN3 interrupt line 1 DCD RNG_IRQHandler ; RNG global interrupt DCD LPUART1_IRQHandler ; LP UART 1 interrupt DCD I2C3_EV_IRQHandler ; I2C3 Event DCD I2C3_ER_IRQHandler ; I2C3 Error DCD DMAMUX_OVR_IRQHandler ; DMAMUX overrun global interrupt DCD QUADSPI_IRQHandler ; QUADSPI DCD DMA1_Channel8_IRQHandler ; DMA1 Channel 8 DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 DCD DMA2_Channel8_IRQHandler ; DMA2 Channel 8 DCD CORDIC_IRQHandler ; CORDIC DCD FMAC_IRQHandler ; FMAC __Vectors_End文件 FreeRTOSConfig.h添加如下代码/* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ // 解决 xTaskIncrementTick 导致触发 HardFault_Handler #undef xPortSysTickHandler #define osSystickHandler SysTick_Handler #ifdef SYSTEM_VIEW // SystemView #include SEGGER_SYSVIEW_FreeRTOS.h #define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_pxTaskGetStackStart 1 // 解决 error: A1586E: Bad operand types (UnDefOT, Constant) for operator ( #undef configPRIO_BITS #define configPRIO_BITS 4 #endif // SYSTEM_VIEW /* USER CODE END Defines */ #endif /* FREERTOS_CONFIG_H */其中 #ifdef SYSTEM_VIEW 指令是方便我的后续调试可以去掉但注意同时删除对应的 #endif 指令。函数 xPortSysTickHandler该函数最终对应 SysTick_Handler 。修改如下代码void xPortSysTickHandler( void ) { #ifdef SYSTEM_VIEW traceISR_ENTER(); #endif /* The SysTick runs at the lowest interrupt priority, so when this interrupt executes all interrupts must be unmasked. There is therefore no need to save and then restore the interrupt mask value as its value is already known - therefore the slightly faster vPortRaiseBASEPRI() function is used in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ vPortRaiseBASEPRI(); { /* Increment the RTOS tick. */ if( xTaskIncrementTick() ! pdFALSE ) { /* A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG portNVIC_PENDSVSET_BIT; } } vPortClearBASEPRIFromISR(); #ifdef SYSTEM_VIEW traceISR_EXIT(); #endif }不触发 FreeRTOS 调度的中断不调用 portYIELD_FROM_ISR(xHigherPriorityTaskWoken) 的中断不会强制触发 FreeRTOS 任务调度。如果没有回调函数那么有如下代码void TIM2_IRQHandler(void) { SEGGER_SYSVIEW_RecordEnterISR(); // 记录中断进入 // ... HAL_TIM_IRQHandler(htim2); SEGGER_SYSVIEW_RecordExitISR(); // 记录中断退出 }如果有对应的回调函数那么有如下代码void TIM2_IRQHandler(void) { SEGGER_SYSVIEW_RecordEnterISR(); // ← 中断开始 HAL_TIM_IRQHandler(htim2); // ← 内部会调用 } // HAL_TIM_PeriodElapsedCallback() { // ... SEGGER_SYSVIEW_RecordExitISR(); // ← 中断结束 }SystemView 软件图6图7图8图9图10参考链接移植Systemviewend

相关新闻

ESP32 智能灌溉实战:1 块开发板 + 3 个传感器搭出远程监控的完整指南

ESP32 智能灌溉实战:1 块开发板 + 3 个传感器搭出远程监控的完整指南

ESP32 智能灌溉实战:1 块开发板 3 个传感器搭出远程监控的完整指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 老张的草莓园,阿姨一请假浇水就…

2026/10/25 21:31:52 阅读更多 →
计算机毕业设计之慧零超市管理系统的设计与实现

计算机毕业设计之慧零超市管理系统的设计与实现

相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低慧零超市的运营人员成本,实现了慧零超市管理系统的标准化、制度化、程序化的管理,有效地防止了慧零超市管理系统的随意管理,提高了信息的处理速度和精确度,…

2026/10/25 0:03:38 阅读更多 →
mysql order by 中文排序

mysql order by 中文排序

前言在 MySQL 中,我们经常会对一个字段进行排序查询,但进行中文排序和查找的时候,对汉字的排序和查找结果往往都是错误的。 这种情况在 MySQL 的很多版本中都存在。如果这个问题不解决,那么 MySQL 将无法实际处理中文。 出现这个问…

2026/10/24 6:16:55 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/15 5:13:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/15 5:13:35 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/15 5:13:35 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/15 3:37:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/15 4:18:38 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/15 5:13:35 阅读更多 →

日新闻

周新闻

月新闻