【FreeRTOS移植笔记】关于FreeRTOS移植记录

一、FreeRTOS移植文件

FreeRTOS官方网站freertos.org,官网下载是从github下载,外网连接有问题基本上不容易下载,库文件使用的是开发板提供的FreeRTOSv9.0.0。

库文件包包括两个文件夹FreeRTOS核心库和FreeRTOS-Plus附加功能库。

源文件视图
移植文件包括include文件夹全部,MemMang文件夹全部,RVDS中的对应内核文件夹,Source根目录下的所有源文件以及Demo文件夹中例程所带的FreeRTOSConfig.h头文件。

二、Keil开发移植过程

复制文件到项目文件夹

创建一个FreeRTOS文件夹
在这里插入图片描述

在FreeRTOS文件夹内创建一个src文件夹和一个port文件夹(include文件夹可以直接从官方源文件中复制过来)。
在这里插入图片描述
复制官方源码中的include文件夹。
在这里插入图片描述
复制内核接口源文件以及内存管理文件到port文件夹中。在这里插入图片描述
复制源码库中的源文件到src文件夹中。
在这里插入图片描述
复制FreeRTOSConfig.h文件到项目用户文件夹中。

添加分组和文件

在创建好的项目文件中添加分组,并在分组中添加源文件等。
创建两个分组Freertos/src和FreeRTOS/port,如图。
添加分组

添加编译头文件路径

添加的路径包括include和对应内核文件夹,如图。
在这里插入图片描述

三、代码部分

包含的头文件

#include "FreeRTOS.h"			// 必须在其他几个头文件之前
#include "queue.h"				// 消息队列
#include "task.h"				// 任务
#include "semphr.h"				// 信号
#include "event_groups.h" 		// 事件组

定义变量

1、任务句柄

static TaskHandle_t demo_TaskHandle;		//任务句柄
...

2、消息队列

QueueHandle_t demo_QueueHandle;				//消息队列句柄
uint8_t demoQueueLength = 8;				//消息队列长度
uint32_t demoQueueSize = 4;					//消息队列单个数据大小

3、信号量

SemaphoreHandle_t demo_SemphrHandle;		//信号量句柄

4、事件组EventGroup

static EventGroupHandle_t Event_Handle = NULL;

5、任务通知TaskNotify
任务通知不需要定义句柄,直接使用的是任务句柄。
任务通知可以替代二值信号量,计数信号量,1字消息队列,事件组。

接口函数

1、任务句柄



2、消息队列



3、信号量



4、事件组EventGroup

xEventGroupCreate(); // 事件创建函数 
vEventGroupDelete(); // 事件删除函数 
xEventGroupSetBits(); // 事件组置位函数 
xEventGroupSetBitsFromISR(); // 事件组置位函数 
xEventGroupWaitBits(); // 等待事件函数 
xEventGroupClearBits(); // 返回值是没有被清除之前的值
xEventGroupClearBitsFromISR(); // 返回值是没有被清除之前的值

5、任务通知TaskNotify

// 发送任务通知函数
xTaskGenericNotify(); // 发送任务通知函数 
xTaskNotifyGive();
vTaskNotifyGiveFromISR();
xTaskNotify();
xTaskNotifyFromISR();
xTaskNotifyAndQuery();
xTaskNotifyAndQueryFromISR();

// 获取任务通知函数
ulTaskNotifyTake(); // 作为信号量获取快速
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
 uint32_t ulBitsToClearOnExit,
 uint32_t *pulNotificationValue,
 TickType_t xTicksToWait );

创建任务例程

注意创建任务有两种方法,一种是先创建完所有任务后再启动调度器;另外一种是先创建一个任务后启动调度器,在任务中创建其他任务后没用的任务删除掉;

任务优先级数字越大优先级越高,和uCOS相反。

#include "stm32f10x.h"
#include "string.h"

#include "bsp_gpio.h"
#include "bsp_led.h"

#include "FreeRTOS.h"			// 必须在其他几个头文件之前
#include "queue.h"				// 消息队列
#include "task.h"				// 任务
#include "semphr.h"				// 信号
#include "event_groups.h"		// 事件组

static void BSP_Init(void);


static TaskHandle_t demo_TaskHandle = NULL;
static TaskHandle_t Task1_Handle = NULL, Task2_Handle = NULL;

QueueHandle_t demo_QueueHandle;				//消息队列句柄
uint8_t demoQueueLength = 8;				//消息队列长度
uint32_t demoQueueSize = 4;					//消息队列单个数据大小

SemaphoreHandle_t demo_SemphrHandle;		//信号量句柄

static void Task1_Entry(void *arg)
{
	BaseType_t xReturn = pdTRUE;
	for (;;)
	{
		xReturn = xSemaphoreGive(demo_SemphrHandle); // 释放信号量,二值置1,计数+1。
		vTaskDelay(100); // 阻塞100个时钟周期
	}
}

static uint32_t ulTestData = 0x01010101;
static void Task2_Entry(void *arg)
{
	BaseType_t xReturn = pdTRUE;
	for (;;)
	{
		xSemaphoreTake(demo_SemphrHandle, portMAX_DELAY); // 等待信号量,一直阻塞
		xReturn = xQueueSend(demo_QueueHandle, &ulTestData , 0); // 发送ulTestData到消息队列
		if (xReturn == pdTRUE)
		{
			printf("接收消息成功\r\n");
		}
		LED2_TOGGLE;
	}
}

uint32_t ulQueueRxBuf;
static void Demo_TaskEntry(void *arg)
{
	BaseType_t xReturn = pdTRUE;
	for (;;)
	{
		xReturn = xQueueReceive(demo_QueueHandle, &ulQueueRxBuf, portMAX_DELAY); // 接收消息队列,使用portMAX_DELAY如果没有消息则一直阻塞
		if (xReturn == pdTRUE)
		{
			printf("接收消息成功\r\n");
		}
		LED1_TOGGLE; // LED切换一次
	}
}

/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{	
	
	BaseType_t ucTaskState = pdTRUE;
	
	BSP_Init();	// 外设初始化
	
	taskENTER_CRITICAL(); // 进入临界区
	
	demo_QueueHandle = xQueueCreate(demoQueueLength, demoQueueSize); // 创建消息队列
	demo_SemphrHandle = xSemaphoreCreateBinary(); // 创建二值信号量
	// demo_SemphrHandle = xSemaphoreCreateCounting(12, 12); // 创建计数信号量,第一个形参是计数信号量最大值,第二个是初始值。
	// TestSemphrHandle = xSemaphoreCreateMutex(); // 创建互斥信号量
	xTaskCreate(Task1_Entry, "Task1", 512, NULL, 2, &Task1_Handle);
	xTaskCreate(Task2_Entry, "Task2", 512, NULL, 3, &Task2_Handle);
	ucTaskState = xTaskCreate((TaskFunction_t)Demo_TaskEntry, "DemoTask", 512, NULL, 3, &demo_TaskHandle); // 创建任务

	taskEXIT_CRITICAL(); // 退出临界区
	
	if (ucTaskState == pdTRUE)
	{
		vTaskStartScheduler(); // 开始任务调度
	}
	else		
	{
		printf("Create Task error!!!\r\n");
	}

	while (1)
	{
		
	}
}

static void BSP_Init(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	LED_GPIO_Config();
	
	USART_Config();
	
	KEY_GPIO_Init();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值