STM32开发之移植FreeRtos

一、新建STM32工程项目

(1)打开keil新建工程文件夹

 (2)选择芯片型号

 接下来会弹出来一个新建工程的小助手,我们关闭就好,接下来我们的工程就创建好了,但是工程还是空的

二、添加STM32的相关固件

2.1 启动文件

(STM32的程序就是从启动文件开始执行的)

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm

 2.2 STM32的外设寄存器描述文件与配置时钟相关文件

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x

1.stm32f10x.h就是STM32的外设寄存器描述文件,它的作用就是和51单片机的头文件REGX52.H一样,是用来描述STM32着哪些寄存器和它对应的地址的

2.这两个system文件是用来配置时钟的;STM32主频72MHz,就是system文件里的函数配置的

 2.3 内核的寄存器描述文件

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport

 

 因为这个STM32是内核和内核外围的设备组成的,而且这个内核的寄存器描述和外围设备的描述文件不是在一起的,所以我们还需要添加一个内核寄存器的描述文件;这两个cm3(Cortex-M3)文件就是内核的寄存器描述,当然他还带了一些内核的配置函数,所以就多了个.c文件

 2.4 工程文件Start文件夹

 (1)新建Start文件夹

在新建的工程中新建一个Start文件夹将上述文件复制到Start文件夹中

 (2)将需要的文件添加到Start组中

 (3)添加Start文件夹的路径

 2.5 工程文件User文件夹

(1)新建文件夹

 (2)新建组

 (3)添加main.c文件进去

 (3)编译看看是否报错

 2.6 修改字体编码格式

(1)使用utf-8格式

 (2)修改代码的字体

 2.7 工程文件Library文件夹

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver

 (1)把这个文件夹下的.c和.h文件全部添加到Library文件夹下

 (2)新建Library组

 2.8 向User文件夹中添加conf.h和中断相关的文件

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template

stm32f10x_conf.h:用来配置库函数头文件的包含关系(还有个用来参数检查的函数定义)

两个it文件:是用来存放中断函数的

(1)工程文件夹中添加文件

 (2)keil工作组中添加文件

(3)添加宏定义

 编译没有问题

至此新建一个STM32的工程文件夹结束 

 三、使用dap-Link进行烧录

 代码下载成功

 STM32的LED开始闪烁

 四、移植FreeRtos文件

4.1 精简官方源码

(1)下载官方源码

 (2)对官方源码进行精简

 4.2 将官方源码移植到Keil工程

(1)新建组

 (2)向组内添加文件

 (3)添加头文件路径

 (4)进行编译,查看是否有问题

 (5)添加FreeRtosConfig.h文件

 (6)只留一种内存管理方式

 (7)修改FreeRtosConfig.h文件

 (7)修改中断文件将几个函数给注释掉

 最终通过上面系列操作移植成功

 五、仿真调试

(1)我们在进行仿真时会出现如下的问题

 这里我们需要点击魔术棒去配置对应的选项

Dialog DLL改为  DARMSTM.DLL

Parameter改为   -pSTM32F103ZE(此项根据具体型号而定)

 程序烧录到开发板通过串口工具打印

 

 六、全部代码

#include "stm32f10x.h"                  // Device header
#include "FreeRTOS.h" 
#include "task.h"
/* Standard includes. */
#include <stdio.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Library includes. */
#include "stm32f10x_it.h"
#include "USART.h" 
#include "semphr.h"

/*
任务目的:任务一执行使PC13端口的LED灯闪烁并且在串口打印
任务二:在串口打印任务二信息
*/

/*************************全局变量****************************/
static SemaphoreHandle_t xSemphoreuMutexsart;//这里的全局变量使用static表示只在本文件中使用,更加规范
/******************任务句柄***************************/
TaskHandle_t xtask1TCB;
TaskHandle_t xtask2TCB;

/******************任务追踪变量***************************/
	int task1flagrun=0;
	int task2flagrun=0;
	int task3flagrun=0;
/******************任务一***************************/
void mytask1(void*para){

	while(1){
	 task1flagrun = 1;
	 task2flagrun = 0;
   // 切换 LED 状态  
   GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));  
   // 延时 1 秒  
   vTaskDelay(pdMS_TO_TICKS(1000)); // 修改为1000ms  
	 xSemaphoreTakeRecursive(xSemphoreuMutexsart, portMAX_DELAY);
	 printf("task 1 is running\r\n");
	 xSemaphoreGiveRecursive(xSemphoreuMutexsart);
	 vTaskDelay(pdMS_TO_TICKS(1)); // 阻塞1ms,之前单位未明确,这里假设是ms 
 
	}
}
/******************任务二***************************/
void mytask2(void*para){
	while(1){
	 task1flagrun = 0;
	 task2flagrun = 1;
	 xSemaphoreTakeRecursive(xSemphoreuMutexsart, portMAX_DELAY);
	 printf("task 2 is running\r\n");
	 xSemaphoreGiveRecursive(xSemphoreuMutexsart);
	  vTaskDelay(pdMS_TO_TICKS(1));
	}
}

 
/*************为空闲任务创建对应的栈和堆******************/
StaticTask_t xIdelTaskTCB ;  
StackType_t xIdleTaskStack[100];  
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )  
{  
    *ppxIdleTaskTCBBuffer = &xIdelTaskTCB;  
    *ppxIdleTaskStackBuffer = xIdleTaskStack;  
    *pulIdleTaskStackSize = 100;  
}
int main(void){
	
	#ifdef DEBUG
  debug();
  #endif
	Usart_Init();
	
	/*初始化GPIO*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  // 修正GPIO端口配置错误  
  GPIO_Init(GPIOC, &GPIO_InitStructure);  
  GPIO_SetBits(GPIOC, GPIO_Pin_13);  
	
  /************1.使用递归锁*************/
	//实现互斥锁
	xSemphoreuMutexsart=xSemaphoreCreateRecursiveMutex();//在创建好之后就可以take了
	//在Take和Give时都要加上Recursive
 
	
	/************2.创建三个任务*************/
  xTaskCreate(mytask1,"task1",100,NULL,1,&xtask1TCB);
	xTaskCreate(mytask2,"task2",100,NULL,1,&xtask2TCB);


	/* Start the scheduler. */
	vTaskStartScheduler();//在这里创建空闲任务
	
  // 如果vTaskStartScheduler返回,则表示有错误  
    while (1) {  
    }  
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程者也

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值