一、插件安装

目前安装的插件,可能有重复功能插件,需自行判断

  1. STM32CubeIDE for Visual Studio Code(安装后会将涉及的插件均安装)
  2. Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code(中文包)
  3. CMake Tools(Cmake编译工具,STM32CubeIDE插件安装后也会有Cmake插件,可不安装)
  4. C/C++(C语言插件)
  5. Cortex-Debug(调试插件)
  6. MemoryView(内存查看插件)
  7. Peripheral Viewer(通过SVD插件查看寄存器内容)
  8. Memory Inspector(内存查看)
  9. Hex Editor(十六进制显示编辑)
  10. debug-tracker-vscode(调试跟踪)
  11. MASM(汇编查看)

二、工程生成

  1. 使用 STM32Cube 插件生成空项目
插件生成空项目
  1. 输入工程名称
输入工程名称
  1. 选择从芯片新建
选择从芯片新建
  1. 选择芯片
选择芯片
  1. 保存路径
保存路径
  1. 生成后的目录
生成后的目录

三、工程配置

CMakeLists.txt配置

1、修改工程名称随文件夹名称变动

# Core project settings
# project("STM32F103VCT6")
# enable_language(C CXX ASM)
get_filename_component(PROJECT_DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
set(CMAKE_PROJECT_NAME ${PROJECT_DIR_NAME})

2、修改实际源文件及对应头文件目录

# Sources
set(sources_SRCS
	${CMAKE_CURRENT_SOURCE_DIR}/Src/main.c
    ${CMAKE_CURRENT_SOURCE_DIR}/Src/system/gpio.c
    ${CMAKE_CURRENT_SOURCE_DIR}/Src/system/iic1.c
    )
# Include directories for all compilers
set(include_DIRS
	${CMAKE_CURRENT_SOURCE_DIR}/Inc
)

3、定义链接目录和链接名称,主要修改链接库需要带参数 m

# Link directories and names of libraries
set(link_DIRS)
set(link_LIBS m)

4、定义输出文件名为项目名称

# Add support for blank char as part of project name
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${CMAKE_PROJECT_NAME})

5、增加系统默认宏定义STM32F103XX

# Add project symbols (macros)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
    ${symbols_SYMB}
    $<$<COMPILE_LANGUAGE:C>: ${symbols_c_SYMB}>
    $<$<COMPILE_LANGUAGE:CXX>: ${symbols_cxx_SYMB}>
    $<$<COMPILE_LANGUAGE:ASM>: ${symbols_asm_SYMB}>

    # Configuration specific
    $<$<CONFIG:Debug>:DEBUG>
    $<$<CONFIG:Release>: >

    STM32F103XX
)

6、修改编译选项和链接选项,已经过多次尝试优化,编译文件尺寸已和keil接近,感兴趣的可自行研究

# Compiler options
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
    ${cpu_PARAMS}
    ${compiler_OPTS}
    # -Wall
    # -Wextra
    # -Wpedantic
    # -Wno-unused-parameter
    $<$<COMPILE_LANGUAGE:C>: 
        -Wall 
        -fdata-sections 
        -ffunction-sections>
    $<$<COMPILE_LANGUAGE:CXX>:

    # -Wno-volatile
    # -Wold-style-cast
    # -Wuseless-cast
    # -Wsuggest-override
        -fno-rtti
        -fno-exceptions
        -fno-threadsafe-statics 
    >
    $<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp -MMD -MP>
    $<$<CONFIG:Debug>:-O0 -g3 -ggdb>
    $<$<CONFIG:Release>:-Os>
)

# Linker options
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
    -T${linker_script_SRC}
    ${cpu_PARAMS}
    ${linker_OPTS}
    -Wl,-Map=${CMAKE_PROJECT_NAME}.map
    # -u _printf_float # STDIO float formatting support (remove if not used)
    # --specs=nosys.specs
    --specs=nano.specs # 
    # -Wl,--start-group
    # -lc
    -lm
    # -lstdc++
    # -lsupc++
    # -Wl,--end-group
    # -Wl,-z,max-page-size=8 # Allow good software remapping across address space (with proper GCC section making)
    -Wl,--print-memory-usage
)

gnu-tools-for-stm32.cmake

一般不要修改

vscode_generated.cmake配置

链接文件和头文件等文件变化时才需要修改

# Linker script
set(linker_script_SRC ${linker_script_SRC}
	${CMAKE_CURRENT_SOURCE_DIR}/stm32f103xc_flash.ld
)

# Sources
set(sources_SRCS ${sources_SRCS}
	${CMAKE_CURRENT_SOURCE_DIR}/Src/syscall.c
	${CMAKE_CURRENT_SOURCE_DIR}/Src/sysmem.c
	${CMAKE_CURRENT_SOURCE_DIR}/Src/startup_stm32f103xx.S
)

CMakePresets.json修改配置

1、一般不要修改,如果不想新建工程文件,只是芯片改了,记得来这里修改芯片型号,否则调试会报错

"CMSIS_Dname": "STM32F103VBT6",

编译

1、工程项目一定设置为debug模式,release模式编译出来的文件有问题

2、windows系统下新建clean_build.bat批处理文件清除编译缓存,代码内容如下:

del /q /f /s build\*
rmdir /s /q build\Debug

3、通过cmake编译生成执行文件
在这里插入图片描述
在这里插入图片描述

调试

1、点击调试自动生成,或者使用配置好的文件直接复制过来,配置调试文件
在这里插入图片描述
2、launch.json需要注意以下几个地方

{
    "version": "0.2.0",
    "configurations": [//cortex-debuge内的jlink
        {
            "cwd": "${workspaceFolder}",
            "executable": "./build/Debug/${workspaceRootFolderName}.elf",
            "name": "JLink6.20",
            "request": "launch",
            "type": "cortex-debug",
            "device": "STM32F103VCT6", //芯片型号必须和Jlink软件中的型号一致
            "runToEntryPoint": "main",
            "showDevDebugOutput": "raw",
            "servertype": "jlink",
            "serverpath": "C:/Program Files (x86)/SEGGER/JLink_V620/JLinkGDBServerCL.exe",//JLinkGDBServerCL.exe自定义路径
            "svdFile": "${workspaceRoot}/STM32F103xx.svd",//指定SVD文件路径,查看寄存器内容
            "liveWatch": {
                "enabled": true,//使能实时查看变量功能
                "samplesPerSecond": 2//2秒采集一次数据
            }
        },
        {//stm for vscode 内的stlink
            "type": "stlinkgdbtarget",
            "request": "launch",
            "name": "STM32Cube: STM32 Launch ST-Link GDB Server",
            "origin": "snippet",
            "cwd": "${workspaceFolder}",
            "preBuild": "${command:st-stm32-ide-debug-launch.build}",
            "runEntry": "main",
            "imagesAndSymbols": [
                {
                    "imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}"
                }
            ]
        }
    ]
}

2、settings.json需要注意以下几个地方

{
    "cmake.cmakePath": "cube-cmake",
    "cmake.configureArgs": [
        "-DCMAKE_COMMAND=cube-cmake"
    ],
    "cmake.preferredGenerators": [
        "Ninja"
    ],
    "stm32cube-ide-clangd.path": "cube",
    "stm32cube-ide-clangd.arguments": [
        "starm-clangd",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-gcc.exe",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/13.3.1+st.9/bin/arm-none-eabi-g++.exe"
    ],
    "files.encoding": "gb2312"
}

3、SVD文件需要去自行下载,下载后放到主目录,svd可以去官方给的驱动包文件中找
在这里插入图片描述
在这里插入图片描述
4、调试时,通过.launch文件使能live watch功能,可实时查看变量值。
在这里插入图片描述

四、代码移植

.ld链接文件修改

1、主要修改配置RAM和FLASH起始地址及大小

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 48K-1
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 20K
}

2、涉及特殊FLASH和RAM配置的需单独配置,比如需要实现远程IAP更新,在写自身flash时需要将flash写函数搬运到RAM中,需要上电后把写flash函数和变量搬运到RAM中,需要单独定义FLASH和RAM空间,以便写flash时自身代码和变量存储区域丢失也不影响函数功能

.s启动文件修改

1、注释掉通过库函数初始化函数启动,直接通过主函数启动

/* Call the clock system initialization function.*/
 ; bl  SystemInit

2、配套上面描述的IAP更新需要在启动main函数前搬运程序

源文件及头文件复制

1、可以按照原来的目录格式直接复制过来,但要记得在Cmake文件中添加对应的源文件及目录
在这里插入图片描述

部分截图在这里插入图片描述

2、如果是ARMCC编译器移植过来的代码,注意ARMCC和GCC有语法区别,目前涉及到的有以下几个

  • 内联汇编写法不一样
    gcc写法
void WFI_SET(void)
{
	__asm__ volatile ("WFI");			  
}

armcc写法

__asm void WFI_SET(void)
{
	WFI;		  
}
  • __packed支持不一样
    gcc写法
typedef union __attribute__((aligned(2), packed)) {
	uint8_t v[6];
	struct __attribute__((packed)){//注意此处,arm-gcc编译器与armcc编译器对__packed的支持不一样
		uint16_t	 		ByteCount;
		}

armcc写法

typedef union __attribute__((aligned(2), packed)) {
	uint8_t v[6];
	__packed struct {
	uint16_t	 		ByteCount;
	}

五、其他注意事项

  • vscode使用技巧
    1、可以针对不同的开发环境,配置不同的插件
    在这里插入图片描述
    2、AI代码补全插件,下载这个插件,很好用
    在这里插入图片描述
    3、堆栈大小一定要设置合理,设置不合理,程序会跑飞,堆栈大小可以按下面的方法估算
    栈大小 = (最大调用深度 × 平均栈帧大小) + (最大中断嵌套层数 × 中断栈开销) + 安全余量
    网络协议栈最大8层,栈帧大小平均128字节
    还要考虑函数局部变量最大值,假如定义了1个1000字节的局部变量,那么栈大小要考虑调用这个函数时会占用的栈空间
    堆大小 = 显式分配需求 + 隐式分配需求 + 安全余量
    显示分配:malloc/calloc/free 调用
    标准库使用:printf/sprintf 等内部可能使用堆
    是否有自定义内存管理

4、调试程序时一定要将launch.json中配置的芯片型号写对,要和jlink中对应的芯片型号对应,比如STM32F103CBT6,实际在jlink中是STM32F103CB;其次STM32F103CB和STM32F103C8也要区分,不能通用,可能导致程序跑飞

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐