1、文件准备
去FreeRTOS官网下载源码,尽量下载最新版本,里面有demo工程,解压完成后只保留FreeRTOS文件夹即可。
source文件即为FreeRTOS源码
新建一个文件夹source,将当前目录的.c文件移动到source文件夹里。
portable文件夹里只保留MemMang和RVDS文件夹,其余可以选择删除或保留。
在Demo文件夹里找到,CORTEX_STM32F103_Keil文件夹,找到FreeRTOSConfig.h文件,将其放到FreeRTOS目录。
到此为止FreeRTOS文件准备完成。
2、添加到工程
将准备好的FreeRTOS文件夹移动到你的Keil工程目录下。
3、修改配置
将FreeRTOS文件夹路径添加到Target
在stm32f10x_it.c文件中注释或者删除掉,void SVC_Handler(void),void PendSV_Handler(void),void SysTick_Handler(void)函数。
在FreeRTOSConfig.c文件最后进行宏定义
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
至此完成移植,以下为闪灯任务源码。
4、源代码
main.c
#include "stm32f10x.h" // Device header
#include "freertos.h"
#include "freertosconfig.h"
#include "task.h"
#include "serial.h"
#include "mygpio.h"
#include "stdio.h"
TaskHandle_t myTaskHandle1,myTaskHandle2;
void myTask1(void *arg);
void myTask2(void *arg);
void myTask1(void *arg)
{
while(1)
{
GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_RESET);
vTaskDelay(200);
GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_SET);
vTaskDelay(200);
printf("myTask1 run\n");
}
}
void myTask2(void *arg)
{
while(1)
{
GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_RESET);
vTaskDelay(100);
GPIO_WriteBit(GPIOA,GPIO_Pin_2,Bit_SET);
vTaskDelay(100);
printf("myTask2 run\n");
}
}
int main(void)
{
myGPIO_Init();
SerialPortInit();
printf("FREERTOS RUNNING!\n");
xTaskCreate(myTask1,"myTask1",100,NULL,1,&myTaskHandle1);
printf("myTask1 ready\n");
xTaskCreate(myTask2,"myTask2",100,NULL,1,&myTaskHandle2);
printf("myTask2 ready\n");
vTaskStartScheduler();
}
串口通信serial.c
/*
* FreeRTOS V202107.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0.
*/
/* Scheduler includes. */
#include <stdio.h>
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
/* Library includes. */
#include "stm32f10x.h" // Device header
/* Demo application includes. */
#include "serial.h"
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/*
* See the serial2.h header file.
*/
void SerialPortInit(void)
{
unsigned long ulWantedBaud = 115200;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* If the queue/semaphore was created correctly then setup the serial port
hardware. */
/* Enable USART1 clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART1 Rx (PA10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
USART_InitStructure.USART_BaudRate = ulWantedBaud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init( USART1, &USART_InitStructure );
//USART_ITConfig( USART1, USART_IT_RXNE, ENABLE );
USART_Cmd( USART1, ENABLE );
}
/*-----------------------------------------------------------*/
int fputc( int ch, FILE *f )
{
USART_TypeDef* USARTx = USART1;
while ((USARTx->SR & (1<<7)) == 0);
USARTx->DR = ch;
return ch;
}
GPIO初始化源码
myGPIO.c
#include "stm32f10x.h" // Device header
void myGPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_WriteBit(GPIOA,GPIO_Pin_1 | GPIO_Pin_2,Bit_RESET);
}
5、调试问题解决方法
当遇到调试报错,显示没有读写权限时修改一下参数即可解决,以STM32F103C8系列为例。其它系列参照Keil官网提供的解决办法,解决方案网站。