一、FreeRTOS之使用初体验

一、FreeRTOS之使用初体验

1. FreeRTOS之全局配置文件FreeRTOSConfig.h

对于全新的RTOS首先第一步首先需要会用才能深度学习其底层实现,所以本章节我们先来看一下FreeRTOS最重要的全局配置文件:FreeRTOSConfig.h

本章节以官方/FreeRTOS/Demo/CORTEX_STM32F103_Keil 为例说明:


#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION		1                               //使能抢占调度器
#define configUSE_IDLE_HOOK			0                               //不使能空闲任务钩子函数
#define configUSE_TICK_HOOK			0                               //不时间片钩子函数
#define configCPU_CLOCK_HZ			( ( unsigned long ) 72000000 )	//设置CPU运行频率
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )         //设置调度周期频率1000hz->10ms
#define configMAX_PRIORITIES		( 5 )                            
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )      //任务最小栈大小128字 = 128*4 Bytes
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )    //设置堆大小
#define configMAX_TASK_NAME_LEN		( 16 )
#define configUSE_TRACE_FACILITY	0
#define configUSE_16_BIT_TICKS		0
#define configIDLE_SHOULD_YIELD		1                               //空闲任务让出时间片给同优先级任务,建议关闭

/* 协程相关,逐步废弃 */
#define configUSE_CO_ROUTINES 		0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

#define INCLUDE_vTaskPrioritySet		1  //使能设置优先级API
#define INCLUDE_uxTaskPriorityGet		1  //使能获取优先级API
#define INCLUDE_vTaskDelete				1  //使能删除任务API
#define INCLUDE_vTaskCleanUpResources	0  //
#define INCLUDE_vTaskSuspend			1  //使能任务挂起API
#define INCLUDE_vTaskDelayUntil			1  //
#define INCLUDE_vTaskDelay				1  //使能设置任务延迟API

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY 		255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15

#endif /* FREERTOS_CONFIG_H */

2. FreeRTOS之创建任务

知道FreeRTOS的全局配置都是干什么的以后,来到了我们最重要的部分,使用rtos就是为了使用多任务,本小节就看如何使用创建任务的API来创建多个不同的任务。

FreeRTOS 任务不允许以任何方式从实现函数中返回,也不能执行到函数末尾。如果一个任务不再需要,可以显式地将其删
除。
任务的原型为:

void ATaskFunction( void *pvParameters )
{
	while(1){
		vTaskDelay(pdMS_TO_TICKS(10UL));	//延迟10ms
	}
	vTaskDelete( NULL );
}

其中pvParameters为给该任务传递的参数。

创建任务的API为xTaskCreate:

portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
							const signed portCHAR * const pcName,
							unsigned portSHORT usStackDepth,
							void *pvParameters,
							unsigned portBASE_TYPE uxPriority,
							xTaskHandle *pxCreatedTask );

pvTaskCode: 任务函数
pcName: 任务名称,调试可用
usStackDepth: 任务堆栈为多少字,先非配大点,后续可以通过系统提供的接口查询实际使用的栈大小
pvParameters: 任务参数
uxPriority: 任务优先级
xTaskHandle:任务句柄,后续可用于删除任务等操作

3. FreeRTOS之使用队列完成任务通信

可以创建任务以后我们就有了一个个小程序,通常这些程序需要能够互相通信起来才会发挥大作用。这里介绍最常用的通信手段 队列。
队列可以存储有限确定长度的数据单元。可被多任务存取,读写都可以阻塞。

3.1创建队列的API函数为xQueueCreate:

xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength,
							unsigned portBASE_TYPE uxItemSize );

uxQueueLength:队列能够存储的最大单元数目,即队列深度
uxItemSize:队列中数据单元的长度,以字节为单位。
xQueueHandle:创建成功的队列句柄

3.2发送数据到队列API:

xQueueSendToBack()和xQueueSendToFront()

portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,
								const void * pvItemToQueue,
								portTickType xTicksToWait );
portBASE_TYPE xQueueSendToBack( xQueueHandle xQueue,
								const void * pvItemToQueue,
								portTickType xTicksToWait );

pvItemToQueue:发送数据的指针。其指向将要复制到目标队列中的数据单元。拷贝的长度为uxItemSize
xTicksToWait:阻塞超时时间。

3.3接受队列数据API:

xQueueReceive()与 xQueuePeek()
xQueueReceive 用于从队列中接收(读取)数据单元。接收到的单元同时会从队列中删除。
xQueuePeek 也是从从队列中接收数据单元,不同的是并不从队列中删出接收到的单元。


portBASE_TYPE xQueueReceive( xQueueHandle xQueue,
							const void * pvBuffer,
							portTickType xTicksToWait );
							
portBASE_TYPE xQueuePeek( xQueueHandle xQueue,
							const void * pvBuffer,
							portTickType xTicksToWait );

pvBuffer:接收缓存指针。其指向一段内存区域,用于接收从队列中拷贝来的数据。
xTicksToWait:阻塞超时时间。

3.4查询队列数据个数API:

uxQueueMessagesWaiting()

unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );

3.5 常用接受队列数据代码结构

接受数据侧:

void ATaskFunction( void *pvParameters )
{
	while(1){
		if( uxQueueMessagesWaiting( xQueue ) != 0 )
		{
			vPrintString( "Queue should have been empty!\r\n" );
		}
		xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
		if( xStatus == pdPASS )
			vPrintStringAndNumber( "Received = ", lReceivedValue );
		else
			vPrintString( "Could not receive from the queue.\r\n" );
		
		vTaskDelay(pdMS_TO_TICKS(10UL));	//延迟10ms
	}
	vTaskDelete( NULL );
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值