将FreeRTOS移植到STM32F103RCT6(江协模版,标准库)

最近,想做台ROS导航小车,底层用STM32F103RCT6控制,想加入FreeRTOS,但网上基于江协模版并用标准库开发的比较少,这里记录一下自己的移植记录,方便后续学习。

参考博客:

移植FreeRTOS到STM32程序中(超详细)_freertos和stm32-CSDN博客

STM32标准库移植FreeRTOS和学习教程_stm32使用freertos实现oled-CSDN博客

第一步,从FreeRTOS官网下载FreeRTOS源码

网址:https://sourceforge.net/projects/freertos/files/FreeRTOS/

1.选择V9.0.0

2.选择FreeRTOSv9.0.0.zip

3.等待一会就可以开始下载了

4.但下载速度很慢,我当时下了两个小时,我这里附上百度网盘链接和源代码供大家参考
http://链接:https://pan.baidu.com/s/1MAG_geUE3J7-TjifNqdbKw?pwd=god6 提取码:god6 --来自百度网盘超级会员V5的分享

第二步,在已创建好的工程文件夹内创建三个新的文件夹FreeRTOS_Inc、FreeRTOS_Src、FreeRTOS_Port,分别存放FreeRTOS的源文件,头文杰和接口文件。

分别往三个文件夹内加入FreeRTOS源码文件

1.头文件在我们下载下来FreeRTOS源码目录:FreeRTOSv9.0.0/FreeRTOSv9.0.0/FreeRTOS/Source/include

2.源文件在我们下载下来FreeRTOS源码目录:FreeRTOSv9.0.0/FreeRTOSv9.0.0/FreeRTOS/Source

3.接口文件在我们下载下来FreeRTOS源码目录:FreeRTOSv9.0.0/FreeRTOSv9.0.0/FreeRTOS/Source/portable/MemMang

FreeRTOSv9.0.0/FreeRTOSv9.0.0/FreeRTOS/Source/portable/RVDS/ARM_CM3

4.FreeRTOSConfig.h在我们下载下来FreeRTOS源码目录:

FreeRTOSv9.0.0/FreeRTOSv9.0.0/FreeRTOS/Demo/CORTEX_STM32F103_Keil/

第三步,进入keil5进行配置

1.点击三个小方块按钮

2.添加路径

3.修改FreeRTPSConfig.h文件

复制如下代码至FreeRTOSConfig.h

#define configUSE_TIME_SLICING 1 		//使能时间片调度(默认式使能的)
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 //硬件计算前导零指令,如果所使用的, MCU 没有这些硬件指令的话此宏应该设置为 0
#define configUSE_TICKLESS_IDLE 0 //置 1:使能低功耗 tickless 模式;置 0:保持系统节拍(tick)中断一直运行
#define configUSE_QUEUE_SETS 1 //启用队列
#define configUSE_TASK_NOTIFICATIONS 1 //开启任务通知功能,默认开启
#define configUSE_MUTEXES 1 //使用互斥信号量
#define configUSE_RECURSIVE_MUTEXES 1 //使用递归互斥信号量
#define configUSE_COUNTING_SEMAPHORES 1 //为 1 时使用计数信号量
#define configQUEUE_REGISTRY_SIZE 10 //设置可以注册的信号量和消息队列个数
#define configUSE_APPLICATION_TASK_TAG 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1 //支持动态内存申请
#define configUSE_MALLOC_FAILED_HOOK 0 //使用内存申请失败钩子函数
// 大于 0 时启用堆栈溢出检测功能,如果使用此功能用户必须提供一个栈溢出钩子函数如果使用的话此值可以为 1 或者 2,因为有两种栈溢出检测方法
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configGENERATE_RUN_TIME_STATS 0 //启用运行时间统计功能
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configUSE_TIMERS 1 //启用软件定时器
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) //软件定时器优先级
#define configTIMER_QUEUE_LENGTH 10 //软件定时器队列长度
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) //软件定时器任务堆栈大小可选函数配置选项
#define INCLUDE_xTaskGetSchedulerState 1	
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
//中断服务函数 也可以修改起始文件
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

插入位置如下,只要在#ifndef和#endif中间即可

继续更改下面的源码,还是在FreeRTOSConfig.h文件中

屏蔽stm32f103x_it.c中的部分代码

在stm32f103x_it.c中添加构造子函数

#include "stdio.h"
void vApplicationStackOverflowHook(void)
{
	while(1)
	{
		
	}
}

 

 第四步,编译,0错误,0警告,移植成功

第五步,配置两个LED

1. .C代码

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOC,GPIO_Pin_2 | GPIO_Pin_3);
}

void LED_ON(uint8_t x)
{
	switch(x)
	{
		case 2:GPIO_ResetBits(GPIOC,GPIO_Pin_2);break;
		case 3:GPIO_ResetBits(GPIOC,GPIO_Pin_3);break;
		default:GPIO_SetBits(GPIOC,GPIO_Pin_2 | GPIO_Pin_3);
	}
}

void LED_OFF(uint8_t x)
{
	switch(x)
	{
		case 2:GPIO_SetBits(GPIOC,GPIO_Pin_2);break;
		case 3:GPIO_SetBits(GPIOC,GPIO_Pin_3);break;
		default:GPIO_SetBits(GPIOC,GPIO_Pin_2 | GPIO_Pin_3);
	}
}

2. .h代码

#ifndef __LED_H
#define __LED_H
void LED_Init(void);
void LED_ON(uint8_t x);
void LED_OFF(uint8_t x);
#endif

 第六步,创建两个任务,实现两个LED同时闪烁,但两个灯的闪烁频率不同

1. 创建并编写freertos_program.c文件

#include "stm32f10x.h"                  // Device header
#include "freertos.h"
#include "task.h"
#include "LED.h"

/*---´´½¨ÈÎÎñ¾ä±ú---*/
static TaskHandle_t myTaskHandler_0;
static TaskHandle_t myTaskHandler_1;
static TaskHandle_t myTaskHandler_2;
	
/*---ÈÎÎñº¯ÊýµÄÉùÃ÷---*/
void task_begin(void *arg);
void myTask_1(void *arg);
void myTask_2(void *arg);
	
/*---µÚÒ»¸öÈÎÎñTask_beginµÄ´´½¨,ÆäÖаüº¬×ÅÆäÓàÁ½¸öÈÎÎñµÄ´´½¨---*/
void freertos_demo(void)
{
	xTaskCreate(task_begin,"task_begin",128,NULL,1,&myTaskHandler_0);
	vTaskStartScheduler();
}
	
/*---µÚÒ»¸öÈÎÎñtask_beginº¯Êý,ÐèÒª½øÈëÈÎÎñÁÙ½çÇø,ºÍÍ˳öÁÙ½çÇø
ÒòΪ³ÌÐòÊÇÒ»ÐÐÒ»ÐÐÀ´µÄ,ËùÒÔmyTask_1´´½¨Ê±,ÓÅÏȼ¶±Ètask_begin¸ß,È»ºóTask2ÓÅÏȼ¶±È1¸ß,ÒÔ´ËÀàÍÆ,3±È2¸ß,×îºóÒ»Ö±ÊÇ3¸ß
---*/

void task_begin(void *arg)
{
	taskENTER_CRITICAL();
	xTaskCreate(myTask_1,"myTask_1",128,NULL,2,&myTaskHandler_1);
	xTaskCreate(myTask_2,"myTask_2",128,NULL,3,&myTaskHandler_2);
	vTaskDelete(NULL);
	taskEXIT_CRITICAL();
}

void myTask_1(void *arg)
{
	while(1)
	{
		LED_ON(2);
		vTaskDelay(200);
		LED_OFF(2);
		vTaskDelay(200);
	}
}

void myTask_2(void *arg)
{
	while(1)
	{
		LED_ON(3);
		vTaskDelay(1000);
		LED_OFF(3);
		vTaskDelay(1000);
	}
}

2. 创建并编写freertos_program.h文件 

#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H
void freertos_demo(void);
void task_begin(void *arg);
void myTask_1(void *arg);
void myTask_2(void *arg);
#endif

第七步,编写主函数,观察现象

#include "stm32f10x.h" // Device header
#include "LED.h"
#include "FreeRTOS.h"
#include "task.h"
#include "freertos_program.h"
int main(void)
{
	LED_Init();
	freertos_demo();
}

led闪烁

 

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值