Source Insight 正常识别解析复杂类型宏定义
相信使用Source Insight查看分析过诸如STM32官方库的小伙伴们都见过如下画面一票的官方库寄存器结构体成员无法被正常语法着色、索引。鼠标移动到官方库结构体成员上时Relation和Context窗口的内容也不正常不再正常关联符号调用关系和显示其声明定义。即使精确完整添加工程文件如何精确完整添加请点击参考我的另一篇文档、宏符号的声明定义、结构体类型的声明定义也无济于事依旧如上。而普通的宏解析却正常本着码农刨根问底的精神的我们不禁要问为什么会这样有没有补救办法原因分析简单宏如#define MAX(a,b) ((a)(b)?(a):(b))SI 能直接展开。但 STM32 的外设地址宏本质是 “地址 类型转换” 的组合#define RCC ((RCC_TypeDef *) RCC_BASE)这类宏本质是带强制类型转换的地址别名Source Insight没有完整的 C 编译器前端无法解析这种地址运算和类型转换的组合。对 SI 来说RCC只是一个普通文本它不知道这代表一个指向RCC_TypeDef结构体的指针因此RCC-APB1RSTR中的APB1RSTR不会被识别为结构体成员也不会触发对应的高亮规则因此会直接 “放弃解析”导致成员高亮、索引跳转、补全失败。知道了问题根源就有办法来修理它。我们可以手动添加 “伪定义”欺骗 SI 解析器具体步骤如下步骤1在工程里新建一个空文件命名为si_parse_fix.h步骤2在si_parse_fix.h中添加“伪定义”适用于STM32F10x/F4xx/F7xx/H7xx 全系列可直接拷贝如下代码#ifndef __SI_PARSE_FIX_H #define __SI_PARSE_FIX_H /* * Source Insight 语法解析修复头文件 * 适用STM32F10x/F4xx/F7xx/H7xx 全系列 * 特性仅对SI生效编译时自动忽略不影响工程代码 */ #ifdef __SOURCE_INSIGHT__ #include stm32f10x.h #include core_cm3.h // // 1. 核心系统外设含F1/F4/F7/H7通用 // static RCC_TypeDef *const RCC; //static RCC_TypeDef *const RCC; static FLASH_TypeDef *const FLASH; static FLASH_OBProgramInitTypeDef *const FLASH_OBInit; static PWR_TypeDef *const PWR; static SCB_Type *const SCB; static SysTick_Type *const SysTick; static NVIC_Type *const NVIC; static MPU_Type *const MPU; static FPU_TypeDef *const FPU; static RCC_ClkInitTypeDef *const RCC_ClkInitStruct; // // 2. GPIO AFIO EXTI SYSCFG补全AFIO // static GPIO_TypeDef *const GPIOA; static GPIO_TypeDef *const GPIOB; static GPIO_TypeDef *const GPIOC; static GPIO_TypeDef *const GPIOD; static GPIO_TypeDef *const GPIOE; static GPIO_TypeDef *const GPIOF; static GPIO_TypeDef *const GPIOG; static GPIO_TypeDef *const GPIOH; static GPIO_TypeDef *const GPIOI; static GPIO_TypeDef *const GPIOJ; static GPIO_TypeDef *const GPIOK; // 补全AFIOF1核心F4/F7/H7兼容 static AFIO_TypeDef *const AFIO; static SYSCFG_TypeDef *const SYSCFG; static EXTI_TypeDef *const EXTI; static EXTI_InitTypeDef *const EXTI_InitStruct; // // 3. 定时器通用高级低功耗 // // 通用定时器 static TIM_TypeDef *const TIM1; static TIM_TypeDef *const TIM2; static TIM_TypeDef *const TIM3; static TIM_TypeDef *const TIM4; static TIM_TypeDef *const TIM5; static TIM_TypeDef *const TIM6; static TIM_TypeDef *const TIM7; // 高级定时器 static TIM_TypeDef *const TIM8; static TIM_TypeDef *const TIM9; static TIM_TypeDef *const TIM10; static TIM_TypeDef *const TIM11; static TIM_TypeDef *const TIM12; static TIM_TypeDef *const TIM13; static TIM_TypeDef *const TIM14; static TIM_TypeDef *const TIM15; static TIM_TypeDef *const TIM16; static TIM_TypeDef *const TIM17; // 低功耗定时器F4/F7/H7 static LPTIM_TypeDef *const LPTIM1; static LPTIM_TypeDef *const LPTIM2; static LPTIM_TypeDef *const LPTIM3; static LPTIM_TypeDef *const LPTIM4; static LPTIM_TypeDef *const LPTIM5; // // 4. 串口USART/UART/LPUART // static USART_TypeDef *const USART1; static USART_TypeDef *const USART2; static USART_TypeDef *const USART3; static USART_TypeDef *const UART4; static USART_TypeDef *const UART5; static USART_TypeDef *const USART6; static UART_TypeDef *const UART7; static UART_TypeDef *const UART8; // 低功耗串口F7/H7 static LPUART_TypeDef *const LPUART1; // // 5. SPI / I2S / FMPI2C补全FMPI2C // static SPI_TypeDef *const SPI1; static SPI_TypeDef *const SPI2; static SPI_TypeDef *const SPI3; static SPI_TypeDef *const SPI4; static SPI_TypeDef *const SPI5; static SPI_TypeDef *const SPI6; // I2S static I2S_TypeDef *const I2S1; static I2S_TypeDef *const I2S2; static I2S_TypeDef *const I2S3; // FMPI2CF7/H7 static FMPI2C_TypeDef *const FMPI2C1; static FMPI2C_TypeDef *const FMPI2C2; // // 6. I2C全系列 // static I2C_TypeDef *const I2C1; static I2C_TypeDef *const I2C2; static I2C_TypeDef *const I2C3; static I2C_TypeDef *const I2C4; // // 7. CAN / FD-CAN补全FD-CAN // static CAN_TypeDef *const CAN1; static CAN_TypeDef *const CAN2; // FD-CANF7/H7 static FDCAN_TypeDef *const FDCAN1; static FDCAN_TypeDef *const FDCAN2; static FDCAN_TypeDef *const FDCAN3; // // 8. DMA / DMAMUX补全通道/流DMAMUX // // DMA控制器 static DMA_TypeDef *const DMA1; static DMA_TypeDef *const DMA2; static DMA_TypeDef *const DMA3; static DMA_TypeDef *const DMA4; // DMA流F4/F7/H7 static DMA_Stream_TypeDef *const DMA1_Stream0; static DMA_Stream_TypeDef *const DMA1_Stream1; static DMA_Stream_TypeDef *const DMA1_Stream2; static DMA_Stream_TypeDef *const DMA1_Stream3; static DMA_Stream_TypeDef *const DMA1_Stream4; static DMA_Stream_TypeDef *const DMA1_Stream5; static DMA_Stream_TypeDef *const DMA1_Stream6; static DMA_Stream_TypeDef *const DMA1_Stream7; static DMA_Stream_TypeDef *const DMA2_Stream0; static DMA_Stream_TypeDef *const DMA2_Stream1; static DMA_Stream_TypeDef *const DMA2_Stream2; static DMA_Stream_TypeDef *const DMA2_Stream3; static DMA_Stream_TypeDef *const DMA2_Stream4; static DMA_Stream_TypeDef *const DMA2_Stream5; static DMA_Stream_TypeDef *const DMA2_Stream6; static DMA_Stream_TypeDef *const DMA2_Stream7; // DMA通道F1 static DMA_Channel_TypeDef *const DMA1_Channel1; static DMA_Channel_TypeDef *const DMA1_Channel2; static DMA_Channel_TypeDef *const DMA1_Channel3; static DMA_Channel_TypeDef *const DMA1_Channel4; static DMA_Channel_TypeDef *const DMA1_Channel5; static DMA_Channel_TypeDef *const DMA1_Channel6; static DMA_Channel_TypeDef *const DMA1_Channel7; static DMA_Channel_TypeDef *const DMA2_Channel1; static DMA_Channel_TypeDef *const DMA2_Channel2; static DMA_Channel_TypeDef *const DMA2_Channel3; static DMA_Channel_TypeDef *const DMA2_Channel4; static DMA_Channel_TypeDef *const DMA2_Channel5; // DMAMUXF7/H7 static DMAMUX_TypeDef *const DMAMUX1; static DMAMUX_TypeDef *const DMAMUX2; // // 9. ADC / DAC / OPAMP / COMP补全OPAMP/COMP // static ADC_TypeDef *const ADC1; static ADC_TypeDef *const ADC2; static ADC_TypeDef *const ADC3; static ADC_TypeDef *const ADC4; static ADC_TypeDef *const ADC5; // DAC static DAC_TypeDef *const DAC1; static DAC_TypeDef *const DAC2; // 运算放大器F4/F7/H7 static OPAMP_TypeDef *const OPAMP1; static OPAMP_TypeDef *const OPAMP2; static OPAMP_TypeDef *const OPAMP3; static OPAMP_TypeDef *const OPAMP4; // 比较器F4/F7/H7 static COMP_TypeDef *const COMP1; static COMP_TypeDef *const COMP2; static COMP_TypeDef *const COMP3; static COMP_TypeDef *const COMP4; static COMP_TypeDef *const COMP5; static COMP_TypeDef *const COMP6; static COMP_TypeDef *const COMP7; // // 10. 看门狗 / RTC / BKP // // 看门狗 static IWDG_TypeDef *const IWDG; static WWDG_TypeDef *const WWDG; // RTC 备份寄存器 static RTC_TypeDef *const RTC; static BKP_TypeDef *const BKP; // // 11. CRC / Hash / RNG补全Hash/RNG // static CRC_TypeDef *const CRC; // 哈希F4/F7/H7 static HASH_TypeDef *const HASH; // 随机数发生器 static RNG_TypeDef *const RNG; // // 12. USB / USB_OTG全系列 // static USB_TypeDef *const USB; static USB_OTG_GlobalTypeDef *const USB_OTG_FS; static USB_OTG_GlobalTypeDef *const USB_OTG_HS; static USB_OTG_GlobalTypeDef *const USB_OTG_HS_ANALOG; // // 13. ETH / GMAC补全GMAC // static ETH_TypeDef *const ETH; static ETH_MAC_TypeDef *const ETH_MAC; static ETH_MMC_TypeDef *const ETH_MMC; static ETH_DMA_TypeDef *const ETH_DMA; // GMACH7 static GMAC_TypeDef *const GMAC; // // 14. FMC / FSMC / NOR/PSRAM/SDMMC/QSPI // static FMC_TypeDef *const FMC; static FSMC_TypeDef *const FSMC; // NOR/PSRAM控制器 static FMC_NORSRAM_TypeDef *const FMC_NORSRAM1; static FMC_NORSRAM_TypeDef *const FMC_NORSRAM2; static FMC_NORSRAM_TypeDef *const FMC_NORSRAM3; static FMC_NORSRAM_TypeDef *const FMC_NORSRAM4; // SDRAM控制器 static FMC_SDRAM_TypeDef *const FMC_SDRAM_DEVICE; // SDMMC static SDMMC_TypeDef *const SDMMC1; static SDMMC_TypeDef *const SDMMC2; // QSPI static QSPI_TypeDef *const QUADSPI; static QSPI_TypeDef *const QUADSPI2; // // 15. 音频/视频外设SAI/SPDIF/HDMI_CEC // static SAI_TypeDef *const SAI1; static SAI_TypeDef *const SAI2; static SAI_TypeDef *const SAI3; // SPDIF接收 static SPDIFRX_TypeDef *const SPDIFRX; // HDMI-CEC static HDMI_CEC_TypeDef *const HDMI_CEC; // // 16. 加密/解密外设AES/TAMP // static AES_TypeDef *const AES; static TAMP_TypeDef *const TAMP; static RNG_TypeDef *const RNG; #endif // __SOURCE_INSIGHT__ #endif // __SI_PARSE_FIX_H步骤 3在你的工程主头文件包含si_parse_fix.h或者嫌麻烦担忧影响原项目编译、功能实现可以不将si_parse_fix.h包含进任何项目工程源码只将该文件添加到SI工程即可步骤 4重建 SI 工程 强制同步刷新索引恭喜可以正常解析这类复杂宏了成员语法着色、跳转、上下文调用关联、定义声明展示等一切又正常了请愉快的编程吧PS:si_parse_fix.h头文件仅是欺骗SI解析器用编译时会被自动忽略或者压根不会被编译丝毫不影响原工程编译和功能实现