VSCode+arm-gcc+FreeRTOS+STM32F1

前言

本文是在Windows10环境下,以VSCode+arm交叉编译工具链为开发环境,将FreeRTOS移植到STM32F103系列单片机的说明。其实不叫移植,叫做拷贝,大家都叫移植,那就这样叫了。

工程基于你自己的一个能运行的裸机工程。并且我用的是标准固件库。

为啥搭建这个环境,首先是喜欢用VSCode编辑,还有一个重要原因是,用到的所有工具都是开源的,不用担心版权问题。没钱买有些正版工具,又不想用盗版的人最后的倔强(笑死)。当然付费的有付费的优势,买了服务嘛!有时候免费的才是最贵的,遇到问题只能自己苦逼到处寻找解决方案哈哈!

先看第七节附录,或许对你有帮助!


1 准备工作

1.1 工具准备

  • VSCode
  • GCC-ARM-NONE-EABI(交叉编译工具)
  • Make(构建工具)
  • CMake(Makefile生成工具)
  • OpenOCD(调试下载工具)

上述工具中,前3项是必须的。CMake可以帮助我们生成Makefile文件,如果你自己写Makefile可以不用;OpenOCD是片上调试工具,可以下载和调试,当然你也可以生成二进制文件,用串口下载,不是必须。
这里就不再赘述工具的安装,未配置好环境的读者,可以参考其他文章,先将工具安装好。

我所使用的工具的版本:
请添加图片描述

1.2 FreeRTOS下载

直接在FreeRTOS官网下载最新的即可,我这里下载的普通版,没有下载长期支持版。官网下载地址

1.3 裸机文件准备

一个能跑的裸机工程,最好带串口驱动的。


2 开始移植

2.1 创建FreeRTOS文件夹

在准备好的裸机工程根目录中创建FreeRTOS文件夹,用于存放系统源码。

裸机工程根目录
VSCode+arm-gcc+FreeRTOS+STM32F1_第1张图片

新的根目录

VSCode+arm-gcc+FreeRTOS+STM32F1_第2张图片

2.2 FreeRTOS源文件拷贝

  1. 解压刚刚下载的FreeRTOS的压缩包,并将路径\FreeRTOSv202212.01\FreeRTOS\Source下的所有文件拷贝到上一步创建的freertos文件夹下,拷贝后,如下图。
    VSCode+arm-gcc+FreeRTOS+STM32F1_第3张图片

  2. 进入FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_STM32F103_Primer_GCC,将main.c以及FreeRTOSConfig.h复制到你自己的用户代码文件夹下面。
    VSCode+arm-gcc+FreeRTOS+STM32F1_第4张图片

  3. 进入\Demo\freertos\portable文件夹,如下图。留下GCC和MemMang,其余的全部删除。
    删除后
    VSCode+arm-gcc+FreeRTOS+STM32F1_第5张图片

  4. 进入\Demo\freertos\portable\GCC文件夹,只留ARM_CM3,其余全部删除。
    VSCode+arm-gcc+FreeRTOS+STM32F1_第6张图片

  5. 进入\Demo\freertos\portable\MemMang文件夹,留下heap_4.c其余全部删除。
    VSCode+arm-gcc+FreeRTOS+STM32F1_第7张图片


3 修改文件

3.1 修改CMakeLists.txt或者Makefile

我这里用的CMakeLists.txt,故只给出CMakeLists.txt的修改。就是在CMakeLists.txt中增加源文件以及头文件的包含路径。
根据你自己文件结构的情况修改即可。
以前的
请添加图片描述

增加后的
VSCode+arm-gcc+FreeRTOS+STM32F1_第8张图片

3.2 修改FreeRTOSConfig.h文件

在FreeRTOSConfig.h文件最后加上如下三句宏定义,意思是使用FreeRTOS给我们写好的这三个中断的处理函数,不用自己写了。这样加的好处是,我们不用去修改启动文件中的中断函数名,直接用裸机的启动文件就可以,有些历程中是将启动文件中对应的三个中断向量名给改了。
二选一,要么改启动文件,就不需要宏定义了,要么宏定义,就不需要改启动文件。我觉得宏定义更方便,所以选择宏定义。

#define vPortSVCHandler    SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

还要删除包含的头文件#include "stm32f10x_lib.h",并将#define configUSE_TICK_HOOK 0定义为0,默认为1的。

说明:链接文件也不需要动

3.3 修改stm32f10x_it.c文件

通常标准库的例程下,都配有专门放中断处理函数的一个文件,即stm32f10x_it.c,我们需要注释掉或者删掉上一步中所提到的三个中断处理函数,避免和FreeRTOS中的冲突,导致重定义。
或者直接删掉存放中断处理函数的源文件和头文件也行。

3.3 修改main.c文件

  1. main函数前面,只留如下代码,并且包含#include "stm32f10x.h"如图:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第9张图片

  2. main函数中,只留如下代码,如图:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第10张图片

  3. main函数后面,只留下static void prvSetupHardware( void );的定义,其他全删咯。并且删除此定义中的最后四行。删去如下四行:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第11张图片


4 VSCode相关配置

4.1 安装代码识别补全插件

安装如下,两个插件,并配置c_cpp_properties.json中的编译器路径。全部配置如下:

VSCode+arm-gcc+FreeRTOS+STM32F1_第12张图片

{
    "configurations": [
        {
            "name": "arm_gcc",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE",
                "STM32F10X_HD",
                "USE_STDPERIPH_DRIVER"
            ],
            "cStandard": "c99",
            "cppStandard": "c++98",
            "intelliSenseMode": "gcc-arm",
            "compilerPath": "E:\\stm32_toolchain\\gcc-arm-none-eabi-10.3-2021.10\\bin\\arm-none-eabi-gcc.exe",
            "configurationProvider": "ms-vscode.cmake-tools"
        }
    ],
    "version": 4
}

4.2 配置cmake和make构建任务

当然,你也可以直接用命令行完成,这样配置为VSCode的任务,是更加方便快捷,不一定都得配置。
这些工具使用的命令参数这些,大家就参考着根据自己的文件结构改一下,这里不多说工具的使用。
配置文件task.json内容如下:

{
	"version": "2.0.0",
	"tasks": [
		{
			"label": "cmake",
			"type": "shell",
			"command":"cmake",
			"args": [
				"-B",
				"build/",
				"-G",
				"Unix Makefiles",
				"-DCMAKE_BUILD_TYPE=Debug"
			],
			"group": "build"
		},
		{
			"label": "build",
			"type": "shell",
			"command":"make",
			"args": [
				"-j4",
				"-C",
				"build/"
			],
			"group": "build"
		},
		{
			"label": "download",
			"type": "shell",
			"command":"openocd",
			"args": [
				"-f",
				"interface/cmsis-dap.cfg",
				"-f",
                "target/stm32f1x.cfg",
				"-c",
				"program build/vscodeSTM32.elf verify reset exit"
			],
			"group": "build"
		}
	]
}

4.3 配置调试

调试任务的文件是launch.json,如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug With OpenOCD",
            "cwd": "${workspaceRoot}",
            "executable": "build/vscodeSTM32.elf",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "configFiles": [
                "interface/cmsis-dap.cfg",
                "target/stm32f1x.cfg"
            ],
            "searchDir": [],
            "runToEntryPoint": "main",
            "showDevDebugOutput": "none",
            "svdFile": "./STM32F10x.svd"
        }
    ]
}

5 构建工程

如果没有配置第4步的,可以直接参考其内容中每个命令,用命令行工具构建。
以下使用配置的VSCode任务来快速构建。
在终端中选择运行生成任务,或者用你的快捷键。
VSCode+arm-gcc+FreeRTOS+STM32F1_第13张图片

  1. 运行cmake任务
    生成成功:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第14张图片

  2. 运行make任务
    构建成功:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第15张图片

到目前为止,编译链接成功,说明我们的工程和配置文件没有问题。


6 大型点灯以及通信工程

我打算用最常见最简单的两个功能来演示,点灯和串口打印。

  1. 先包含串口头文件,然后GPIO口的配置声明,以及两个任务函数。如图:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第16张图片
#include "bsp_usart.h"

static void GPIO_LED_Conf(void);

void Task1_LED(void *param)
{
	GPIO_LED_Conf();
	const TickType_t xTickstoWait = pdMS_TO_TICKS(500);
	while (1)
	{
		GPIO_WriteBit(GPIOE, GPIO_Pin_5, Bit_RESET);
		vTaskDelay(xTickstoWait);
		GPIO_WriteBit(GPIOE, GPIO_Pin_5, Bit_SET);
		vTaskDelay(xTickstoWait);
	}
}

void Task2_Print(void *param)
{
	USART_Conf();
	const TickType_t xTickstoWait = pdMS_TO_TICKS(1000);
	while (1)
	{
		printf("Print Task is runing every 1 second...\n");
		vTaskDelay(xTickstoWait);
	}
}
  1. 然后在main函数中创建任务。如图:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第17张图片
xTaskCreate(Task1_LED, "Task1_LED", 100, NULL, 1, NULL);
xTaskCreate(Task2_Print, "Task2_Print", 100, NULL, 1, NULL);
  1. GPIO的配置我放在main函数后面的,这个需要根据自己的板子led的引脚位置来改。
static void GPIO_LED_Conf(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOE, &GPIO_InitStructure);
}
  1. 再次构建build或者说make
    构建成功:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第18张图片

  2. 然后就是下载了,可以用串口,也可以用刚刚配置的任务download,反正下载的方式非常多,用你之前的只要能下进去就行。
    下载进去试试:
    LED灯闪烁:

    串口打印:
    VSCode+arm-gcc+FreeRTOS+STM32F1_第19张图片

到此为止,FreeRTOS算是成功移植到了STM32F103上面了。收工!


7 附录

GitHub仓库
视频教程

你可能感兴趣的:(stm32,c语言,stm32,vscode)