目录
前言:
此笔记通过一个简单的串口打印实例,来学习FreeRTOS的移植。
所用工具:
1.FreeRTOS源码(官网下载)
2.MDK-Keil软件
3.STM32F1xx/STM32F4xxHAL库
4.STM32F103C8T6
5.串口调试助手
知识概括:
1.对FreeRTOS进行裁剪
2.了解FreeRTOS的源码结构
3.移植过程中FreeRTOS的报错处理
4.串口打印
5.创建简单的任务
6.模拟器以及开发板(STM32F103C8T6)上运行FreeRTOS实例
一、FreeRTOS目录结构
对于源码进行文件裁剪
根据源码进行裁剪,以Keil工具下STM32F103芯片为例,它的FreeRTOS的目录如下:
其中本实例中Common的ARMv8M也已经裁剪,如下图并未标注
tools为亚马逊相关文件,非必须(本实例中已裁剪)
核心为Source下的文件(了解)
二、修改官方源码并串口打印(模拟器)
2.1处理裁剪后的报错(去掉无关代码)
完成源码的裁剪后打开工程并对部分文件进行删除,最终如下所示
由于删除了很多文件,编译后会出现一大堆报错,下面开始对这些报错一一进行处理。
为vTimer2IntHandler、LCD、usMaxJitter、prvSetupHardware四部分一系列报错
2.1.1 vTimer2IntHandler报错处理
处理该错误位于STM32F10x.s中 删除图中40行
并通过分好进行注释 成功处理掉第一个关于vTimer2IntHandler的报错
2.1.2 LCD一系列的报错处理
处理该错误位于main.c中
下文中具体的函数部分记得删除
打印函数改为如下所示
2.1.3 usMaxJitter报错处理
删除下述函数
2.1.4 prvSetupHardware报错处理
删除下述函数
2.2添加串口打印功能
2.2.1串口初始化和编写fputc(serial.c)
下述为.C文件,只保留以及修改初始化部分以及打印串口打印部分,具体如下所示:
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
/* Library includes. */
#include "stm32f10x_lib.h"
#include "stdio.h"
/* 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_InitStructure.USART_Clock = USART_Clock_Disable;
USART_InitStructure.USART_CPOL = USART_CPOL_Low;
USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_InitStructure.USART_LastBit = USART_LastBit_Disable;
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;
}
/*-----------------------------------------------------------*/
其中.h文件自行自行对应修改
2.2.2主函数(main.c)和外部函数部分报错的修改(STM32F10x.s)
添加该函数
删除该函数
串口初始化
注意串口的头文件的引用
位于STM32F10x.s中,对其进行下述的修改
删除该部分
注释该部分
2.2.2Keil中模拟器实现功能
最终实现效果如上图所示
三、在STM32F103C8T6上运行FreeRTOS实例
编写一个简单的创建任务代码(main.c)
/*-----------------------------------------------------------*/
void Task1Function( void * param)
{
while(1)
{
printf("1");
}
}
void Task2Function( void * param)
{
while(1)
{
printf("2");
}
}
int main( void )
{
TaskHandle_t xHandleTask1;
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
printf("Hellow,world!\r\n");
xTaskCreate(Task1Function,"Task1",100,NULL,1,&xHandleTask1);
xTaskCreate(Task2Function,"Task2",100,NULL,1,NULL);
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}
/*-----------------------------------------------------------*/
打开串口助手最终效果如图所示。
此过程遇到了printf打印不出来的问题,或者表现又类似的占用,堵塞了别的程序运行,但是并没有找到问题,最后发现原来是下述没有选中。