FreeRTOS移植到STM32F103

1.创建工程

2.将FreeRTOS源码,拷贝到工程目录

3.删除其它架构和编译器的代码

查看portable文件夹发现

MemMang为内存管理相关文件需要保留

Commom里面有个mpu相关代码,我们不使用mpu,可以删除

我们的开发环境是keil,打开keil文件夹,提示我们参照RVDS,因此保留RVDS,其它删除

打开RVDS文件夹

STM32F103的内核为CORTEX-M3,删除其它架构相关文件

4.将FreeRTOS文件添加进工程

添加好之后,编译出现错误,缺少FreeRTOSConfig.h文件

5.添加配置文件

从FreeRTOS的demo程序中,将FreeRTOSConfig.h文件拷贝过来

重新编译,无错误无警告

6.修改异常向量入口

我们知道SVC用于产生系统函数的调用请求,需要立即得到响应。SysTick用于产生系统节拍。PendSV用于悬起延迟处理。

在FreeRTOS的port.c中定义了这个三个异常的处理入口,分别为vPortSVCHandler、xPortSysTickHandler、xPortPendSVHandler。

在stm32f10x_it.c中也定义了这个三个异常的处理入口,分别为SVC_Handler、PendSV_Handler、SysTick_Handler。

因此,我们需要将异常处理入口指向由原来的SVC_Handler、PendSV_Handler、SysTick_Handler改变为vPortSVCHandler、xPortSysTickHandler、xPortPendSVHandler。

注释掉原来的异常处理入口函数

在FreeRTOSConfig.h中重新定义异常处理入口函数

7.测试移植是否成功,创建rcc.h、rcc.c、nvic.h、nvic.c、freertos.c五个文件。

/**
	***********************************
	* 文件名:rcc.h
	* 作者:	stone
	* 版本:	V0.1
	* 日期:	2018-3-29
	* 描述:	配置时钟源
	***********************************
	*/
#ifndef __RCC_H_
#define __RCC_H_

/* 功能:	RCC时钟配置
	 参数:	无
   返回值:无
 */
void rcc_config(void);

#endif
/**
	***********************************
	* 文件名:	rcc.c
	* 作者:		stone
	* 版本:		V0.1
	* 日期:		2018-3-29
	* 描述:		配置时钟源
	***********************************
	*/
#include "stm32f10x.h"
#include "stm32f10x_flash.h"
#include "rcc.h"

/* 功能:	RCC时钟配置
	 参数:	无
   返回值:无
 */
void rcc_config(void)
{ 
	ErrorStatus HSEStartUpStatus;

	/* RCC寄存器设置为默认配置 */
	RCC_DeInit();
	
	/* 打开外部高速时钟 */
	RCC_HSEConfig(RCC_HSE_ON);
	/* 等待外部高速时钟稳定 */
	HSEStartUpStatus = RCC_WaitForHSEStartUp();
	if(HSEStartUpStatus == SUCCESS) 
	{ 
		/* 设置HCLK = SYSCLK */
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		/* 设置PCLK2 = HCLK */
		RCC_PCLK2Config(RCC_HCLK_Div1);
		/* 设置PCLK1 = HCLK / 2 */
		RCC_PCLK1Config(RCC_HCLK_Div2);
		
		/* 设置FLASH代码延时 */
		FLASH_SetLatency(FLASH_Latency_2);
		/* 使能预取址缓存 */
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		
		/* 设置PLL时钟源为HSE倍频9 72MHz */
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
		/* 使能PLL */
		RCC_PLLCmd(ENABLE);
		/* 等待PLL稳定 */
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		
		/* 设置PLL为系统时钟源 */
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		/* 等待系统时钟源切换到PLL */
		while(RCC_GetSYSCLKSource() != 0x08);

		/* 设置系统节拍器时钟源为FCLK */
		SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
	}
}
/**
	***********************************
	* 文件名:	nvic.h
	* 作者:		stone
	* 版本:		V0.1
	* 日期:		2018-3-29
	* 描述:		设置中断控制器
	***********************************
	*/
#ifndef __NVIC_H_
#define __NVIC_H_

/* 功能:	中断嵌套控制器配置
   参数:	无
   返回值:无
 */
void nvic_config(void);

#endif
/**
	***********************************
	* 文件名:	nvic.c
	* 作者:		stone
	* 版本:		V0.1
	* 日期:		2018-3-29
	* 描述:		设置中断控制器
	***********************************
	*/
#include "stm32f10x.h"
#include "nvic.h"

/* 功能:	中断嵌套控制器配置
   参数:	无
   返回值:无
 */
void nvic_config(void)
{
	/* 选择中断分组4 */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
/**
	***********************************
	* 文件名:	main.c
	* 作者:		stone
	* 版本:		V0.1
	* 日期:		2018-3-29
	* 描述:		主文件
	***********************************
	*/
#include "stm32f10x.h"
#include "rcc.h"
#include "nvic.h"
#include "FreeRTOS.h"
#include "task.h"

/* 硬件初始化 */
static void prvSetupHardware(void);
/* freertos初始化 */
void freertos_init(void);

/* 主函数 */
int main(void)
{
	/* 硬件初始化 */
	prvSetupHardware();
	
	/* freertos初始化 */
	freertos_init();
	
	/* 启动调度器 */
	vTaskStartScheduler();
}

/* 硬件初始化 */
static void prvSetupHardware(void)
{
	/* 时钟配置 */
	rcc_config();
	
	/* 中断嵌套控制器配置 */
	nvic_config();
}
/**
	***********************************
	* 文件名:	freertos.c
	* 作者:		stone
	* 版本:		V0.1
	* 日期:		2019-2-25
	* 描述:		系统对象创建
	***********************************
	*/
#include "FreeRTOS.h"
#include "task.h"

/* 测试任务1 */
void test1Task(void *argument);
/* 测试任务2 */
void test2Task(void *argument);

/* 功能:	freertos初始化
	 参数:	无
   返回值:无
 */
void freertos_init(void)
{
	/* 创建测试任务1 */
	xTaskCreate(test1Task, "test1", 128, NULL, 3, NULL );
	
	/* 创建测试任务2 */
	xTaskCreate(test2Task, "test2", 128, NULL, 3, NULL );
}

/* 功能:	测试任务1
	 参数:	创建时传入
   返回值:无
 */
void test1Task(void *argument)
{
	/* 主循环 */
  for(;;)
  {
		/* 延时1秒 */
    vTaskDelay(1000);
  }
}

/* 功能:	测试任务2
	 参数:	创建时传入
   返回值:无
 */
void test2Task(void *argument)
{
	/* 主循环 */
  for(;;)
  {
		/* 延时1秒 */
    vTaskDelay(1000);
  }
}

使用j-link调试,在任务1和任务2中分别打上断点,系统调度正常

移植成功。

猜你喜欢

转载自blog.csdn.net/lushoumin/article/details/87915711